【问题标题】:Tensorflow RNN cells have different weightsTensorflow RNN 单元具有不同的权重
【发布时间】:2017-09-24 08:24:21
【问题描述】:

我正在尝试在 tensorflow 中编写一个简单的 RNN,基于此处的教程:https://danijar.com/introduction-to-recurrent-networks-in-tensorflow/ (我使用的是简单的 RNN 单元而不是 GRU,并且没有使用 dropout)。

我很困惑,因为我序列中的不同 RNN 单元似乎被分配了不同的权重。如果我运行以下代码

import tensorflow as tf

seq_length = 3
n_h = 100   # Number of hidden units
n_x = 26    # Size of input layer
n_y = 26    # Size of output layer

inputs = tf.placeholder(tf.float32, [None, seq_length, n_x])

cells = []
for _ in range(seq_length):
    cell = tf.contrib.rnn.BasicRNNCell(n_h)
    cells.append(cell)
multi_rnn_cell = tf.contrib.rnn.MultiRNNCell(cells)

initial_state = tf.placeholder(tf.float32, [None, n_h])

outputs_h, output_final_state = tf.nn.dynamic_rnn(multi_rnn_cell, inputs, dtype=tf.float32)

sess = tf.Session()
sess.run(tf.global_variables_initializer())

print('Trainable variables:')
for v in tf.trainable_variables():
    print(v)

如果我在 python 3 中运行它,我会得到以下输出:

Trainable variables:
<tf.Variable 'rnn/multi_rnn_cell/cell_0/basic_rnn_cell/kernel:0' shape=(126, 100) dtype=float32_ref>
<tf.Variable 'rnn/multi_rnn_cell/cell_0/basic_rnn_cell/bias:0' shape=(100,) dtype=float32_ref>
<tf.Variable 'rnn/multi_rnn_cell/cell_1/basic_rnn_cell/kernel:0' shape=(200, 100) dtype=float32_ref>
<tf.Variable 'rnn/multi_rnn_cell/cell_1/basic_rnn_cell/bias:0' shape=(100,) dtype=float32_ref>
<tf.Variable 'rnn/multi_rnn_cell/cell_2/basic_rnn_cell/kernel:0' shape=(200, 100) dtype=float32_ref>
<tf.Variable 'rnn/multi_rnn_cell/cell_2/basic_rnn_cell/bias:0' shape=(100,) dtype=float32_ref>

首先,这不是我想要的 - RNN 需要在每一层从输入到隐藏和隐藏到隐藏的权重相同!

其次,我真的不明白为什么我得到所有这些单独的变量。如果我查看source code for rnn cells,它看起来BasicRNNCell 应该调用_linear,它应该查找是否存在名称为_WEIGHTS_VARIABLE_NAME(全局设置为"kernel")的变量,如果是,则使用它。我不明白"kernel" 是如何被装饰成"rnn/multi_rnn_cell/cell_0/basic_rnn_cell/kernel:0" 的。

如果有人能解释我做错了什么,我将不胜感激。

【问题讨论】:

    标签: python python-3.x tensorflow neural-network rnn


    【解决方案1】:

    注意区分两个不同的东西:循环神经网络的层数和该 RNN 通过时间反向传播算法展开以处理序列长度的次数。

    在您的代码中:

    • MultiCellRNN 负责创建 3 层 RNN(您正在那里创建 3 层,而 MultiCellRNN 只是一个包装器,以便于处理它们)
    • tf.nn.dynamic_rnn 负责根据您的序列长度多次展开这个三层网络

    【讨论】:

    • 我现在明白了!谢谢你 - 现在你已经指出了这一点,这非常明显。