训练回归网络时的 NaN 损失

我有一个数据矩阵在“一热编码”(所有1和0)与260,000行和35列。我在用克拉斯训练一个简单的神经网络来预测一个连续变量。建立网络的代码如下:

model = Sequential()
model.add(Dense(1024, input_shape=(n_train,)))
model.add(Activation('relu'))
model.add(Dropout(0.1))


model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.1))


model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Dense(1))


sgd = SGD(lr=0.01, nesterov=True);
#rms = RMSprop()
#model.compile(loss='categorical_crossentropy', optimizer=rms, metrics=['accuracy'])
model.compile(loss='mean_absolute_error', optimizer=sgd)
model.fit(X_train, Y_train, batch_size=32, nb_epoch=3, verbose=1, validation_data=(X_test,Y_test), callbacks=[EarlyStopping(monitor='val_loss', patience=4)] )

然而,在训练过程中,我看到损失减少的很好,但在第二纪元中期,它去南:

Train on 260000 samples, validate on 64905 samples
Epoch 1/3
260000/260000 [==============================] - 254s - loss: 16.2775 - val_loss:
13.4925
Epoch 2/3
88448/260000 [=========>....................] - ETA: 161s - loss: nan

我尝试用 RMSProp代替 SGD,我尝试用 tanh代替 relu,我尝试有和没有辍学,都没有用。我尝试使用一个更小的模型,即只有一个隐藏层,和相同的问题(它在不同的点变成 nan)。但是,如果只有5列,那么它确实可以使用较少的特性,并且提供了相当好的预测。看起来似乎有些溢出,但我不能想象为什么——损失一点也不大。

Python 版本2.7.11,在 Linux 机器上运行,只能使用 CPU。我用最新版本的 Theano 进行了测试,我也得到了 Nans,所以我试着去 Theano 0.8.2,也遇到了同样的问题。与最新版本的 Keras 有同样的问题,也与0.3.2版本有关。

177759 次浏览

Regression with neural networks is hard to get working because the output is unbounded, so you are especially prone to the 爆炸梯度问题 (the likely cause of the nans).

从历史上来看,一个关键的解决方案是降低学习率,但随着每参数在线机机器学习率算法的出现,如亚当,你不再需要设置一个学习率,以获得良好的性能。除非你是一个神经网络狂热分子并且知道如何调整学习进度表,否则再也没有什么理由使用动力 SGD 了。

下面是一些你可以尝试的方法:

  1. 通过 分位数归一化z scoring使输出正常化。为了严格起见,在训练数据上计算这种转换,而不是在整个数据集上。例如,使用分位数规范化,如果一个示例位于训练集的第60个百分位数,那么它得到的值为0.6。(还可以将分位数标准化值向下移动0.5,使得第0个百分位数为 -0.5,第100个百分位数为 + 0.5)。

  2. 通过增加辍学率或增加 L1和 L2惩罚来增加规则性。L1正则化类似于特征选择,既然您说过将特征数量减少到5可以提供良好的性能,那么 L1也可以。

  3. 如果这些仍然没有帮助,减少您的网络的大小。这并不总是最好的主意,因为它可能会损害性能,但在您的情况下,您有大量的第一层神经元(1024)相对于输入功能(35) ,所以它可能有所帮助。

  4. 批量从32增加到128。128是相当标准的,可能会增加优化的稳定性。

答案是“1”相当不错。然而,所有的修复似乎都是间接地而不是直接地修复问题。我建议使用渐变剪辑,它将剪辑任何高于一定值的渐变。

