Tensorflow 为什么vgg16的损耗等于nan,但在添加额外的Softmax层时性能正常?
我正在用Tensorflow低级api编写vgg16网络。该模型在imagenet12数据集中进行了测试。由于计算成本,我将验证集分为80%的训练数据和20%的测试数据 首先,最后一层Tensorflow 为什么vgg16的损耗等于nan,但在添加额外的Softmax层时性能正常?,tensorflow,softmax,vgg-net,Tensorflow,Softmax,Vgg Net,我正在用Tensorflow低级api编写vgg16网络。该模型在imagenet12数据集中进行了测试。由于计算成本,我将验证集分为80%的训练数据和20%的测试数据 首先,最后一层fc8在未激活softmax的情况下输出,我使用tf.nn.softmax\u cross\u entropy\u和_logits\u v2(标签、登录)来计算损失。最后在训练过程中输出nan 然后,我尝试在fc8下添加一个softmax层,但仍然使用tf.nn.softmax\u cross\u entropy\
fc8
在未激活softmax
的情况下输出,我使用tf.nn.softmax\u cross\u entropy\u和_logits\u v2(标签、登录)
来计算损失。最后在训练过程中输出nan
然后,我尝试在fc8
下添加一个softmax
层,但仍然使用tf.nn.softmax\u cross\u entropy\u和\u logits\u v2(标签、登录)
来计算损失。令人惊讶的是,损耗输出正常,而不是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不会影响最终损耗,因为它不会改变每个输出单元的比例。是的,这很奇怪。阅读文档:
**警告:*此op需要无标度的logits,因为它在内部对logits执行softmax以提高效率。不要使用softmax的输出调用此op,因为它将产生不正确的结果。
因此产生NaN的情况实际上是函数的正确用法。是的。现在我想如果是因为初始化值产生了nan
loss。首先,我将从keras.applications.vgg16.vgg16
中提取的参数用于conv层,并使用正态分布初始化fc层的参数。然后我尝试初始化keras.applications.vgg16.vgg16
中的所有参数,当我设置可使用的学习率和正则化器时,它工作并且不输出nan
。@StefanDragnev我同意这一点。然而,我认为理论上两层softmax不会改变最终损失。还是有点奇怪╥﹏╥.是的,这很奇怪。阅读文档:**警告:*此op需要无标度的logits,因为它在内部对logits执行softmax以提高效率。不要使用softmax的输出调用此op,因为它将产生不正确的结果。
因此产生NaN的情况实际上是函数的正确用法。是的。现在我想如果是因为初始化值产生了nan
loss。首先,我将从keras.applications.vgg16.vgg16
中提取的参数用于conv层,并使用正态分布初始化fc层的参数。然后我尝试初始化keras.applications.vgg16.vgg16
中的所有参数,当我设置可使用的学习率和正则化器时,它工作并且不输出nan
。@StefanDragnev我同意这一点。然而,我认为理论上两层softmax不会改变最终损失。还是有点奇怪╥﹏╥.