在Tensorflow的RNN教程中:https://www.tensorflow.org/tutorials/recurrent . 它提到了两个参数:批量大小和时间步长 . 我对这些概念感到困惑 . 在我看来,RNN引入批次是因为列车序列可能非常长,使得反向传播不能计算那么长(爆炸/消失的梯度) . 因此,我们将长列车序列划分为较短的序列,每个序列都是一个小批量,其大小称为"batch size" . 我在这儿吗?
关于时间步长,RNN仅由细胞(LSTM或GRU细胞或其他细胞)组成,并且该细胞是连续的 . 我们可以通过展开来理解顺序概念 . 但是展开顺序单元是一个概念,而不是真实的,这意味着我们不会以展开的方式实现它 . 假设列车序列是文本语料库 . 然后我们每次向RNN小区提供一个单词,然后更新权重 . 那么为什么我们在这里有时间步骤呢?结合我对上述“批量大小”的理解,我更加困惑 . 我们是用单词还是多个单词(批量大小)来提供单元格?
3 回答
批量大小与一次更新网络权重时要考虑的训练样本数量有关 . 因此,在前馈网络中,假设您希望基于从一个单词一次计算渐变来更新网络权重,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))
output(t) = g(hidden_activations(t)) = g(f(input(t)))
在大小batch_size的训练传递之后,计算关于每个网络参数的损失函数的梯度并更新您的权重 .
然而,在递归神经网络(RNN)中,您的网络运行方式有点不同:
hidden_activations(t) = f(input(t), hidden_activations(t-1))
output(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 .
我发现这个图帮助我可视化数据结构 .
从图像中,“批量大小”是您要为该批次训练RNN的序列的示例数 . “每时间步长的值”是您的输入 . (在我的情况下,我的RNN需要6个输入)最后,你的时间步长是'长度',可以说是你正在训练的序列
我也在学习反复出现的神经网络,以及如何为我的一个项目准备批次(并偶然发现这个线程试图解决它) .
对前馈和经常性网络进行批处理略有不同,当查看不同的论坛时,两者的术语都会被抛出并且会让人感到困惑,因此将其可视化非常有用 .
希望这可以帮助 .
RNN的“批量大小”是为了加速计算(因为并行计算单元中有多个通道);它不是反向传播的小批量 . 一种证明这一点的简单方法是使用不同的批量大小值,批量大小= 4的RNN单元可能比批量大小= 1快大约4倍,并且它们的损失通常非常接近 .
至于RNN 's 875356 , let',请查看rnn.py的以下代码片段 . static_rnn()一次调用每个input_的单元格,BasicRNNCell :: call()实现其前向部分逻辑 . 在文本预测的情况下,比如批量大小= 8,我们可以认为input_这里是来自大文本语料库中不同句子的8个单词,而不是句子中的8个连续单词 . 根据我的经验,我们根据我们想要在"time"或"sequential dependency"中建模的深度来决定时间步长的 Value . 同样,要使用BasicRNNCell预测文本语料库中的下一个单词,可以使用小时间步骤 . 另一方面,较大的时间步长可能会遇到梯度爆炸问题 .