在 Keras,你可以使用 clipnorm=1(参见 https://keras.io/optimizers/)简单地剪辑所有标准高于1的渐变。

我以前也遇到过同样的问题。我寻找并找到这个问题和答案。上面提到的所有技巧对训练深层神经网络都很重要。我都试过了,但还是得到了 NAN。

I also find this question here. https://github.com/fchollet/keras/issues/2134. 我引用了作者的总结如下:

我想指出这一点,以便它的存档,其他人谁可能 experience this problem in future. I was running into my loss function suddenly returning a nan after it go so far into the training process. I checked the relus, the optimizer, the loss function, my dropout in 根据我的网络的大小和形状 网络。我仍然得到损失,最终变成了一个男人 我很生气。

然后我突然意识到,我可能有一些不好的想法 我交给 CNN 的图片(正在进行正常化处理。) 除了0之外什么都没有。我没有检查这个情况,当我 减去平均值,用标准差标准化,因此我 结果得到了一个样本矩阵只有 Nan 的,有一次我 修正了我的归一化功能,我的网络现在训练得很完美。

我同意上面的观点: 输入对您的网络是敏感的。我使用密度估计的对数值作为输入。绝对值可能非常大,这可能导致 NaN 经过几个步骤的梯度。我认为输入检查是必要的。首先,您应该确保输入 does not包含 Inf 或 inf,或者一些绝对值非常大的数字。

I tried every suggestion on this page and many others to no avail. We were importing csv files with pandas, then using keras Tokenizer with text input to create vocabularies and word vector matrices. After noticing some CSV files led to nan while others worked, suddenly we looked at the encoding of the files and realized that ascii files were NOT working with keras, leading to nan loss and accuracy of 0.0000e+00; however, Utf-8和 utf-16文件 < em > 正在工作! Breakthrough.

如果您正在执行文本分析,并且在尝试了这些建议之后发现 nan丢失,那么使用 file -i {input}(linux)或 file -I {input}(osx)来发现您的文件类型。如果你有 ISO-8859-1us-ascii,尝试转换到 utf-8utf-16le。我还没有试过后者,但我想它也会起作用的。希望这可以帮助某人非常非常沮丧!

训练一开始,我作为南就输了。从输入数据中删除 nas 这样简单的解决方案对我来说是可行的(df.drop na ())

我希望这对遇到类似问题的人有所帮助

我遇到过一个非常相似的问题,这就是我如何让它运行的。

The first thing you can try is changing your activation to LeakyReLU instead of using Relu or Tanh. The reason is that often, many of the nodes within your layers have an activation of zero, and backpropogation doesn't update the weights for these nodes because their gradient is also zero. This is also called the 'dying ReLU' problem (you can read more about it here: https://datascience.stackexchange.com/questions/5706/what-is-the-dying-relu-problem-in-neural-networks).

为此,您可以使用以下方法导入 LeakyReLU 激活:

from keras.layers.advanced_activations import LeakyReLU

然后像这样把它融入到你的图层中:

model.add(Dense(800,input_shape=(num_inputs,)))
model.add(LeakyReLU(alpha=0.1))

此外,输出特性(您试图预测的连续变量)可能是一个不平衡的数据集,并且有太多的0。解决这个问题的一个方法是使用平滑。为此,可以将此列中所有值的分子加1,并将此列中的每个值除以1/(此列中所有值的平均值)

这实际上将所有值从0移动到大于0的值(这仍然可能非常小)。这样可以防止曲线预测0和最小化损失(最终使其为 NaN)。较小的值比较大的值受到的影响更大,但是总的来说,数据集的平均值保持不变。

I had similar issue with my logloss, MAE and others being all NA's. I looked into the data and found, I had few features with NA's in them. I imputed NA's with approximate values and was able to solve the issue.

I faced the same problem with using LSTM, the problem is my data has some nan value after standardization, therefore, we should check the input model data after the standarization if you see you will have nan value:

print(np.any(np.isnan(X_test)))
print(np.any(np.isnan(y_test)))

你可以通过像这样给 Std 加一个小值(0.000001)来解决这个问题,

def standardize(train, test):




mean = np.mean(train, axis=0)
std = np.std(train, axis=0)+0.000001


X_train = (train - mean) / std
X_test = (test - mean) /std
return X_train, X_test

我也有同样的问题,我在用 Kera 解决多元回归问题。后来我意识到,我的数据集中的一些值是 nan,这导致了 nan 的丢失。 我使用了下面的命令:

df=df.dropna()

这解决了我的问题。

我在使用 keras 时也遇到过类似的问题。在输入第二批数据之后,丢失变成了 NAN。

我试着:

  1. 使用 softmax 作为输出密集层的激活
  2. 把 Nan 放进去
  3. 正常化输入

然而,这并没有奏效,所以,然后我试着:

  1. 降低学习速度

问题解决了。

我有同样的问题与我的 RNN 与 Keras LSTM 层,所以我尝试从上面的每个解决方案。我已经缩放了我的数据(使用 sklearn.preprocessing.MinMaxScaler) ,缩放后数据中没有 NaN值。像使用 LeakyRelU 或者改变学习速度这样的解决方案并没有帮助。

因此,我决定改变定标器从 MinMaxScalerStandardScaler,即使我没有 NaN值,我发现它很奇怪,但它的工作!

我有同样的问题与我的 Keras CNN,作为其他我尝试上述所有解决方案: 降低学习率,从列车数据中删除空性,正常化数据,添加辍学层和..。 但这并不能解决 nan 的问题,我尝试将分类器(最后一层)的激活函数从 sigmoid 改为 softmax。成功了! 试试把最后一层的激活函数改成 softmax!

在我的案例中,问题是我复制粘贴了我以前的二进制分类工作,并在输出层使用了 sigmoid激活,而不是 softmax(新的网络是关于多元分类的)。

总结这里提到的不同解决方案,以及这次 github讨论中提到的不同解决方案,这当然取决于你的具体情况:

  • 添加正则化,增加11或12罚款的权重。否则,尝试一个较小的 l2规则。即 l2(0.001) ,或删除它,如果已经存在。
  • 试着降低辍学率。
  • 夹住梯度,防止它们爆炸。例如,在 Keras,你可以使用 clipnorm = 1。或剪辑值 = 1。作为优化器的参数。
  • 检查输入的有效性(没有 NaNs,有时是0) . 即 df.isnull () . any ()
  • 用更容易处理的 Adam 替换优化器。有时用 rmsprop 替换 sgd 也会有所帮助。
  • 使用 RMSProp 重正则化防止梯度爆炸。
  • 尝试对数据进行标准化,或检查标准化过程中是否引入了错误值。
  • 验证你使用的激活函数是否正确(例如,在多类分类中使用 softmax 而不是 sigmoid)。
  • 尝试增加批量大小(例如32到64或128)以增加优化的稳定性。
  • 试着降低你的学习速度。
  • Check the size of your last batch which may be different from the batch size.

当我尝试创建一个包围盒回归时,我也得到了同样的结果。 我的神经网络层次比你的大,我提高了退出值,得到了合适的结果。

尝试检查您的数据,如果有 NAN 值。删除 NAN 值为我解决了问题。

为我的分类网络获取 NaN。 Answering here as it might help someone.

犯了个错误

培训标签上的班级数目为5个,即从0班增加到4班。

在最后的密集层分类有4个节点,这意味着4个类,这是问题。

Chaging the number of nodes in the last layer of network to 5 solved the issue for me.

我有一个类似的问题,我试图改变我的激活从西格莫德到 Softmax 和从 RelU 到 LeakyRelu 和问题得到解决。所以我想,只要没有 NaN 的输入开始,你已经尝试降低你的学习速度,可行的解决方案是发挥你的激活!

当我的一个训练数据条目包含一个 Nan 时,我遇到了这个问题

我得到了同样的问题。成功地,你可以使用克拉回归。解决了我的问题

我的情况:

Train Loss: nan, Train Accuracy: 0.0, Validation Loss: nan, Validation Accuracy: 0.0

后来我才知道原来是因为我的标签是 1, 2, 3, 4不是从0开始的。 So I relabel them, use 0, 1, 2, 3 instead of 1, 2, 3, 4 as labels. 问题解决了!

Hope my answer helps!

我也有同样的问题。检查数据时,我意识到在数据采集过程中发生了一个错误。

在 Keras 中,类标签从0开始。例如,如果你有7个类,那么要么从0到6给它们贴上标签,然后给最后一个密集层(用 softmax 激活函数)添加单位 = 7。或者,如果您应该将数据标记为从1到7,那么在这种情况下,您必须设置 unit = 8(在最后一个稠密层中)。

我得到了二进制分类的 nan值,然后我把损失函数从分类交叉熵改为“二进制交叉熵”,它工作得很好。

顺便说一下,它似乎是一个 染色渐变没有爆炸。

  • 当所有训练实例的输入为负值时,神经元死亡。

这里 “ adam”优化器帮助对抗 NaNs。 But concerning your situation - be sure, you have 缩放数据集 & loss='均方误差均方误差均方误差' (as opposed to yours)

model.compile(optimizer = 'adam', loss = keras.losses.mean_squared_error, metrics=keras.metrics.mean_absolute_error)

当您的数据出现以下问题时,可能会发生此错误:

输入包含 NaN、无穷大或一个对于 dtype (‘ float64’)来说太大的值。 在这些情况下,可以通过删除 NaN 值来解决这个问题,比如:

`df = df.dropna()`

或任何其他 fillna()方法

注意 : 这些方法仅适用于大熊猫的数据帧。

删除包含 nan 值的行,或者用数据集或数据框中的某个值替换 nan 值。它将解决错误。