对RNN中批量大小和时间步骤的疑虑

时间:2017-06-06 04:32:19

标签: recurrent-neural-network

在Tensorflow的RNN教程中:https://www.tensorflow.org/tutorials/recurrent 。它提到了两个参数:批量大小和时间步长。我对这些概念感到困惑。在我看来,RNN引入批次是因为列车序列可能非常长,使得反向传播不能计算那么长(爆炸/消失的梯度)。因此,我们将长列车序列划分为较短的序列,每个序列都是一个小批量,其大小称为批量大小"。我在这儿吗?

关于时间步长,RNN仅由一个细胞(LSTM或GRU细胞或其他细胞)组成,并且该细胞是连续的。我们可以通过展开来理解顺序概念。但是展开顺序单元是一个概念,而不是真实的,这意味着我们不会以展开的方式实现它。假设列车序列是文本语料库。然后我们每次向RNN小区提供一个单词,然后更新权重。那么为什么我们在这里有时间步骤呢?结合我对上述"批量大小"的理解,我更加困惑。我们是用单词还是多个单词(批量大小)来提供单元格?

3 个答案:

答案 0 :(得分:8)

批量大小与一次更新网络权重时要考虑的训练样本数量有关。因此,在前馈网络中,假设您希望根据一次只计算一个单词的渐变来更新网络权重, batch_size = 1。 由于梯度是从单个样本计算的,因此计算上非常便宜。另一方面,这也是非常不稳定的训练。

要了解在培训此类前馈网络期间发生的情况,  我会推荐你​​这个very nice visual example of single_batch versus mini_batch to single_sample training

但是,您想了解 num_steps 变量会发生什么。这与您的batch_size不同。您可能已经注意到,到目前为止,我已经提到了前馈网络。在前馈网络中,输出由网络输入确定,输入 - 输出关系由学习的网络关系映射:

hidden_​​activations(t)= f(输入(t))

输出(t)= g(hidden_​​activations(t))= g(f(输入(t)))

在大小 batch_size 的训练传递之后,计算关于每个网络参数的损失函数的梯度并更新您的权重。

然而,在递归神经网络(RNN)中,您的网络运行方式不同:

hidden_​​activations(t)= f(输入(t),hidden_​​activations(t-1))

输出(t)= g(hidden_​​activations(t))= g(f(输入(t),hidden_​​activations(t-1)))

= g(f(输入(t),f(输入(t-1),hidden_​​activations(t-2))))= g(f(inp(t),f(inp(t-) 1),...,f(inp(t = 0),hidden_​​initial_state))))

正如您可能从命名意义上推测的那样,网络保留了其先前状态的记忆,并且神经元激活现在也依赖于先前的网络状态,并且通过扩展在网络发现自己处于的所有状态大多数RNN使用健忘因子来更加重视最近的网络状态,但这不仅仅是你的问题。

然后,正如你可能推测的那样,如果你必须考虑自网络创建以来所有状态的反向传播,计算损失函数相对于网络参数的梯度在计算上是非常非常昂贵的,那么就有一个整洁的加快计算速度的小技巧:用历史网络状态子集 num_steps 逼近渐变。

如果此概念性讨论不够明确,您还可以查看more mathematical description of the above

答案 1 :(得分:3)

我发现这个图表帮助我可视化数据结构。

Data Structure

从图像中,“批量大小”是您要为该批次训练RNN的序列的示例数。 “每个时间步长的值”是您的输入。 (在我的情况下,我的RNN需要6个输入)最后,你的时间步长是'长度',可以说是你正在训练的序列

我也在学习反复出现的神经网络,以及如何为我的一个项目准备批次(并偶然发现这个线程试图找出它)。

对前馈和经常性网络进行批处理略有不同,当查看不同的论坛时,两者的术语都会被抛出并且会让人感到困惑,因此对其进行可视化非常有帮助。

希望这有帮助。

答案 2 :(得分:1)

  1. RNN"批量大小"是加速计算(因为在并行计算单元中有多个通道);它不是反向传播的小批量。一种证明这一点的简单方法是使用不同的批量大小值,批量大小= 4的RNN单元可能比批量大小= 1快大约4倍,并且它们的损失通常非常接近。

  2. 对于RNN"时间步骤",让我们从rnn.py查看以下代码段。 static_rnn()一次为每个input_调用单元格,BasicRNNCell :: call()实现其前向部分逻辑。在文本预测的情况下,比如批量大小= 8,我们可以认为input_这里是来自大文本语料库中不同句子的8个单词,而不是句子中的8个连续单词。 根据我的经验,我们根据我们希望在"时间"中建模的深度来决定时间步长的价值。或者"顺序依赖"。同样,要使用BasicRNNCell预测文本语料库中的下一个单词,可以使用小时间步骤。另一方面,较大的时间步长可能会遇到梯度爆炸问题。

    def static_rnn(cell,
           inputs,
           initial_state=None,
           dtype=None,
           sequence_length=None,
           scope=None):
    """Creates a recurrent neural network specified by RNNCell `cell`.
       The simplest form of RNN network generated is:
    
       state = cell.zero_state(...)
       outputs = []
       for input_ in inputs:
           output, state = cell(input_, state)
       outputs.append(output)
       return (outputs, state)
    """
    
    class BasicRNNCell(_LayerRNNCell):
    def call(self, inputs, state):
    """Most basic RNN: output = new_state = 
       act(W * input + U * state + B).
    """
        gate_inputs = math_ops.matmul(
            array_ops.concat([inputs, state], 1), self._kernel)
        gate_inputs = nn_ops.bias_add(gate_inputs, self._bias)
        output = self._activation(gate_inputs)
        return output, output
    
  3. 为了可视化这两个参数与数据集和权重的关系,Erik Hallström's post值得一读。从this diagram及以上代码段开始,很明显RNN"批量大小"不会影响重量(wa,wb和b)但是"时间步长"确实。因此,人们可以决定RNN"时间步骤"根据他们的问题和网络模型以及RNN"批量大小"基于计算平台和数据集。