深学南楠失败的原因

Fre*_*Url 46 python machine-learning theano keras tensorflow

也许是一般性的问题,但任何人都可以解释什么会导致卷积神经网络发散?

具体细节:

我正在使用Tensorflow的iris_training模型和我自己的一些数据并继续获取

错误:tensorflow:模型与损失= NaN分歧.

追溯...

tensorflow.contrib.learn.python.learn.monitors.NanLossDuringTrainingError:训练期间NaN丢失.

回溯源于线:

 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")
Run Code Online (Sandbox Code Playgroud)

我已经尝试调整优化器,使用零学习率,并且不使用优化器.任何有关网络层,数据大小等的见解都是值得赞赏的.

cha*_*255 76

我看到很多东西使模型分歧.

  1. 学习率太高.如果损失开始增加然后发散到无穷大,您通常可以判断是否是这种情况.

  2. 我不熟悉DNNClassifier,但我猜它使用了分类交叉熵成本函数.这涉及在预测接近零时取得预测的对数.这就是为什么人们通常会在预测中添加一个小的epsilon值来防止这种分歧.我猜测DNNClassifier可能会这样做或使用tensorflow opp.可能不是问题.

  3. 其他数值稳定性问题可能存在,例如除以零,其中添加epsilon可以提供帮助.另一个不那么明显的一个,如果在处理有限精度数时,如果没有正确简化,那么导数的平方根可以发散.我再次怀疑这是DNNClassifier的问题.

  4. 您可能遇到输入数据问题.尝试调用assert not np.any(np.isnan(x))输入数据以确保不引入nan.还要确保所有目标值都有效.最后,确保数据已正确规范化.您可能希望像素在[-1,1]范围内,而不是[0,255].

  5. 标签必须在损失函数的域中,因此如果使用基于对数的损失函数,则所有标签必须是非负的(如evan pu和下面的注释所述).

  • 感谢您的分解。我的问题是我的标签围绕零对称(即 [-5,...,5])。移位解决了这个问题。 (3认同)
  • 标签应该是二进制的.1或0.否则分类交叉熵成本函数没有意义. (3认同)
  • `tf.keras.utils.normalize(data)` 对于标准化数据很有用。 (2认同)
  • “二进制”表示它们应该是单热编码的,即向量 (1,0,0,....,0) 作为第一类的示例,(0,1,0,.... 0) 为第二类的示例,(0,.....,0,1) 为最后一类的示例。输出节点的数量应该与您拥有的类的数量相同。 (2认同)

Eva*_* Pu 8

如果您正在训练交叉熵,则需要在输出概率中添加一个像1e-8这样的小数字.

因为log(0)是负无穷大,当你的模型训练得足够时,输出分布会非常偏斜,例如说我正在做一个4类输出,在开始时我的概率看起来像

0.25 0.25 0.25 0.25
Run Code Online (Sandbox Code Playgroud)

但最终概率可能会如此

1.0 0 0 0
Run Code Online (Sandbox Code Playgroud)

而你采用这种分布的交叉熵,一切都会爆炸.修复是人为地在所有术语中添加一个小数字以防止这种情况.


Gui*_*ido 7

在我的情况下,我在设置远程整数标签时得到了 NAN。IE:

  • 标签 [0..100] 训练没问题,
  • 标签 [0..100] 加上一个额外的标签 8000,然后我得到了 NAN。

所以,不要使用距离很远的标签。

编辑您可以在以下简单代码中看到效果:

from keras.models import Sequential
from keras.layers import Dense, Activation
import numpy as np

X=np.random.random(size=(20,5))
y=np.random.randint(0,high=5, size=(20,1))

model = Sequential([
            Dense(10, input_dim=X.shape[1]),
            Activation('relu'),
            Dense(5),
            Activation('softmax')
            ])
model.compile(optimizer = "Adam", loss = "sparse_categorical_crossentropy", metrics = ["accuracy"] )

print('fit model with labels in range 0..5')
history = model.fit(X, y, epochs= 5 )

X = np.vstack( (X, np.random.random(size=(1,5))))
y = np.vstack( ( y, [[8000]]))
print('fit model with labels in range 0..5 plus 8000')
history = model.fit(X, y, epochs= 5 )
Run Code Online (Sandbox Code Playgroud)

结果显示了添加标签 8000 后的 NAN:

fit model with labels in range 0..5
Epoch 1/5
20/20 [==============================] - 0s 25ms/step - loss: 1.8345 - acc: 0.1500
Epoch 2/5
20/20 [==============================] - 0s 150us/step - loss: 1.8312 - acc: 0.1500
Epoch 3/5
20/20 [==============================] - 0s 151us/step - loss: 1.8273 - acc: 0.1500
Epoch 4/5
20/20 [==============================] - 0s 198us/step - loss: 1.8233 - acc: 0.1500
Epoch 5/5
20/20 [==============================] - 0s 151us/step - loss: 1.8192 - acc: 0.1500
fit model with labels in range 0..5 plus 8000
Epoch 1/5
21/21 [==============================] - 0s 142us/step - loss: nan - acc: 0.1429
Epoch 2/5
21/21 [==============================] - 0s 238us/step - loss: nan - acc: 0.2381
Epoch 3/5
21/21 [==============================] - 0s 191us/step - loss: nan - acc: 0.2381
Epoch 4/5
21/21 [==============================] - 0s 191us/step - loss: nan - acc: 0.2381
Epoch 5/5
21/21 [==============================] - 0s 188us/step - loss: nan - acc: 0.2381
Run Code Online (Sandbox Code Playgroud)


ype*_*per 5

如果使用整数作为目标,请确保它们在 0 处不对称。

即,不要使用类 -1, 0, 1。而使用 0, 1, 2。

  • 您愿意评论一下原因或引用完成参考吗? (3认同)
  • @gsimard,这是因为已接受答案中的原因 5。基于逻辑的回归函数通常使用对数,仅在非负数上定义 (2认同)