文章目录
课堂提问
- 问: RNN中某些层的激活函数为什么使用tanh?
1. 引入
普通神经网络和循环神经网络的对比如下,他可以是多输入多输出的:
序列化
如果我们输入的数据不是像上图所示的是一个序列的,则我们需要将数据序列化。
例如我们要分类一张手写体图像,我们的输入不是整张图像,而是在图像上采样不同的子区域,然后使用RNN来进行分类:
基本结构
RNN的基本单元如下图右侧所示:
- 其每次接收到当前输入的X,然后将其计算后存储在中间隐藏状态(internal hidden state),并将结果按照某种方式反馈给模型,最后得出输出Y
- 上述过程被形式的描述成左侧公式(注意我们每一步产生输出都是使用相同的W和 )
举个例子,一个简单的RNN单元如下图:其接收输入、更新隐藏状态、产生输出:
将其 计算图 展开我们能得到下图:
可以看到,我们每个时刻的状态不仅与当前输入有关,而且还与之前的输入有关。如果,我们每个时间点都产生一个输出,则有下面的计算图:
同样的,一对多,多对一的过程与上图类似,例如我们在机器翻译中,最常见的做法是:接收不定长的输入,然后编码(encode)到一个隐藏状态,最后再解码(decode)产生多个输出:
则我们在反向传播时,所有时序步都有梯度反向传播到共享权重W
2. 语言建模
RNN常见的应用就是语言建模,例如输入一串字符或者单词,然后预测下一个字符和单词:
在训练的时候,我们每次输入一个字符,然后输出其可能的下一字符,并会进行一系列输入和输出。(因为我们输入的是一个字符串来作为训练)
在 测试的时候,我们会输入一个字符,然后不断地将其输出当成后续的输入:
**Q:**为什么将其输出还要继续输入,而不是直接输出一个得分最高的字母?
**A:**不产生直接输出,而是继续计算概率分布,能得出更多的输出,有时候可能会比较合理。(例如,我们后面将的Image Caption)。
Q: 为什么不将Softmax的输出直接当下一次的输入,而是转换成字符的特征表示?
A:
- 1.和训练阶段所使用的数据不一致;
- 2.我们的词库可能很大,所以我们需要用稀疏的One-hot编码来表示一个字符或者单词,否则Softmax的输出可能会出现很多位置都很接近的情况 。
但是,上述形式还会产生其它问题:
例如,我们在前向传播的时候是按照时序进行的,所以反向传播需要按照时序逆行(因为当前隐藏状态受之前隐藏状态的影响)。但是,当我们的输入序列长度很长的时候,反向传播将会比较麻烦。
所以,一般我们采用子序列截断的方法:即前向传播若干步,然后计算一次损失进行反向传播,依此类推。
这有点类似于我们更新梯度的时候不适用全部样本,而是小批量更新(mini-batch)。
示例代码 min-char-rnn.py
这种预测字符下一个字符的模型还是非常有用的,它能让我们学习到某种格式的文本的内部结构,例如学习C语言的结构,莎士比亚的十四行诗的结构,然后模仿产生类似的文本。
可解释性
Karpathy, Johnson, and Fei-Fei: Visualizing and Understanding Recurrent Networks, ICLR Workshop 2016
一篇论文从RNN模型中的隐藏层状态中抽取固定位置的激活值,然后观察一个序列输入过程中其大小的变化,发现某些位置是有一定语义的,例如:
- 下面这个单元在寻找引号(前引号输入后开始激活,直到后引号为止,输入值变小)
- 再例如判断if语句的神经元:
下面开始介绍RNN在计算机视觉上的应用:
3. 图像描述(Image Caption)
3.1 基础模型结构
如上图,Image Caption的常见情景就是输入一张图片,然后输出描述这张图片的文字,由于输出是不固定的,所以非常适合使用CNN+RNN的结构。即先用CNN提取图像的一个特征表示,在像之前预测字符一样输出到RNN,循环产生输出。
而在实际操作的使用,我们输入一个指示符START
表示我们的输入开始,而且每个隐藏层的状态不仅由上一隐藏层和当前输入单词决定,还要输入我们的 图像特征。
3.2 带有注意力的模型
比之前的模型稍微复杂一点,即在产生描述的时候允许注意力引导模型关注到图像中的关键部分。
其一般做法如下:
Xu et al, “Show, Attend, and Tell: Neural Image Caption Generation with Visual Attention”, ICML 2015
- 表示图像不是由一个一维向量完成的,而是一个向量的序列构成二维网格(L * D)
- 然后每次计算出我们的单词概率分布的同时会产生一个网格的注意力矩阵 ,它指示了我们应该更多的注意的区域(值越大一般注意力越大)。
- 然后下一次输入特征的时候,这个注意力矩阵会加权原始特征矩阵 并和我们的 单词一起输入影响隐藏状态的更新:
- 训练完成后,我们也能看到在产生单词的时候,注意力会在图像中转移
注:软注意力(Soft attention)即将图像特征进行加权组合,就会有一些特征权重大,一些权重小;硬注意力(hard attention)即每一步只选择图像中的一个区域。
4. 视觉问答(Visual Question Answering)
将图像和用自然语言描述的问题作为输入,然后选择(或者输出)我们的答案。
Agrawal et al, “VQA: Visual Question Answering”, ICCV 2015
Zhu et al, “Visual 7W: Grounded Question Answering in Images”, CVPR 2016
其一般做法如下:
Q: 如何将问题向量和图片特征结合起来?
A: 最一般的做法是直接连接起来(即图像特征输入到问题的RNN中作为初始状态),或者在两个向量间作乘法。
5. 多层RNN
之前介绍的RNN只有一种隐藏状态,但是其实RNN还可以使用多层结构,但是一般不超过三四层。
6. 改善的RNN结构
6.1 引入——梯度传播(Gradient Flow)
Bengio et al, “Learning long-term dependencies with gradient descent
is difficult”, IEEE Transactions on Neural Networks, 1994
Pascanu et al, “On the difficulty of training recurrent neural networks”,
ICML 2013
一般RNN单元的前向传播和反向传播过程如下图:
- 可以看到上一层的梯度在传给下一层的时候会乘以一个权重 的转置。而当时序很长的时候,后面的权重流向第一时间点的时候,就会乘以非常多的权重因子。
- 这样,当权重因子某一位置大于1的时候,容易发生梯度爆炸;当小于1的时候,容易发生梯度消失。而发生梯度爆炸的时候,我们可以使用 梯度截断,即让梯度按比例减小;但是发生梯度消失的时候,就需要在网络结构和梯度流向上进行改变。
6.2 LSTM(长短时记忆网络)
Hochreiter and Schmidhuber, “Long Short Term Memory”, Neural Computation
1997
被设计用来缓解 梯度消失 和 梯度爆炸 的问题:
由上图所示,我们的LSTM在每一个时间点都维持两个隐藏状态:
- 一个是单元状态(Cell) ,相当于保留在LSTM内部,外部输出不直接可见;
- 一个是 ,就像个我们之前的基本RNN一样,其和内部的单元状态有关,可以继续产生我们的输出
- 而我们会对输入产生4个门的输出,即:忘记门 ,输入门 ,输出门 。
- 具体的:
- 先由输入计算 4 个门,其中由 激活的门是一个二值门:1表示保留,0表示遗忘;
- 我们先由 输入 和 前一单元状态 决定 当前单元状态;
- 然后由 当前单元状态 和 输出门 决定当前对外可见的 隐藏状态。
为什么gate门使用的是tanh激活函数:
为了生成t时刻的候选记忆
时,范围限制在
,表明
在一个时间步内可能会自增或者自减至多一个单位。但是如果选择 relu,则正向无饱和区域。 同时,tanh的输出是[-1,1],且以0为中心,在0附近的梯度值较大,收敛快。
- 再来看看其中的梯度流动情况:
- 可以看到,在进行反向传播的时候我们的梯度是乘以遗忘门
,而不是
,这又两个好处:(1) 遗忘门是矩阵元素相乘,而不是矩阵相乘;(2)在不同的时间点,乘的遗忘门不一样,而普通的RNN却总是乘以相同的权重
。
- 可以看到,从单元状态(cell)流动的梯度彷佛是一高速公路(highway),可以直接从最后流到最前面。因为 , 梯度在回传的时候最多乘以一个遗忘门 f。(有时候人们在初始化的时候,可能会初始化遗忘门的偏执参数,使得其成为达到某种程度的正数,而不会因为长期小于1而发生梯度消失)。
- 而对于W的梯度,其与 和 均有关,由于我们较好的维持了 的梯度,所以W也能很好的传播。
- 而这种比较高效的梯度流动有点像之前谈到的ResNet,和另一篇论文中谈到的 ,它们除了对输入进行一个激活之外还计算了另一个门函数来权衡其和输入的关系。
6.3 GRU(门控循环单元,Gait Recurrent Unit)
- 其与LSTM类似,都是用加法门来连接信息,用乘法门来处理信息:
- 先通过输入和前一隐藏层得出两个门 ,然后通过计算输入 和 前一隐藏层的 能够得到的信息 ,最后将当前得到的信息 和前一层的隐藏信息 结合起来。其中,信息的结合由门来控制。
总结(summary)
可能我们使用LSTM或者GRU并不是不可思议的,但是我们使用 加法门 和 元素相乘 的方式来控制梯度的流动却是很有效的。