RNN 不会过度拟合简单数据
RNN is not overfitting on simple data
我正在尝试为输入向量中的每个数字预测 class。有 3 个 class。 Class 1,如果输入值从 0 变为 1。Class 2,如果它从 1 变为 0。Class 0 否则。
在第二个纪元之后,精度停留在 0.8824。更多的训练时期不会改变任何东西。我已经尝试将 LSTM
切换为 GRU
或 SimpleRNN
,这没有任何改变。我还尝试生成更长的输入向量和多个批次,同样没有成功。
唯一有帮助的是将 LSTM 层的大小增加到 128,添加三个 TimeDistributedDense(128, relu)
层,并在包括 LSTM 在内的每一层之后添加 BatchNormalization
。但是对于这样一个简单的问题来说似乎有点矫枉过正,而且无论如何都没有给出完美的结果。
我花了一天多的时间来让它发挥作用。可能是什么问题?
谢谢!
# complete code for training
from keras.models import Sequential
from keras.layers import Dense, LSTM, TimeDistributed
from keras.utils.np_utils import to_categorical
import numpy as np
np.random.seed(1337)
X = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])
Y = np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0])
Y_cat = to_categorical(Y, 3).reshape((1, len(X), 3))
X_r = X.reshape((1, len(X), 1))
model = Sequential()
model.add(LSTM(32, input_dim=1, return_sequences=True))
model.add(LSTM(32, return_sequences=True))
model.add(LSTM(32, return_sequences=True))
model.add(TimeDistributed(Dense(3, activation='softmax')))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_r, Y_cat, nb_epoch=10)
model.predict_classes(X_r) # will print array filled with zeros
你可以看出哪里出了问题,因为你的代码在第一个纪元后的损失值为 NaN。问题是过去不止一次困扰我的常见问题,即 fit
方法采用默认为 32 的 batch_size
参数。由于您只有一个示例,因此您甚至无法填写一批,这种情况显然不会被 Keras 检测到,但会导致错误的损失计算。所以你只需要把它改成:
model.fit(X_r, Y_cat, nb_epoch=10, batch_size=1)
不过,可能需要一些努力来拟合该数据。神经网络可能很难处理单个特征(如果输入是 one-hot 编码可能会更容易)并且数据很小。此外,bigger/deeper 网络越适合权重(即使它应该更强大)。但至少现在您将能够看到损失是如何减少的。我已经能够通过你的例子达到 100% 的准确率,删除第二和第三 LSTM 层并训练大约 250 个时期(当然,如果你有更多和更长的例子,这个数字肯定会更小)。
我正在尝试为输入向量中的每个数字预测 class。有 3 个 class。 Class 1,如果输入值从 0 变为 1。Class 2,如果它从 1 变为 0。Class 0 否则。
在第二个纪元之后,精度停留在 0.8824。更多的训练时期不会改变任何东西。我已经尝试将 LSTM
切换为 GRU
或 SimpleRNN
,这没有任何改变。我还尝试生成更长的输入向量和多个批次,同样没有成功。
唯一有帮助的是将 LSTM 层的大小增加到 128,添加三个 TimeDistributedDense(128, relu)
层,并在包括 LSTM 在内的每一层之后添加 BatchNormalization
。但是对于这样一个简单的问题来说似乎有点矫枉过正,而且无论如何都没有给出完美的结果。
我花了一天多的时间来让它发挥作用。可能是什么问题? 谢谢!
# complete code for training
from keras.models import Sequential
from keras.layers import Dense, LSTM, TimeDistributed
from keras.utils.np_utils import to_categorical
import numpy as np
np.random.seed(1337)
X = np.array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0])
Y = np.array([0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0])
Y_cat = to_categorical(Y, 3).reshape((1, len(X), 3))
X_r = X.reshape((1, len(X), 1))
model = Sequential()
model.add(LSTM(32, input_dim=1, return_sequences=True))
model.add(LSTM(32, return_sequences=True))
model.add(LSTM(32, return_sequences=True))
model.add(TimeDistributed(Dense(3, activation='softmax')))
model.compile(optimizer='rmsprop',
loss='categorical_crossentropy',
metrics=['accuracy'])
model.fit(X_r, Y_cat, nb_epoch=10)
model.predict_classes(X_r) # will print array filled with zeros
你可以看出哪里出了问题,因为你的代码在第一个纪元后的损失值为 NaN。问题是过去不止一次困扰我的常见问题,即 fit
方法采用默认为 32 的 batch_size
参数。由于您只有一个示例,因此您甚至无法填写一批,这种情况显然不会被 Keras 检测到,但会导致错误的损失计算。所以你只需要把它改成:
model.fit(X_r, Y_cat, nb_epoch=10, batch_size=1)
不过,可能需要一些努力来拟合该数据。神经网络可能很难处理单个特征(如果输入是 one-hot 编码可能会更容易)并且数据很小。此外,bigger/deeper 网络越适合权重(即使它应该更强大)。但至少现在您将能够看到损失是如何减少的。我已经能够通过你的例子达到 100% 的准确率,删除第二和第三 LSTM 层并训练大约 250 个时期(当然,如果你有更多和更长的例子,这个数字肯定会更小)。