关于 RNN 中的批大小和时间步长的疑问

Posted

技术标签:

【中文标题】关于 RNN 中的批大小和时间步长的疑问【英文标题】:doubts regarding batch size and time steps in RNN 【发布时间】:2017-11-06 23:10:03 【问题描述】:

在TensorFlow的RNN教程中:https://www.tensorflow.org/tutorials/recurrent .它提到了两个参数:批量大小和时间步长。我对这些概念感到困惑。在我看来,RNN 引入批处理是因为训练序列可能很长,以至于反向传播无法计算那么长(梯度爆炸/消失)。所以我们将长的待训练序列划分为更短的序列,每个序列都是一个小批量,其大小称为“批量大小”。我在吗?

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

【问题讨论】:

【参考方案1】:

批量大小与每次更新网络权重时要考虑的训练样本量有关。因此,在前馈网络中,假设您想根据一次计算一个单词的梯度来更新网络权重,您的 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(input(t))

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

在大小为 batch_size 的训练过程之后,将计算您的损失函数相对于每个网络参数的梯度并更新您的权重。

但是,在循环神经网络 (RNN) 中,您的网络功能略有不同:

hidden_​​activations(t) = f(input(t), hidden_​​activations(t-1))

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

=g(f(input(t), f(input(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。

【讨论】:

我们可以计算所有状态的子集,而不是计算所有状态,这意味着我们只需要最后的“num_steps”个记忆。为了实现,每个内存都是一个数组。所以在这种情况下,我们需要一个“num_steps”x“每个内存大小”的矩阵。我的理解对吗? 我仍然很困惑每个批次中的训练示例究竟是如何工作的。假设我们一批有 5 个训练样例。这是否意味着每个训练样本都会被输入一个隐藏的神经元单元,所以我们在 RNN 中总共有 5 个单元? 假设您的数据大小为 100,批量大小为 5,每个 epoch 有 20 次网络参数更新。它首先传播前 5 个训练示例,根据您提供的优化方法更新其参数,然后采用接下来的 5 个,直到完全传递数据。 num_steps 决定了您展开的单元格数量,从而决定了梯度计算中使用的数据量。由于每个单元/层共享参数,这不会导致要优化的参数增加,但它支持上下文学习,这就是为什么您首先需要 RNN。 评论变得太长,所以继续这里:假设您希望能够在文本语料库中捕获诸如“云在......”之类的上下文关系。我们都知道网络输出可能是什么,无论其输入如何。为此,您需要 num_steps >=4 让网络学习这些依赖项。 Batch_size 与依赖无关,它只是确定每个训练批次使用的数据量。批次越大,计算的梯度对整个数据集的代表性越强,但内存需求越大【参考方案2】:

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

从图片中,“批量大小”是您想要为该批次训练 RNN 的序列的示例数。 “每个时间步的值”是您的输入。 (在我的例子中,我的 RNN 需要 6 个输入)最后,您的时间步长就是您正在训练的序列的“长度”

我还在学习循环神经网络以及如何为我的一个项目准备批次(并且偶然发现了这个线程试图弄清楚)。

前馈网络和循环网络的批处理略有不同,在查看不同的论坛时,两者的术语都会被抛出并且非常混乱,因此将其可视化非常有帮助。

希望这会有所帮助。

【讨论】:

我为您嵌入了图像。您应该尽力总结图像如何回答 OP 的问题。仅链接的答案在堆栈溢出时被视为低质量。 在您进行编辑时,我嵌入图像的编辑似乎被拒绝了。如果你愿意,我可以再做一次。 @JoeyHarwood 请。谢谢【参考方案3】:

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

    李>

    关于RNN的“时间步长”,我们看一下rnn.py下面的代码sn-ps。 static_rnn() 一次调用每个 input_ 的单元,BasicRNNCell::call() 实现其前向部分逻辑。在文本预测的情况下,比如batch size=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
    

    为了可视化这两个参数与数据集和权重的关系,Erik Hallström's post 值得一读。从this diagram 及以上代码 sn-ps 来看,显然 RNN 的“批量大小”不会影响权重(wa、wb 和 b),但“时间步长”会影响。所以,可以根据问题和网络模型来决定RNN的“时间步长”,根据计算平台和数据集来决定RNN的“batch size”。

【讨论】:

以上是关于关于 RNN 中的批大小和时间步长的疑问的主要内容,如果未能解决你的问题,请参考以下文章

关于Addressable打包大小的疑问

Python中偶尔遇到的细节疑问:去除列名特殊字符标准差出现nan切片索引可超出范围range步长

关于 Angular 2 中的事件发出的一些疑问。这个例子究竟是如何工作的?

输入数据形状和大小,RNN Keras,回归

关于HashMap中的扰动函数的疑问

LSTM RNN 同时预测多个时间步长和多个特征