在 keras 的 LSTM 中使用隐藏状态而不是输出

Use hidden states instead of outputs in LSTMs of keras

我想使用 Yang et al.. I found a working implementation of a custom layer that uses this attention machanism here 的注意力机制实现。而不是使用我的 LSTM 的输出值:

my_lstm = LSTM(128, input_shape=(a, b), return_sequences=True)
my_lstm = AttentionWithContext()(my_lstm)
out = Dense(2, activation='softmax')(my_lstm)

我想使用 LSTM 的隐藏状态:

my_lstm = LSTM(128, input_shape=(a, b), return_state=True)
my_lstm = AttentionWithContext()(my_lstm)
out = Dense(2, activation='softmax')(my_lstm)

但我收到错误消息:

TypeError: can only concatenate tuple (not "int") to tuple

我尝试将它与 return_sequences 结合使用,但到目前为止我尝试的所有方法都失败了。如何修改返回的张量以便像返回的输出序列一样使用它?

谢谢!

我认为您的困惑可能源于 Keras 文档有点不清楚。

return_sequences: Boolean. Whether to return the last output in the output sequence, or the full sequence.
return_state: Boolean. Whether to return the last state in addition to the output.

return_state 上的文档特别令人困惑,因为它们暗示隐藏状态与输出不同,但它们是相同的。对于 LSTM,这有点模糊,因为除了隐藏(输出)状态之外,还有单元状态。我们可以通过查看 Keras 代码中的 LSTM 阶跃函数来确认这一点:

class LSTM(Recurrent):
    def step(...):
        ...
        return h, [h, c]

此步进函数的return类型为output, states。所以我们可以看到隐藏状态 h 实际上是输出,对于状态我们得到隐藏状态 h 和单元状态 c。这就是为什么您看到链接的 Wiki article 交替使用术语 "hidden" 和 "output"。

仔细查看您链接的论文,在我看来您的原始实现就是您想要的。

my_lstm = LSTM(128, input_shape=(a, b), return_sequences=True)
my_lstm = AttentionWithContext()(my_lstm)
out = Dense(2, activation='softmax')(my_lstm)

这会将每个时间步的隐藏状态传递给您的注意力层。唯一不走运的情况是您实际上想要将单元状态从每个时间步传递到您的注意力层(这是我最初的想法),但我认为这不是您想要的。您链接的论文实际上使用了一个 GRU 层,它没有细胞状态的概念,其步进函数也 return 隐藏状态作为输出。

class GRU(Recurrent):
    def step(...):
        ...
        return h, [h]

所以这篇论文几乎肯定是指隐藏状态(也就是输出)而不是细胞状态。

只是为了给 Nicole 的回答加一分 -

如果我们在 LSTM 中使用 return_state = Truereturn_sequences = True 的组合,那么第一个 [h] 将 return 隐藏状态也就是每个时间步长(向量)的输出,而第二个 [ h] 将 return 最后一个时间步的隐藏状态(标量)。