Я кодирую сеть vgg16 с API низкого уровня Tensorflow. Модель тестируется в наборе данных imagenet12. Из-за стоимости вычислений я разделил набор проверки на 80% данных обучения и 20% данных испытаний.
Во-первых, последний слой fc8
выводит без активации softmax
, и я использую tf.nn.softmax_cross_entropy_with_logits_v2(labels, logits)
для вычисления потерь. Наконец, в процессе обучения выводится nan
.
Затем я пытаюсь добавить слой softmax
под fc8
, но все еще использую tf.nn.softmax_cross_entropy_with_logits_v2(labels, logits)
для вычисления потерь. Удивительно, но потери выводят обычно, а не nan
.
Вот код перед добавлением softmax
слоя:
def vgg16():
...
fc8_layer = FullConnectedLayer(y, self.weight_dict, regularizer_fc=self.regularizer_fc)
self.op_logits = fc8_layer.layer_output
def loss(self):
entropy = tf.nn.softmax_cross_entropy_with_logits_v2(labels=self.Y, logits=self.op_logits)
l2_loss = tf.losses.get_regularization_loss()
self.op_loss = tf.reduce_mean(entropy, name='loss') + l2_loss
и я изменяю вывод vgg16 следующим образом:
def vgg16():
...
fc8_layer = FullConnectedLayer(y, self.weight_dict, regularizer_fc=self.regularizer_fc)
self.op_logits = tf.nn.softmax(fc8_layer.layer_output)
Кроме того, вот мой оптимизатор:
def optimize(self):
update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)
with tf.control_dependencies(update_ops):
with tf.variable_scope(tf.get_variable_scope(), reuse=tf.AUTO_REUSE):
self.opt = tf.train.MomentumOptimizer(learning_rate=self.config.learning_rate, momentum=0.9,
use_nesterov=True)
self.op_opt = self.opt.minimize(self.op_loss)
Я не понимаю, почему добавление слоя softmax работает. По моей идее, два слоя softmax не влияют на окончательную потерю, так как она не меняет пропорцию каждой единицы вывода.