在有效但良好地训练LSTM上,并行性与训练方式

时间:2018-08-08 19:20:00

标签: python machine-learning neural-network keras lstm

对于我打算自发生成序列的模型,我发现逐个样本地训练它并保持其间的状态是最自然的。在阅读了许多有用的资源之后,我设法在Keras中构建了它。 (因此:Q and two fantastic answers,Macine Learning Mastery 123

首先构建一个序列(在我的情况下也是单编码)。通过将Y向前移动一个时间步,可以从该序列中删除X和Y。训练以一个样本和一个时间步为单位进行。

对于Keras,这看起来像这样:

data = get_some_data()   # Shape (samples, features)
Y = data[1:, :]          # Shape (samples-1, features)
X = data[:-1, :].reshape((-1, 1, data.shape[-1])) # Shape (samples-1, 1, features)

model = Sequential()
model.add(LSTM(256, batch_input_shape=(1, 1, X.shape[-1]), stateful=True))
model.add(Dense(Y.shape[-1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['categorical_accuracy'])

for epoch in range(10):
    model.fit(X, Y, batch_size=1, shuffle=False)
    model.reset_states()

它确实起作用。但是,在咨询我的任务管理器后,似乎只使用了我的GPU资源的大约10%,而这已经非常有限了。我想改善这一点以加快培训速度。批处理大小的增加将允许并行计算。

即使在训练序列开始时,处于当前状态的网络也可能“记住”事物。对于分批训练,需要首先设置序列,然后预测一个值-并对多个值进行此操作。要训​​练完整的序列,将需要生成(samples-steps, steps, features)形式的数据。我想拥有至少跨越几百个时间步长的序列并不少见。因此,这将意味着数据量的巨大增加。

在对问题的框架有所不同并且需要将更多数据存储在内存中并且仅利用少量处理资源之间,我必须问:

  • 我对自然训练和有状态的理解是否正确?
  • 此培训是否还有其他弊端,每批次只有一个样本?
  • 可以通过其他方式解决利用率问题吗?
  • 最后,是否存在进行这种训练以生成长序列的公认方法?

任何帮助都将不胜感激,我对LSTM还是陌生的。

1 个答案:

答案 0 :(得分:1)

我不知道您的特定应用程序,但是仅发送一个时间步的数据肯定不是一个好主意。您应该改为给LSTM先前给定的单热点矢量(可能是单词)的整个序列,并在必要时给pre-pad(带有零),因为您似乎正在处理不同长度的序列。如果这些确实是单词,请考虑在LSTM之前使用embedding层。仔细阅读文档。

GPU利用率低不是问题。您根本没有足够的数据来充分利用每个批次中的所有资源。分批培训是一个顺序的过程,没有真正的方法可以并行化此过程,至少是一种介绍性的并且对您的目标有益的方法。但是,如果确实在每个时间步上为LSTM提供了更多数据,那肯定会增加您的利用率。

LSTM中的

statefull不会执行您认为的操作。 LSTM 始终会记住它在更新其内部隐藏状态hc时要遍历的序列。此外,在训练过程中学会了“建立”那些内部状态的权重转换。 stateful的作用是保留上一个批处理索引中的上一个隐藏状态。这意味着,批次中第三个元素的最终隐藏状态将作为下一个批次中第三个元素的初始隐藏状态发送,依此类推。我认为这对您的应用程序没有帮助。

使用每批一个样本来训练LSTM有不利之处。通常,使用min-batches increases stability进行培训。但是,您似乎不是在训练每批次一个样品,而是每个样本一个时间步长


编辑(来自评论)

如果您使用有状态并在与前一批相同的索引中发送序列的下一个“字符”,则类似于发送每个样本的完整序列时间步长。我仍然建议使用上述初始方法,以提高应用程序的速度并与其他LSTM应用程序保持一致。对于每个样本发送完整序列而不是在每个批次中发送完整序列的方法,我认为没有任何缺点。但是,速度的优势,能够按批次重新整理输入数据以及更具可读性/一致性的优点将值得IMO更改。