我正在尝试使用 Keras 实现一个 LSTM 层,并在一个非常简单的数据库上进行测试。
这是我的代码
X = np.load("X.npy")y = np.load("y.npy")trainX = X[:30, :, :]testX = X[30:, :, :]trainY = y[:30, :]testY = y[30:, :]lastDense = X.shape[2]if(X.shape[2] == 1): lastDense = 1 trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))in_out_neurons = trainX.shape[2]hidden_neurons = 100model = Sequential()model.add(LSTM(in_out_neurons, return_sequences=False, input_shape=(None, in_out_neurons)))model.add(Dense(hidden_neurons))model.add(Dropout(0.1))model.add(Dense(lastDense))model.add(Activation("linear"))model.compile(loss="mse", optimizer="adam")model.fit(trainX, trainY, nb_epoch=700, batch_size=trainX.shape[0])print 'train'print trainXprint model.predict(trainX)print 'test'print testXprint model.predict(testX)
它没有显示任何错误,运行并显示输出。
我给它的序列只是从1到39的数字按递增顺序排列,其中1到31是训练集,32到39是测试集。
这些数字是按三元组排列的,这意味着一个训练样本将是 (1, 2, 3)
,我期望输出是 4
。
这是训练数据的输出
train[[[ 1. 2. 3.]] [[ 2. 3. 4.]] [[ 3. 4. 5.]] [[ 4. 5. 6.]] [[ 5. 6. 7.]] [[ 6. 7. 8.]] [[ 7. 8. 9.]] [[ 8. 9. 10.]] [[ 9. 10. 11.]] [[ 10. 11. 12.]] [[ 11. 12. 13.]] [[ 12. 13. 14.]] [[ 13. 14. 15.]] [[ 14. 15. 16.]] [[ 15. 16. 17.]] [[ 16. 17. 18.]] [[ 17. 18. 19.]] [[ 18. 19. 20.]] [[ 19. 20. 21.]] [[ 20. 21. 22.]] [[ 21. 22. 23.]] [[ 22. 23. 24.]] [[ 23. 24. 25.]] [[ 24. 25. 26.]] [[ 25. 26. 27.]] [[ 26. 27. 28.]] [[ 27. 28. 29.]] [[ 28. 29. 30.]] [[ 29. 30. 31.]] [[ 30. 31. 32.]]][[ 4.09406757] [ 5.05801105] [ 5.98857021] [ 6.88568211] [ 7.78905582] [ 8.71695137] [ 9.67439938] [ 10.66011047] [ 11.66990376] [ 12.69835663] [ 13.73967934] [ 14.78820229] [ 15.83870316] [ 16.88658524] [ 17.92800713] [ 18.95988846] [ 19.97993088] [ 20.98649979] [ 21.97856903] [ 22.95560837] [ 23.91747856] [ 24.86432266] [ 25.79648972] [ 26.71446228] [ 27.61878586] [ 28.51003265] [ 29.3887558 ] [ 30.25547028] [ 31.11066628] [ 31.77085686]]
它运行得相当好。你可以看到第一个例子确实是 [1, 2, 3],输出是 4.09。下一个例子是 [2, 3, 4],输出是 5.05,这对我来说已经足够好了。
但是在测试集中,每个例子得到的结果都是相同的。
test[[[ 31. 32. 33.]] [[ 32. 33. 34.]] [[ 33. 34. 35.]] [[ 34. 35. 36.]] [[ 35. 36. 37.]] [[ 36. 37. 38.]] [[ 37. 38. 39.]]][[ 31.81325912] [ 31.85035133] [ 31.88280106] [ 31.91120529] [ 31.93606949] [ 31.95784378] [ 31.97691345]]
结果非常糟糕。我是在过拟合吗?我使用了 dropout,所以不应该这样,但不知道发生了什么以及如何修复它。我是否错误地使用了 Keras 的 LSTM 层?
回答:
是的,计数是一个 LSTM 可以完美执行的简单功能。
- 打乱样本顺序,使网络无法学习批次之间的增量变化。
-
添加一个验证集,可能再分一次。Keras 允许你使用 validation_data,看看它,可能在第 “n” 个周期开始过拟合,所以你可以 “提前停止” 学习过程。
-
减少神经元的数量,计数或求和是一个非常简单的操作。
- 如果这些方法都不奏效…增加样本数量…也许到1万。增加样本数量可以避免过拟合。
玩得开心!
示例:
X = []for x in range(100): X.append([[x], [x+1], [x+2], [x+3]])X = np.array(X)np.random.shuffle(X)trainX = X[:30, 0:-1, :]testX = X[30:, 0:-1, :]trainY = X[:30, -1, :]testY = X[30:, -1, :]lastDense = X.shape[2]in_out_neurons = trainX.shape[1]hidden_neurons = 100model = Sequential()model.add(LSTM(in_out_neurons, return_sequences=False, input_shape=( in_out_neurons,1)))model.add(Dense(hidden_neurons))model.add(Dense(lastDense))model.add(Activation("linear"))model.compile(loss="mse", optimizer="adam", lr=.1)model.fit(trainX, trainY,validation_split=0.05, epochs=2000, batch_size=trainX.shape[0])print ('train')print (trainX)print (model.predict(trainX))print ('test')print (testX)print (model.predict(testX))