训练回归网络时NaN损失

时间:2016-05-14 23:04:30

标签: python theano keras

我有一个“one-hot encoding”(全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)] )

然而,在训练过程中,我看到损失减少很好,但在第二个时代的中期,它变成了南:

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版本。

22 个答案:

答案 0 :(得分:61)

使用神经网络进行回归很难实现,因为输出是无界的,因此您特别容易出现exploding gradients problem(可能是nans的原因)。

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

以下是您可能尝试的一些事项:

  1. quantile normalizingz scoring标准化您的输出。要严格,请在训练数据上计算此变换,而不是在整个数据集上计算。例如,对于分位数归一化,如果示例在训练集的第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 :(得分:24)

1“的答案非常好。但是,所有修复似乎间接而不是直接解决问题。我建议使用渐变剪辑,它只会剪切任何高于某个值的渐变。

在Keras中,您可以使用clipnorm=1(请参阅https://keras.io/optimizers/)简单地剪切所有梯度,其范围大于1。

答案 2 :(得分:18)

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

我也在这里找到这个问题。 https://github.com/fchollet/keras/issues/2134。 我引用作者的总结如下: “我想指出这一点,以便将来可能会遇到此问题的其他人存档。在进入训练过程之后,我突然遇到了失去的功能。我检查了relus,优化器,丢失函数,根据relus我的丢失,我的网络大小和网络的形状。我仍然受到损失,最终变成了一个纳,我变得非常沮丧。

然后我突然意识到了。我可能有一些不好的意见。事实证明,我递给我的CNN的图像之一(并且正在进行标准化)只不过是0。当我减去平均值并通过标准偏差归一化时,我没有检查这种情况,因此我最终得到了一个范例矩阵,这只不过是南方的。一旦我修正了规范化功能,我的网络就可以完美地训练了。“

我同意上述观点:输入对您的网络很敏感。 在我的情况下,我使用密度估算的日志值作为输入。绝对值可能非常大,这可能在几个梯度步骤后导致NaN。我认为输入检查是必要的。首先,您应确保输入包含 -inf或inf ,或绝对值中的一些非常大的数字。

答案 3 :(得分:9)

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

  • 添加正则化将权重增加l1或l2。否则,请尝试使用较小的l2 reg。即l2(0.001),或者如果已经存在则将其删除。
  • 尝试较小的辍学率。
  • 剪切渐变以防止其爆炸。例如,在Keras中,您可以使用clipnorm = 1。或clipvalue = 1。作为优化程序的参数。
  • 检查输入的有效性(无NaN或有时为0)。即df.isnull()。any()
  • 用更容易处理的Adam替换优化器。有时也用rmsprop替换sgd会有所帮助。
  • 使用RMSProp进行正则化以防止梯度爆炸。
  • 尝试规范化数据,或检查规范化过程中是否引入了任何不良值。
  • 验证您使用的激活功能正确(例如,使用softmax代替Sigmoid进行多类分类)。
  • 尝试增加批量大小(例如32至64或128),以提高优化的稳定性。
  • 尝试降低学习率。
  • 检查最后一个批次的大小,该大小可能与批次大小不同。

答案 4 :(得分:6)

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

您可以尝试的第一件事是将激活更改为LeakyReLU,而不是使用Relu或Tanh。原因是,层中的许多节点通常激活为零,并且反向传播不会更新这些节点的权重,因为它们的梯度也为零。这也称为“垂死的ReLU”问题(您可以在此处了解更多信息: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)。较小的值比较大的值受到的影响更大,但总体而言,数据集的平均值保持不变。

答案 5 :(得分:2)

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

答案 6 :(得分:2)

一旦训练开始,我就在第一个时代得到了损失。解决方法就像从输入数据中删除nas一样简单(df.dropna())

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

答案 7 :(得分:2)

尝试检查您的数据是否有NAN值。删除NAN值可以为我解决问题。

答案 8 :(得分:1)

我的keras CNN遇到了同样的问题,就像其他我尝试过上述所有解决方案的问题一样:降低学习率,从训练数据中删除无效性,对数据进行规范化,添加退出层并... 但是无法解决nan问题,我尝试将分类器(最后)层中的激活函数从Sigmoid更改为softmax。有效! 尝试将最后一层的激活功能更改为softmax!

答案 9 :(得分:1)

在我的情况下,问题是我复制粘贴了以前的工作以进行二进制分类,并在输出层而不是sigmoid上使用了softmax激活(新网络涉及多类分类)。 / p>

答案 10 :(得分:1)

我的keras LSTM层的RNN遇到相同的问题,因此我从上面尝试了每种解决方案。我已经缩放了数据(使用sklearn.preprocessing.MinMaxScaler),缩放后数据中没有NaN值。使用LeakyRelU或更改学习率等解决方案均无济于事。

因此,我决定将缩放器从MinMaxScaler更改为StandardScaler,即使我没有NaN值,但发现它很奇怪,但仍然有效!

答案 11 :(得分:1)

我在使用keras时遇到了类似的问题。输入第二批后损失变为NAN。

我试图:

  1. 使用softmax激活输出密集层
  2. 将nan输入到输入中
  3. 标准化输入

但是,那没有用。所以,然后我尝试:

  1. 降低学习率

问题解决了。

答案 12 :(得分:0)

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

df=df.dropna()

它解决了我的问题。

答案 13 :(得分:0)

使用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

答案 14 :(得分:0)

当我尝试创建边界框回归器时,我得到了同样的东西。 我的神经网络比你的神经网络更大。我提高了辍学率,并得到了合适的结果。

答案 15 :(得分:0)

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

答案 16 :(得分:0)

正在为我的分类网络获取NaN。 在这里回答可能会帮助某人。

犯了一个错误-

培训标签中的课程数量为5。即从0到4。

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

将网络最后一层的节点数减少到5个对我来说解决了这个问题。

答案 17 :(得分:0)

我遇到了类似的问题,我尝试将激活从 Sigmoid 更改为 Softmax,从 RelU 更改为 LeakyRelU,问题解决了。所以我想只要输入中没有 NaN,并且您已经尝试降低学习率,可行的解决方案就是使用您的激活!

答案 18 :(得分:0)

我尝试了此页面上的所有建议以及其他许多建议无济于事。我们使用pandas导入csv文件,然后使用带有文本输入的keras Tokenizer来创建词汇表和单词矢量矩阵。在注意到一些CSV文件导致其他人工作之后,突然我们查看了文件的编码并意识到 ascii 文件不能与keras一起工作,导致nan丢失和准确性0.0000e+00;但是, utf-8和utf-16文件 正在工作!突破。

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

答案 19 :(得分:0)

我遇到了同样的问题。成功地您可以使用 keras 进行回归。 将您的所有数据转换为四舍五入的数字解决了我的问题。 例如。 23.43 到 23

答案 20 :(得分:0)

我的情况:

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

后来我发现这是因为我的标签是 1, 2, 3, 4 不是以 0 开头。 所以我重新标记它们,使用 0, 1, 2, 3 而不是 1, 2, 3, 4 作为标签。 问题解决了!

希望我的回答有帮助!

答案 21 :(得分:-2)

我遇到了同样的问题。检查数据,我意识到数据采集过程中发生了错误。