Keras状态性LSTM

5
请考虑这个简单的例子。
nb_samples = 100000
X = np.random.randn(nb_samples)
Y = X[1:]
X = X[:-1]
X = X.reshape((len(Y), 1, 1))
Y = Y.reshape((len(Y), 1))

所以我们基本上
Y[i] = X[i-1]

这个模型只是一个滞后运算符。

我可以用无状态的LSTM学习这个模型,但我想在Keras中理解和应用有状态的LSTM。

因此,我尝试使用有状态的LSTM学习这个模型,逐一给定值对(x, y)(batch_size = 1)

model = Sequential()
model.add(LSTM(batch_input_shape=(1, 1, 1),
               output_dim =10,
               activation='tanh', stateful=True
          )
    )
model.add(Dense(output_dim=1, activation='linear'))
model.compile(loss='mse', optimizer='adam')


for epoch in range(50):
    model.fit(X_train,
              Y_train,
              nb_epoch = 1,
              verbose = 2,
              batch_size = 1,
              shuffle = False)
    model.reset_states()

但是模型什么也没学到。

根据Marcin的建议,我修改了训练代码如下:

for epoch in range(10000):
    model.reset_states()
    train_loss = 0
    for i in range(Y_train.shape[0]):
        train_loss += model.train_on_batch(X_train[i:i+1],
                         Y_train[i:i+1],
                         )
    print '# epoch', epoch, '  loss ', train_loss/float(Y_train.shape[0])

但我仍然看到平均损失约为1,这是我随机生成的数据的标准差,因此模型似乎没有学习。

我是不是出了什么问题?


1
你尝试过增加单元的数量吗?你希望你的网络能够完全记忆长度为10000的随机模式 - 因此实际上它应该被作为一个序列完全记忆。10个单元可能对此来说不够。你也可以减少序列长度或尝试检查一些连续函数(如sine或多项式)。目前,你的架构似乎对你的任务来说过于简单了。 - Marcin Możejko
@volatile LSTM经常学习运行平均值。 randn的运行平均值将为0。 如果这是您的输出,则实际上学习成功了。尝试学习有意义的东西。 - nemo
@nemo:感谢您的回答。我不是在学习长度为10000的随机模式,而是一个模式,其中t时刻的输出应该是t-1时刻的输入。我希望网络能够学会将输入x[t]简单地放入其隐藏状态中,然后在t+1时刻,将其隐藏状态作为输出y[t+1]返回,并用x[t+1]替换隐藏状态,以此类推。显然,我可以使用具有移动窗口的无状态LSTM来实现这一点,但是我希望使用有状态的LSTM来获得结果。 - volatile
1个回答

1

您可能已经在这里阅读到,即使由于网络的状态性质而不重置模型状态,优化器参数也会被重置,而且由于优化器在循环神经网络训练中非常重要,重置它们的状态可能对您的训练非常有害。为了防止这种情况,请尝试:

for epoch in range(50):
    model.train_on_batch(X_train,
              Y_train)
    model.reset_states()
< p > train_on_batch 方法不会重置优化器状态,这可能会使您的训练变得不可行。 < /p >

谢谢。我尝试了,但似乎不起作用。我更新了我的问题,说明我现在在做什么。 - volatile

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接