训练回归n时NaN损失

我有一个“一键编码”(全1和全0)的数据矩阵,具有260,000行和35列。 我正在使用Keras训练简单的神经网络来预测连续变量。 组成网络的代码如下:

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)] )

但是,在训练过程中,我看到损失减少得很好,但是在第二个时期的中间,损失就变成了nan:

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,我尝试了是否有辍学,但都无济于事。 我尝试了一种较小的模型,即仅具有一个隐藏层,并且存在相同的问题(在不同的点它变得很困难)。 但是,它确实具有较少的功能,即如果只有5列,并且给出了很好的预测。 似乎有某种溢出,但我无法想象为什么-损失根本不是不合理的大。

Python版本2.7.11,仅在CPU上的Linux机器上运行。 我使用最新版的Theano进行了测试,并且我也得到了Nans,因此我尝试使用Theano 0.8.2并遇到了同样的问题。 与最新版本的Keras具有相同的问题,并且也与0.3.2版本相同。

The_Anomaly asked 2020-02-18T11:37:31Z
9个解决方案
73 votes

由于输出是无穷大的,因此很难使用神经网络进行回归,因此您特别容易出现爆炸梯度问题(可能是引起Nans的原因)。

从历史上看,爆炸梯度的一个关键解决方案是降低学习速率,但是随着像亚当这样的每参数自适应学习速率算法的出现,您不再需要设置学习速率即可获得良好的性能。 除非您是神经网络的恶魔并且知道如何调整学习时间表,否则几乎没有理由再使用SGD了。

您可以尝试以下操作:

  1. 通过分位数归一化或z评分对输出进行归一化。 为严格起见,请根据训练数据而非整个数据集计算此转换。 例如,使用分位数归一化,如果示例位于训练集的第60个百分位数中,则其值为0.6。 (您还可以将分位数归一化值向下移动0.5,以使第0个百分位数为-0.5,第100个百分位数为+0.5)。

  2. 通过增加辍学率或对权重添加L1和L2惩罚来增加正则化。 L1正则化类似于特征选择,并且由于您说过将特征数减少到5可以提供良好的性能,因此L1也可以。

  3. 如果这些仍然不能解决问题,请减小网络规模。 这并不总是最好的主意,因为它会损害性能,但是在您的情况下,相对于输入特征(35),您拥有大量的第一层神经元(1024),因此可能会有所帮助。

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

1'' answered 2020-02-18T11:38:17Z
27 votes

用1“表示的答案是非常好的。但是,所有修复似乎都是间接解决了问题,而不是直接解决了问题。我建议您使用渐变剪切,它会简单地剪切超过某个值的所有渐变。

在Keras中,您可以使用clipnorm=1(请参阅[https://keras.io/optimizers/]]来简单地裁剪范数大于1的所有渐变。

pir answered 2020-02-18T11:38:42Z
23 votes

我以前也遇到过同样的问题。 我搜索并找到此问题和答案。 上面提到的所有技巧都对训练深度神经网络很重要。 我尝试了所有这些,但仍然得到了NAN。

我也在这里找到这个问题。 [https://github.com/fchollet/keras/issues/2134。]我引用了作者的总结如下:

“我想指出这一点,以便将其归档给其他可能   将来会遇到这个问题。 我遇到了亏损功能   进入训练过程后,突然返回了一个Nan。   我检查了relus,优化器,损失函数,中途退出   根据规则,我的网络规模和形状   网络。 我仍然处于亏损之中,最终变成了难缠   我感到很沮丧。

然后它突然降临在我身上。 我可能有一些不好的输入。 原来,其中之一   我交给CNN的图片(并进行均值归一化)   on)就是0。 我当时没有检查这种情况   减去平均值并通过标准偏差归一化,因此我   最终得到了一个示例矩阵,这个矩阵不过是nan的。 有一次,我   修复了我的归一化功能,现在我的网络可以完美地训练。”

我同意以上观点:输入对您的网络敏感。 就我而言,我将密度估算的对数值用作输入。 绝对值可能会非常大,经过数步渐变后可能会导致NaN。 我认为输入检查是必要的。 首先,您应确保输入中不包含-inf或inf或绝对值中包含一些非常大的数字。

HenryZhao answered 2020-02-18T11:39:22Z
7 votes

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

您可以尝试的第一件事是将激活更改为LeakyReLU,而不是使用Relu或Tanh。 原因是,层中的许多节点通常激活为零,并且反向传播不会更新这些节点的权重,因为它们的梯度也为零。 这也称为“垂死的ReLU”问题(您可以在此处了解更多信息:[https://datascience.stackexchange.com/questions/5706/what-is-the-dying-relu-problem-in-neural- 网络)。

为此,您可以使用以下命令导入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)。 较小的值比较大的值受到的影响更大,但总体而言,数据集的平均值保持不变。

Arnav answered 2020-02-18T11:40:08Z
4 votes

我在使用LSTM时遇到了同样的问题,问题是我的数据在标准化后具有一定的nan值,因此,如果您看到自己具有nan的值,我们应该在标准化之后检查输入模型数据:

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
javac answered 2020-02-18T11:40:37Z
2 votes

培训开始后,我在第一个时期就失去了机会。 就像从输入数据中删除nas一样简单的解决方案对我有用(df.dropna())

我希望这可以帮助遇到类似问题的人

Krithi07 answered 2020-02-18T11:41:02Z
1 votes

我尝试了此页面上的所有建议以及许多其他建议都无济于事。 我们正在导入带有熊猫的csv文件,然后将nan与文本输入配合使用来创建词汇表和词向量矩阵。 在注意到一些CSV文件导致nan却又其他文件正常工作之后,突然我们查看了文件的编码,意识到ascii文件不适用于keras,导致file -i {input}丢失,准确性为file -I {input}; 但是,utf-8和utf-16文件正在工作! 突破。

如果尝试执行这些建议后正在执行文本分析并丢失nan,请使用file -i {input}(linux)或file -I {input}(osx)查找文件类型。 如果您有ISO-8859-1utf-8,请尝试转换为utf-8utf-16le。还没有尝试过后者,但我想它也可以。 希望这可以帮助某人非常沮丧!

Clay Coleman answered 2020-02-18T11:41:28Z
1 votes

我的logloss,MAE和其他均为NA时也遇到了类似的问题。 我查看了一下数据,发现其中几乎没有带有NA的功能。 我用近似值估算NA并能够解决该问题。

Not_Dave answered 2020-02-18T11:41:49Z
1 votes

我遇到了同样的问题,当时我正在使用Keras进行多元回归问题。 后来我意识到,我的数据集中有些值是nan,这导致了nan的损失。我使用了命令:

df=df.dropna()

它解决了我的问题。

Kushagra Bhatia answered 2020-02-18T11:42:19Z
translate from https://stackoverflow.com:/questions/37232782/nan-loss-when-training-regression-network