The*_*aly 48 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)] )
Run Code Online (Sandbox Code Playgroud)
然而,在训练过程中,我看到损失减少很好,但在第二个时代的中期,它变为南:
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
Run Code Online (Sandbox Code Playgroud)
我尝试使用RMSProp而不是SGD,我试过tanh而不是relu,我试着有没有辍学,都无济于事.我尝试使用较小的模型,即只有一个隐藏层,同样的问题(它在不同的点变成了nan).但是,它确实可以使用较少的功能,即如果只有5列,并提供了很好的预测.似乎存在某种溢出,但我无法想象为什么 - 损失根本不是非常大.
Python版本2.7.11,在linux机器上运行,仅限CPU.我用最新版本的Theano测试了它,我也得到了Nans,所以我尝试去Theano 0.8.2并遇到同样的问题.与最新版本的Keras有同样的问题,并且还有0.3.2版本.
1''*_*1'' 74
使用神经网络进行回归很难实现,因为输出是无界的,所以你特别容易出现爆炸梯度问题(nans的可能原因).
从历史上看,爆炸梯度的一个关键解决方案是降低学习速度,但随着像Adam这样的每参数自适应学习速率算法的出现,您不再需要设置学习速率来获得良好的性能.除非你是一个神经网络恶魔并且知道如何调整学习计划,否则没有理由再使用SGD动力了.
以下是您可能尝试的一些事项:
通过分位数标准化或z评分来标准化您的输出.要严格,请在训练数据上计算此变换,而不是在整个数据集上计算.例如,对于分位数归一化,如果示例在训练集的第60百分位数中,则其值为0.6.(您还可以将分位数归一化值向下移动0.5,使得第0百分位数为-0.5,第100百分位数为+0.5).
通过增加丢失率或向权重添加L1和L2惩罚来添加正则化.L1正则化类似于特征选择,并且因为您说将特征数量减少到5可以提供良好的性能,L1也可以.
如果这些仍然没有帮助,请减小网络的大小.这并不总是最好的主意,因为它可能会损害性能,但在您的情况下,相对于输入功能(35),您有大量的第一层神经元(1024),因此它可能有所帮助.
将批量大小从32增加到128. 128是相当标准的,可能会提高优化的稳定性.
pir*_*pir 30
1"的答案非常好.但是,所有修复似乎间接而不是直接解决问题.我建议使用渐变剪辑,它将简单地剪切任何高于某个值的渐变.
在Keras中,您可以使用clipnorm=1(请参阅https://keras.io/optimizers/)简单地剪切所有具有1以上范数的渐变.
小智 23
我之前遇到过同样的问题.我搜索并找到这个问题和答案.上面提到的所有技巧对于训练深度神经网络都很重要.我尝试了所有这些,但仍然有NAN.
我也在这里找到这个问题.https://github.com/fchollet/keras/issues/2134.我引用了作者的总结如下:"我想指出这一点,以便将其归档给将来可能遇到此问题的其他人.在进入训练过程之后,我突然遇到了失去的功能.我检查了relus,优化器,丢失函数,根据relus我的丢失,我的网络大小和网络的形状.我仍然感到失落,最终变成了一个纳,我变得非常沮丧.
然后它突然出现在我身上.我可能有一些不好的意见.事实证明,我向CNN提交的图像之一(并且正在进行归一化)只不过是0.当我减去平均值并通过标准偏差归一化时,我没有检查这种情况,因此我最终得到了一个样本矩阵,它只不过是nan的.一旦我修正了标准化功能,我的网络就可以完美地训练了."
我同意上述观点:输入对您的网络敏感.在我的例子中,我使用密度估计的对数值作为输入.绝对值可能非常大,这可能在几个梯度步骤后导致NaN.我认为输入检查是必要的.首先,您应该确保输入不包括-inf或inf,或绝对值中的一些非常大的数字.
jav*_*vac 15
我在使用 LSTM 时遇到了同样的问题,问题是我的数据在标准化后有一些 nan 值,因此,如果您看到有 nan 值,我们应该检查标准化后的输入模型数据:
print(np.any(np.isnan(X_test)))
print(np.any(np.isnan(y_test)))
Run Code Online (Sandbox Code Playgroud)
你可以通过像这样向 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
Run Code Online (Sandbox Code Playgroud)
Oth*_*ane 13
总结这里和这个github讨论中提到的不同解决方案,这当然取决于您的特定情况:
小智 10
我遇到了同样的问题,我正在使用 Keras 来解决多元回归问题。我后来意识到,我的数据集中的某些值是 nan,这导致了 nan 损失。我使用了命令:
df=df.dropna()
它解决了我的问题。
我遇到了一个非常类似的问题,这就是我如何运行它.
您可以尝试的第一件事是将激活更改为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
Run Code Online (Sandbox Code Playgroud)
并将其合并到您的图层中,如下所示:
model.add(Dense(800,input_shape=(num_inputs,)))
model.add(LeakyReLU(alpha=0.1))
Run Code Online (Sandbox Code Playgroud)
此外,输出功能(您尝试预测的连续变量)可能是不平衡的数据集并且具有太多的0.解决此问题的一种方法是使用平滑.您可以通过在此列中的所有值的分子上加1并将此列中的每个值除以1 /(此列中所有值的平均值)来执行此操作
这实际上将所有值从0移到大于0的值(可能仍然非常小).这可以防止曲线预测0并最小化损失(最终使其成为NaN).较小的值比较大的值受到的影响更大,但总的来说,数据集的平均值保持不变.
| 归档时间: |
|
| 查看次数: |
49522 次 |
| 最近记录: |