我正在创建一个语言模型:具有 2 个双向 LSTM 层的 seq2seq 模型。我已经有了要训练的模型,并且准确性似乎不错,但是在坚持弄清楚推理模型的同时,我发现自己对每个 LSTM 层返回的状态有点困惑。
我使用本教程作为指南,尽管此链接中的示例未使用双向层:https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning -in-keras.html
注意:我正在使用预训练的词嵌入。
lstm_units = 100
# Set up embedding layer using pretrained weights
embedding_layer = Embedding(total_words+1, emb_dimension, input_length=max_input_len, weights=[embedding_matrix], name="Embedding")
# Encoder
encoder_input_x = Input(shape=(None,), name="Enc_Input")
encoder_embedding_x = embedding_layer(encoder_input_x)
encoder_lstm_x, enc_state_h_fwd, enc_state_c_fwd, enc_state_h_bwd, enc_state_c_bwd = Bidirectional(LSTM(lstm_units, dropout=0.5, return_state=True, name="Enc_LSTM1"), name="Enc_Bi1")(encoder_embedding_x)
encoder_states = [enc_state_h_fwd, enc_state_c_fwd, enc_state_h_bwd, enc_state_c_bwd]
# Decoder
decoder_input_x = Input(shape=(None,), name="Dec_Input")
decoder_embedding_x = embedding_layer(decoder_input_x)
decoder_lstm_layer = Bidirectional(LSTM(lstm_units, return_state=True, return_sequences=True, dropout=0.5, name="Dec_LSTM1"))
decoder_lstm_x, _, _, _, _= decoder_lstm_layer(decoder_embedding_x, initial_state=encoder_states)
decoder_dense_layer = TimeDistributed(Dense(total_words+1, activation="softmax", name="Dec_Softmax"))
decoder_output_x = decoder_dense_layer(decoder_lstm_x)
model = Model(inputs=[encoder_input_x, decoder_input_x], outputs=decoder_output_x)
model.compile(loss='sparse_categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
我希望编码器将
enc_state_h_fwd
和 enc_state_c_fwd
转发给解码器。此连接由橙色箭头突出显示。
但是由于模型是双向的,我有一些问题:
encoder_states
输出 4 个状态。 h
和 c
表示前进和后退。我觉得“向后”状态在我的图表中由编码器左侧的粉红色箭头表示。我将这些传递给解码器,但为什么它需要它们?我是否错误地将左侧的粉色箭头连接到从右侧进入解码器的紫色箭头?该模型无效。它被设置为一个翻译模型,在推理期间一次预测一个单词,从
start of sequence token
开始,预测 y1,然后循环并输入 start of sequence token, y1
以获得 y2 等。
除非整个解码器输入可用,否则双向 LSTM 不能用于多对多预测中的实时预测。在这种情况下,解码器输入仅在每次预测一个步骤后才可用,因此如果没有序列的其余部分 (y2-yt),第一个预测 (y1) 是无效的。
因此解码器不应该是双向 LSTM。
至于状态,编码器双向 LSTM 确实输出
h
和 c
前进状态(橙色箭头),以及 h
和 c
后退状态(粉色箭头)。
通过连接这些状态并将它们提供给解码器,我们可以为解码器提供更多信息。这是可能的,因为我们在推理时确实拥有整个编码器输入。
还需要注意的是,带有
lstm_units
(例如 100)的双向编码器实际上有 200 个 lstm 单元,一半向前,一半向后。要将这些输入解码器,解码器也必须有 200 个单元。