【问题标题】:Bad output from keras LSTM generating a simple sequencekeras LSTM 的错误输出生成一个简单的序列
【发布时间】:2017-04-25 12:43:29
【问题描述】:

我正在尝试使用 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 = 100

model = 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 trainX
print model.predict(trainX)

print 'test'
print testX
print 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层?

【问题讨论】:

    标签: python machine-learning deep-learning keras lstm


    【解决方案1】:

    是的,count 是一个 LSTM 可以完美完成的简单函数。

    • 打乱网络不学习批次间增量的示例。
    • 添加一个验证集,可能是另一个拆分。 Keras 允许您使用 validation_data 来查看它,也许在“第 n 个”时期有一个点开始过度拟合,因此您可以“early stop”学习。

    • 减少神经元的数量,计数或求和是一个非常简单的操作。

    • 如果这不起作用.. 增加示例数.. 可能是 10k。增加示例数量可以避免过度拟合。

    玩得开心!

    例子:

    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 = 100
    
    model = 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))
    

    【讨论】:

    • 这些东西都没有帮助。我认为代码可能有问题。我是否需要使用有状态的机器?
    • np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1])) Keras 期望输入为 (batch_size, sequence_len, features) 所以你的形状应该是 ( X, 3, 1) 就像一个 char 级 charbot..
    • 奇怪的是,当我这样做时它不起作用。这就是我添加“如果”部分的原因。并且只有在每个示例中的功能数量为 1 时,它才不起作用。我的意思是没有像 in 那样工作 - 根本没有运行。出错了。
    • 因为您应该根据您的数据将 input_shape 固定为 input_shape=(3,)input_shape=(3, 1)
    • 删除了整形,我的数据现在是 (10000, 3, 1) 并且我尝试过输入形状 (3,1) 和 (3,)。在 (3,) 我得到一个错误“ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=2”,当它的 (3, 1) 我得到一个错误“TypeError: Cannot convert Type TensorType( float32, 3D) (变量 Subtensor{:int64:}.0) 转换为 TensorType(float32, (False, False, True))。您可以尝试手动将 Subtensor{:int64:}.0 转换为 TensorType(float32 ,(假,假,真))。”
    猜你喜欢
    • 2019-04-14
    • 2021-01-19
    • 1970-01-01
    • 2018-04-17
    • 2018-06-25
    • 1970-01-01
    • 2021-10-02
    • 2017-07-27
    • 1970-01-01
    相关资源
    最近更新 更多