TensorFlow 2 中的堆叠双向 RNN 令人困惑

Posted

技术标签:

【中文标题】TensorFlow 2 中的堆叠双向 RNN 令人困惑【英文标题】:Puzzled by stacked bidirectional RNN in TensorFlow 2 【发布时间】:2020-10-18 00:34:53 【问题描述】:

我正在学习如何基于this TensorFlow 2 NMT tutorial 构建一个 seq2seq 模型,并且我正在尝试通过为编码器和解码器堆叠多个 RNN 层来扩展它。但是,我无法检索对应于编码器隐藏状态的输出。

这是我在编码器中构建堆叠双向GRUCell 层的代码:

# Encoder initializer
def __init__(self, n_layers, dropout, ...):
    ...
    gru_cells = [layers.GRUCell(units, 
                                recurrent_initializer='glorot_uniform',
                                dropout=dropout)
                 for _ in range(n_layers)]
    self.gru = layers.Bidirectional(layers.RNN(gru_cells,
                                               return_sequences=True,
                                               return_state=True))

假设以上是正确的,那么我调用我创建的层:

# Encoder call method
def call(self, inputs, state):
    ...
    list_outputs = self.gru(inputs, initial_state=state)
    print(len(list_outputs)) # test

list_outputsn_layers = 1 时的长度为 3,这是根据this SO post 的预期行为。当我将n_layers 增加一时,我发现输出的数量增加了二,我认为这是新层的正向和反向最终状态。所以 2 层 -> 5 个输出,3 层 -> 7 个输出,等等。但是,我无法弄清楚哪个输出对应于哪个层和哪个方向。

最终我想知道的是:如何在这个堆叠的双向 RNN 中获得 last 层的正向和反向最终状态?如果我正确理解了 seq2seq 模型,它们构成了传递给解码器的隐藏状态。

【问题讨论】:

【参考方案1】:

在挖掘了RNNBidirectional 类的TensorFlow 源代码后,我对堆叠双向RNN 层的输出格式的最佳猜测是以下1+2n 元组,其中n 是堆叠层数:

[0] 跨 RNN 的前向和后向状态串联 [1 : len//2 + 1] 前向层的最终状态,从第一个到最后一个 [len//2 + 1:] 反向层的最终状态,从第一个到最后一个

【讨论】:

以上是关于TensorFlow 2 中的堆叠双向 RNN 令人困惑的主要内容,如果未能解决你的问题,请参考以下文章

ValueError: Tensor 必须来自与 Tensorflow 中具有双向 RNN 的 Tensor 相同的图

在tensorflow中使用glstm(Group LSTM) cell构建双向rnn

TensorFlow实战12:Bidirectional LSTM Classifier

使用 TensorFlow 进行端到端语音识别的 RNN

TensorFlow 中的 RNN 实时实现

Tensorflow 与 Keras 中的 RNN,tf.nn.dynamic_rnn() 的贬值