我正在尝试在 tensorflow 中使用 MultiRNNCell 和 GRUCell 实现堆叠 RNN。
从GRUCell的默认实现可以看出,GRUCell的“输出”和“状态”是一样的:
class GRUCell(RNNCell)
...
def call(self, inputs, state):
...
new_h = u * state + (1 - u) * c
return new_h, new_h
这是有道理的,因为它与定义一致。但是,当我们将它们与 MultiRNNCell 堆叠时,定义为:
class MultiRNNCell(RNNCell):
...
def call(self, inputs, state):
...
cur_inp = inputs
new_states = []
for i, cell in enumerate(self._cells):
# set cur_state = states[i] ...
cur_inp, new_state = cell(cur_inp, cur_state)
new_states.append(new_state)
return cur_inp, new_states
(代码已被压缩以突出显示相关位)
在这种情况下,任何不是第一个 GRUCell 的 GRUCell 都会收到相同的“输入”和“状态”值。本质上,它在单个输入上运行,即前一层的输出。
由于重置/更新门的值取决于两个输入值(输入/状态)的比较,这最终不会成为冗余操作,最终会直接从第一层传递值吗?
MultiRNNCell 的这种架构似乎主要是在设计时考虑了 LSTM 单元,因为它们将输出和单元状态分开,但不适用于 GRU 单元。