Мне недавно дали задание выполнить регрессию угла с помощью глубокой нейронной сети,
Вдохновленный этой нитью , я планирую реализовать регрессию угла с помощью тензорной пары [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 и никогда не падает, что-то не так с моим полностью подключенным слоем?