【问题标题】:What's the difference between two implementations of RNN in tensorflow?tensorflow中RNN的两种实现有什么区别?
【发布时间】:2016-05-16 11:35:40
【问题描述】:

我在tensorflow中找到了两种RNN的实现方式。

第一个实现是this(从第 124 行到第 129 行)。它使用循环来定义 RNN 中输入的每一步。

with tf.variable_scope("RNN"):
      for time_step in range(num_steps):
        if time_step > 0: tf.get_variable_scope().reuse_variables()
        (cell_output, state) = cell(inputs[:, time_step, :], state)
        outputs.append(cell_output)
        states.append(state)

第二个实现是this(从第 51 行到第 70 行)。它不使用任何循环来定义RNN中输入的每一步。

def RNN(_X, _istate, _weights, _biases):

    # input shape: (batch_size, n_steps, n_input)
    _X = tf.transpose(_X, [1, 0, 2])  # permute n_steps and batch_size
    # Reshape to prepare input to hidden activation
    _X = tf.reshape(_X, [-1, n_input]) # (n_steps*batch_size, n_input)
    # Linear activation
    _X = tf.matmul(_X, _weights['hidden']) + _biases['hidden']

    # Define a lstm cell with tensorflow
    lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)
    # Split data because rnn cell needs a list of inputs for the RNN inner loop
    _X = tf.split(0, n_steps, _X) # n_steps * (batch_size, n_hidden)

    # Get lstm cell output
    outputs, states = rnn.rnn(lstm_cell, _X, initial_state=_istate)

    # Linear activation
    # Get inner loop last output
    return tf.matmul(outputs[-1], _weights['out']) + _biases['out']



在第一个实现中,我发现输入单元到隐藏单元之间没有权重矩阵,只定义隐藏单元到输出单元之间的权重矩阵(从第 132 行到第 133 行)..

output = tf.reshape(tf.concat(1, outputs), [-1, size])
        softmax_w = tf.get_variable("softmax_w", [size, vocab_size])
        softmax_b = tf.get_variable("softmax_b", [vocab_size])
        logits = tf.matmul(output, softmax_w) + softmax_b

但是在第二个实现中,两个权重矩阵都被定义了(从第 42 行到第 47 行)。

weights = {
    'hidden': tf.Variable(tf.random_normal([n_input, n_hidden])), # Hidden layer weights
    'out': tf.Variable(tf.random_normal([n_hidden, n_classes]))
}
biases = {
    'hidden': tf.Variable(tf.random_normal([n_hidden])),
    'out': tf.Variable(tf.random_normal([n_classes]))
}

不知道为什么?

【问题讨论】:

    标签: python tensorflow deep-learning lstm recurrent-neural-network


    【解决方案1】:

    我注意到的不同之处在于second implementation 中的代码使用了 tf.nn.rnn,它获取每个时间步的输入列表并为每个时间步生成输出列表。

    (Inputs: 一个长度为 T 的输入列表,每个输入都是一个形状的张量 [batch_size, input_size]。)

    因此,如果您在第 62 行检查第二个实现中的代码,输入数据将被整形为 n_steps * (batch_size, n_hidden)

    # Split data because rnn cell needs a list of inputs for the RNN inner loop
    _X = tf.split(0, n_steps, _X) # n_steps * (batch_size, n_hidden)
    

    1st implementation 中,它们循环遍历 n_time_steps 并提供输入并获得相应的输出并存储在输出列表中。

    代码 sn-p 从第 113 行到第 117 行

    outputs = []
        state = self._initial_state
        with tf.variable_scope("RNN"):
          for time_step in range(num_steps):
            if time_step > 0: tf.get_variable_scope().reuse_variables()
            (cell_output, state) = cell(inputs[:, time_step, :], state)
            outputs.append(cell_output)
    

    关于第二个问题:

    如果您仔细注意两种实现中输入被馈送到 RNN 的方式。

    在第一个实现中,输入的形状已经是 batch_size x num_steps(这里 num_steps 是隐藏大小):

    self._input_data = tf.placeholder(tf.int32, [batch_size, num_steps])
    

    而在第二个实现中,初始输入的形状为 (batch_size x n_steps x n_input)。所以需要一个权重矩阵来转化为形状(n_steps x batch_size x hidden_​​size):

        # Input shape: (batch_size, n_steps, n_input)
        _X = tf.transpose(_X, [1, 0, 2])  # Permute n_steps and batch_size
        # Reshape to prepare input to hidden activation
        _X = tf.reshape(_X, [-1, n_input]) # (n_steps*batch_size, n_input)
        # Linear activation
        _X = tf.matmul(_X, _weights['hidden']) + _biases['hidden']
        # Split data because rnn cell needs a list of inputs for the RNN inner loop
        _X = tf.split(0, n_steps, _X) # n_steps * (batch_size, n_hidden)
    

    我希望这会有所帮助...

    【讨论】:

    • 感谢您的回答。还有一个问题,在第二个实现中,我可以在 rnn.rnn() 中使用“sequence_length”参数,但在第一个实现中,我不知道在哪里使用这个参数。你能帮我吗?
    • 第二个实现将“sequence_length”视为“num_steps”的第一个实现。您的问题描述中的链接已失效。你可以用this替换它吗?
    • @Rob Romijnders 在第二种实现中,您可以使用“sequence_length”来决定序列的长度。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-24
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    相关资源
    最近更新 更多