我运行在Keras中使用imdb数据集的LSTM网络的示例代码。可以在以下链接中找到代码。 imdb_lstm.py
我的问题是随着代码的进展,训练损失减少,训练准确度也随着预期的增加而增加,但验证准确度在一个区间内波动,验证损失增加到一个很高的值。我附上下面培训阶段的部分日志。即使我观察到,当训练损失非常小(~0.01-0.03)时,有时它会在下一个时期增加,然后再次减少。我提到的可以在时代75-77中看到。但总的来说它会减少。
我的期望是训练准确性总是增加到0.99-1并且训练损失总是减少。此外,验证准确度应该从0.4开始并最终提高到例如0.8。如果验证准确性没有改善,那么在时代期间等待的重点是什么?最后,测试精度接近0.81。
我也尝试了自己的数据并提出了同样的情况。我以类似的方式处理我的数据。我的意思是我的训练,验证和测试点的处理方式与本示例代码中的相同。
此外,在从LSTM获取每个单词的输出后,我不明白该代码如何表示整个句子。它是否进行均值或最大池化,还是只将LSTM层的最后一个输出提供给逻辑回归分类器?
任何帮助都将不胜感激。
Using Theano backend.
Loading data...
25000 train sequences
25000 test sequences
Pad sequences (samples x time)
X_train shape: (25000, 80)
X_test shape: (25000, 80)
Build model...
Train...
Train on 22500 samples, validate on 2500 samples
Epoch 1/100
22500/22500 [==============================] - 236s - loss: 0.5438 - acc: 0.7209 - val_loss: 0.4305 - val_acc: 0.8076
Epoch 2/100
22500/22500 [==============================] - 237s - loss: 0.3843 - acc: 0.8346 - val_loss: 0.3791 - val_acc: 0.8332
Epoch 3/100
22500/22500 [==============================] - 245s - loss: 0.3099 - acc: 0.8716 - val_loss: 0.3736 - val_acc: 0.8440
Epoch 4/100
22500/22500 [==============================] - 243s - loss: 0.2458 - acc: 0.9023 - val_loss: 0.4206 - val_acc: 0.8372
Epoch 5/100
22500/22500 [==============================] - 239s - loss: 0.2120 - acc: 0.9138 - val_loss: 0.3844 - val_acc: 0.8384
....
....
Epoch 75/100
22500/22500 [==============================] - 238s - loss: 0.0134 - acc: 0.9868 - val_loss: 0.9045 - val_acc: 0.8132
Epoch 76/100
22500/22500 [==============================] - 241s - loss: 0.0156 - acc: 0.9845 - val_loss: 0.9078 - val_acc: 0.8211
Epoch 77/100
22500/22500 [==============================] - 235s - loss: 0.0129 - acc: 0.9883 - val_loss: 0.9105 - val_acc: 0.8234
答案 0 :(得分:7)
何时停止培训:当验证数据计算的某个指标开始增长时,这是停止培训的常用方法。这是过度拟合的常用指标。但请注意,您正在使用辍学技术 - 这会导致在每个时期内训练略有不同的模型 - 这就是为什么您应该应用某种耐心 - 并且当这样的现象发生在几个连续的时期时停止训练。
波动的原因:与第一点相同 - 您正在使用一种辍学技术,它会为您的网络带来某种随机性。这是我认为观察到波动的主要原因。
Keras模型将其作为Dense图层的输入:如果您仔细研究LSTM/RNN图层的文档,您会注意到return_sequences=False
设置为默认参数。这意味着只将处理序列的最后一个输出作为下一层的输入。您可以使用1-D Convolutions更改该内容。