Угловая регрессия с обнаружением одиночного выстрела (иначе, SSD), общая потеря не упадет - PullRequest
0 голосов
/ 28 апреля 2020

Мне недавно дали задание выполнить регрессию угла с помощью глубокой нейронной сети,
Вдохновленный этой нитью , я планирую реализовать регрессию угла с помощью тензорной пары [sin, cos] в SSD один из подходов, о котором я думаю, - это добавить полностью связанный слой для регрессии тензора [sin (a), cos (a)] сразу после conv7, conv8, conv9, conv10 или conv11. Вот мое решение (я поставил F C слой после Conv7):

 def __init__(self, data_format='channels_first'):
    super(VGG16Backbone, self).__init__()
    self._data_format = data_format
    self._bn_axis = -1 if data_format == 'channels_last' else 1
    #initializer = tf.glorot_uniform_initializer  glorot_normal_initializer
    self._conv_initializer = tf.glorot_uniform_initializer
    self._conv_bn_initializer = tf.glorot_uniform_initializer#lambda : tf.truncated_normal_initializer(mean=0.0, stddev=0.005)
    # VGG layers
    self._conv1_block = self.conv_block(2, 64, 3, (1, 1), 'conv1')
    self._pool1 = tf.layers.MaxPooling2D(2, 2, padding='same', data_format=self._data_format, name='pool1')
    self._conv2_block = self.conv_block(2, 128, 3, (1, 1), 'conv2')
    self._pool2 = tf.layers.MaxPooling2D(2, 2, padding='same', data_format=self._data_format, name='pool2')
    self._conv3_block = self.conv_block(3, 256, 3, (1, 1), 'conv3')
    self._pool3 = tf.layers.MaxPooling2D(2, 2, padding='same', data_format=self._data_format, name='pool3')
    self._conv4_block = self.conv_block(3, 512, 3, (1, 1), 'conv4')
    self._pool4 = tf.layers.MaxPooling2D(2, 2, padding='same', data_format=self._data_format, name='pool4')
    self._conv5_block = self.conv_block(3, 512, 3, (1, 1), 'conv5')
    self._pool5 = tf.layers.MaxPooling2D(3, 1, padding='same', data_format=self._data_format, name='pool5')
    self._conv6 = tf.layers.Conv2D(filters=1024, kernel_size=3, strides=1, padding='same', dilation_rate=6,
                        data_format=self._data_format, activation=tf.nn.relu, use_bias=True,
                        kernel_initializer=self._conv_initializer(),
                        bias_initializer=tf.zeros_initializer(),
                        name='fc6', _scope='fc6', _reuse=None)
    self._conv7 = tf.layers.Conv2D(filters=1024, kernel_size=1, strides=1, padding='same',
                        data_format=self._data_format, activation=tf.nn.relu, use_bias=True,
                        kernel_initializer=self._conv_initializer(),
                        bias_initializer=tf.zeros_initializer(),
                        name='fc7', _scope='fc7', _reuse=None)
    self.pool_angle1 = tf.layers.MaxPooling2D(3, 1, padding='same', data_format=self._data_format, name='pool_angle1')
    self._fc_angle1 = tf.layers.Dense(units = 64, activation = tf.nn.sigmoid, kernel_initializer = tf.random_normal_initializer(mean=0.0, stddev=0.001),   name = "fc_angle1")
    self._fc_angle2 = tf.layers.Dense(units = 2, kernel_initializer = tf.random_normal_initializer(mean=0.0, stddev=0.001), name = "fc_angle2")

    # SSD layers
    with tf.variable_scope('additional_layers') as scope:
        self._conv8_block = self.ssd_conv_block(256, 2, 'conv8')
        self._conv9_block = self.ssd_conv_block(128, 2, 'conv9')
        self._conv10_block = self.ssd_conv_block(128, 1, 'conv10', padding='valid')
        self._conv11_block = self.ssd_conv_block(128, 1, 'conv11', padding='valid')

def forward(self, inputs, training=False):
    # inputs should in BGR
    feature_layers = []
    # forward vgg layers
    for conv in self._conv1_block:
        inputs = forward_module(conv, inputs, training=training)
    inputs = self._pool1.apply(inputs)
    for conv in self._conv2_block:
        inputs = forward_module(conv, inputs, training=training)
    inputs = self._pool2.apply(inputs)
    for conv in self._conv3_block:
        inputs = forward_module(conv, inputs, training=training)
    inputs = self._pool3.apply(inputs)
    for conv in self._conv4_block:
        inputs = forward_module(conv, inputs, training=training)


    with tf.variable_scope('conv4_3_scale') as scope:
        weight_scale = tf.Variable([20.] * 512, trainable=training, name='weights')
        if self._data_format == 'channels_last':
            weight_scale = tf.reshape(weight_scale, [1, 1, 1, -1], name='reshape')
        else:
            weight_scale = tf.reshape(weight_scale, [1, -1, 1, 1], name='reshape')

        feature_layers.append(tf.multiply(weight_scale, self.l2_normalize(inputs, name='norm'), name='rescale')
                            )
    inputs = self._pool4.apply(inputs)
    for conv in self._conv5_block:
        inputs = forward_module(conv, inputs, training=training)
    inputs = self._pool5.apply(inputs)
    # forward fc layers
    inputs = self._conv6.apply(inputs)
    inputs = self._conv7.apply(inputs)
    # fc7
    feature_layers.append(inputs)
    # forward ssd layers

    #############################################################
    ################### my fc layer start here###################
    #############################################################
    inputs_angle_flatten = tf.reshape(inputs, [32,  -1])
    #inputs_angle_norm = tf.layers.batch_normalization(inputs_angle_flatten)
    angle_pred = self._fc_angle1.apply(inputs_angle_flatten)
    angle_pred = tf.layers.dropout(angle_pred, rate = 0.5)
    angle_pred = tf.layers.batch_normalization(angle_pred)
    angle_pred = self._fc_angle2.apply(angle_pred)
    angle_pred = tf.layers.dropout(angle_pred, rate = 0.5)

    #############################################################
    ################### my fc layer end here###################
    #############################################################
    for layer in self._conv8_block:
        inputs = forward_module(layer, inputs, training=training)
    # conv8
    feature_layers.append(inputs)
    for layer in self._conv9_block:
        inputs = forward_module(layer, inputs, training=training)
    # conv9
    feature_layers.append(inputs)
    for layer in self._conv10_block:
        inputs = forward_module(layer, inputs, training=training)
    # conv10
    feature_layers.append(inputs)
    for layer in self._conv11_block:
        inputs = forward_module(layer, inputs, training=training)
    # conv11
    feature_layers.append(inputs)
    return feature_layers

Функция угла потери равна L1, как показано ниже,

diff =orientations_pred - orientations_gt
abs_diff = tf.abs(diff)
smooth_loss = tf.reduce_mean(abs_diff, name = 'angle_loss')

Потеря угла добавляется к total_loss вместе с потерей местоположения и перекрестной энтропией.

 total_loss = tf.add(cross_entropy + loc_loss + angle_loss, tf.multiply(params['weight_decay'], tf.add_n(l2_loss_vars), name='l2_loss'), name='total_loss')

Мой вопрос: кажется, что значение angle_loss остается неизменным, оно составляет около 0,6 и никогда не падает, что-то не так с моим полностью подключенным слоем?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...