【问题标题】:Isn't Tensorflow RNN PTB tutorial test measure and state reset wrong?Tensorflow RNN PTB 教程测试测量和状态重置是不是错了?
【发布时间】:2017-05-09 01:39:00
【问题描述】:

我有两个关于 Tensorflow PTB RNN 教程代码 ptb_word_lm.py 的问题。下面的代码块来自代码。

  1. 是否可以为每个批次重置状态?

    self._initial_state = cell.zero_state(batch_size, data_type())
    
    with tf.device("/cpu:0"):
      embedding = tf.get_variable(
          "embedding", [vocab_size, size], dtype=data_type())
      inputs = tf.nn.embedding_lookup(embedding, input_.input_data)
    
    if is_training and config.keep_prob < 1:
      inputs = tf.nn.dropout(inputs, config.keep_prob)
    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)
    

    在第 133 行,我们将初始状态设置为零。然后,第 153 行,我们使用零状态作为 rnn 步骤的起始状态。这意味着批次的每个起始状态都设置为零。我相信如果我们想应用 BPTT(通过时间的反向传播),我们应该在先前数据完成的步骤中进行外部(非零)状态输入,例如有状态的 RNN(在 Keras 中)。

    我发现将起始状态重置为零实际上可行。但是有什么理论背景(或论文)可以解释为什么会这样吗?

  2. 这样测量测试困惑度可以吗?

    eval_config = get_config()
    eval_config.batch_size = 1
    eval_config.num_steps = 1
    

    与上一个问题有关...模型将每个批次的初始状态固定为零。但是,在第 337 ~ 338 行,我们将批量大小设置为 1,将步骤数设置为 1 用于测试配置。然后,对于测试数据,我们将每次放入单个数据并在没有上下文的情况下预测下一个数据(!),因为每个批次的状态都为零(只有一个时间步长)。

    这是测试数据的正确度量吗?是否所有其他语言模型论文都将测试困惑度测量为在没有上下文的情况下预测下一个单词?

我运行了这段代码并得到了与代码所述以及原始论文所述相似的结果。如果这段代码是错误的,我希望不是,你知道如何复制论文结果吗?如果我修改问题,也许我可以提出拉取请求。

【问题讨论】:

    标签: tensorflow recurrent-neural-network perplexity


    【解决方案1】:

    Re (1),代码是(cell_output, state) = cell(inputs[:, time_step, :], state)。这会将下一个时间步的状态分配为该时间步的输出状态。

    当你开始一个新的批处理时,你应该独立于你迄今为止所做的计算(注意批处理之间的区别,它们是完全不同的例子,而时间步长在相同的序列中)。

    Re (2),大部分时间都使用上下文。

    【讨论】:

    • 你能给我更多的细节吗?我认为代码在 RNN 循环和运行循环之前将状态初始化为零 num_steps 次。在循环期间,状态被更新为下一个。但循环的初始状态始终为零。所以,我想在 (2) 中问的是,如果我们使用 num_step = 1,那么它将始终从零开始并仅以一步结束。因此,例如,“我有一只猫”将被计算为(零初始化 - 获得“I”的成本),(零初始化 - 获得“拥有”的成本),(零初始化,...)我相信至少对于测试集不应初始化状态...
    • 是的,num_steps 等于 1 将始终在每一步之后将状态重新初始化为 0。这不等同于使用完整模型。