是什么导致卷积神经网络发散?
具体情况:
我正在使用Tensorflow的iris_training模型,并用我自己的数据进行训练,但一直得到
ERROR:tensorflow:模型在损失为NaN时发散。
Traceback…
tensorflow.contrib.learn.python.learn.monitors.NanLossDuringTrainingError: 训练期间损失为NaN。
Traceback源自以下代码行:
tf.contrib.learn.DNNClassifier(feature_columns=feature_columns, hidden_units=[300, 300, 300], #optimizer=tf.train.ProximalAdagradOptimizer(learning_rate=0.001, l1_regularization_strength=0.00001), n_classes=11, model_dir="/tmp/iris_model")
我尝试调整优化器,使用零学习率,以及不使用优化器。
回答:
我见过很多导致模型发散的情况。
-
学习率过高。如果损失开始增加然后发散到无穷大,通常可以判断这是因为学习率过高。
-
我不太熟悉DNNClassifier,但我猜它使用的是分类交叉熵成本函数。这涉及到对预测值取对数,当预测值接近零时会发散。这就是为什么人们通常会在预测值中添加一个小的epsilon值来防止这种发散。我猜DNNClassifier可能已经做了这件事,或者使用了tensorflow的操作来处理。可能不是问题所在。
-
其他数值稳定性问题也可能存在,比如除以零,添加epsilon值可以帮助解决。另一个不太明显的问题是平方根,如果没有正确简化处理有限精度数字,其导数可能会发散。但我怀疑在DNNClassifier的情况下这不是问题。
-
您可能在输入数据上存在问题。尝试在输入数据上调用
assert not np.any(np.isnan(x))
,以确保您没有引入NaN值。还要确保所有目标值都是有效的。最后,确保数据已正确归一化。您可能希望像素值在[-1, 1]范围内,而不是[0, 255]范围内。 -
标签必须在损失函数的定义域内,因此如果使用基于对数的损失函数,所有标签必须是非负的(如evan pu和下面的评论中所指出的)。