如何在 Keras 中为双向 LSTM 配置输入形状

How to configure input shape for bidirectional LSTM in Keras

我面临以下问题。 我有大量文档要使用双向 LSTM 进行编码。每个文档都有不同数量的单词,单词可以被认为是一个时间步长。

配置双向 LSTM 时,我们需要提供时间序列长度。 当我训练模型时,每个批次的这个值都会不同。 我应该为 timeseries_size 选择一个数字,这是我允许的最大文档大小吗?任何比这更大的文档都不会被编码?

示例配置:

Bidirectional(LSTM(128, return_sequences=True), input_shape=(timeseries_size, encoding_size))

这是一个众所周知的问题,它涉及普通和双向 RNN。 This discussion on GitHub 可能会对您有所帮助。本质上,这是最常见的选项:

  • 一个简单的解决方案是将 timeseries_size 设置为训练集的最大长度,并用零填充较短的序列。 Example Keras code。如果训练集恰好有很长和很短的输入,一个明显的缺点是内存浪费。

  • 将输入样本分成不同长度的桶,例如length <= 16 的一个桶,length <= 32 的另一个桶,等等。基本上这意味着为不同的句子集训练几个单独的 LSTM。这种方法(称为 bucketing)需要更多的努力,但目前被认为是最有效的,并且实际上用于最先进的翻译引擎 Tensorflow Neural Machine Translation.

一种选择是使用可变长度配置模型:input_shape=(None,encoding_size)

然后您将必须单独训练每个文档。

for epoch in range(epochs):
    for document,output in zip(list_of_documents,list_of_outputs):
        #make sure you have a batch, even if its size is 1
        document.reshape((1,this_doc_length,encoding_size)) 
        output.reshape((1,whatever_output_shape,...))   

        model.train_on_batch(document,output,....)

其他选项是使用最大长度的单个输入数组并添加 Masking 层。 (如果您使用的是 Embedding 层,则与制作参数 mask_zero=True 一样简单)

这对于单向 LSTM 非常有效,但我不确定它是否适用于双向(从未测试过)。