什么是RNN?
1 前言
说起深度学习,大家首先会想到几个经典的模型,比如CNN,RNN等,上一篇博客:深度学习 | CNN原理及Keras实现 中笔者已经将CNN的原理以及实现大概介绍了下,本篇博客咱们就聚焦下一个常见模型:循环神经网络RNN(Recurrent Neural Network)!其中Recurrent表示反复的,一再发生的!
2 RNN的应用场景
上一篇博客我们知道CNN主要应用在图像领域,那么RNN呢?
- 为语言模型来建模。即利用RNN来预测一句话被扣掉一部分内容是啥?利用RNN来判断一段语言讲的是啥,输出成文字!
- 语言模型就是这样的东西:给定一个一句话前面的部分,预测接下来最有可能的一个词是什么。
- 语音转文本。
- 图像到文本的识别。
- 普通的一句话后面应该出现什么话,比如下面的例子:
我昨天上学迟到了,老师批评了____。 [基本循环神经网络]
我的手机坏了,我打算____一部新手机。 [双向循环神经网络]
- 情感分析。输入任意,输出固定。利用RNN来预测一句话表明的情感态度是正向还是负向的?
- 图像标注。输入固定,输出任意。利用RNN来生成对应一个图片的文本描述。
- 语言翻译。输入和输出是不同长度的。即利用RNN来对输入的文本进行翻译成另一种语言。
小结:
- 通过上述分析可以看到RNN的输入内容之间是有序的,比如文字,打乱顺序很可能就会是截然相反的含义。即RNN主要用于序列数据的建模!无论是文本还是语音都是有序的!
- 序列的信息决定事件本身。如果我们试图使用这类数据得到有用的输出,就需要一个这样的网络:能够访问一些关于数据的先前知识(prior knowledge),以便完全理解这些数据。因此,循环神经网络(RNN)粉墨登场。
3 RNN的原理
了解了RNN的应用场景之后,我们就需要来看看RNN究竟是个什么鬼?原理是啥?
3.1 前向计算过程
上一个经典的图:
上述的过程就代表了RNN的实现原理,要输出一个结果究竟要经历哪几步呢?和普通神经网络有什么区别呢?考虑
O
t
O_t
Ot的输出!
- 首先,计算 x t U x_tU xtU 即输入乘以权重
- 其次,计算 s t − 1 s_{t-1} st−1乘以 W W W,即 s t − 1 W s_{t-1}W st−1W。含义为上一层神经元存储的结果乘以权重
- 然后,将上述两步结果相加再放入激活函数中! f ( s t − 1 W + x t U ) f(s_{t-1}W+x_tU) f(st−1W+xtU) , f f f一般为relu激活函数等
- 最后,将上述结果乘以 V V V再套一层输出层的激活函数即可!
用公式表示就是:
所以通过上述计算过程我们就可以看出,RNN和之前普通的神经网络区别有两点:
- 记忆功能。每个输入对应计算输出的时候还考虑了上一个神经元的缓存结果!至于为什么要有记忆功能在上面的应用场景中就能体会到了,如果给出完整的一句话再判断输出和只给前面的一个词汇判断其输出哪个更加准确?毫无疑问,拥有的记忆功能更强(即获得的句子越长)效果越好!
- 权重共享。输入层权重 U U U,输出层权重 V V V,多层之间传递权重 W W W共享!也即权重都为一致的!
另外关于前向计算的Excel版本实现可以参考博客:https://zhuanlan.zhihu.com/p/32755043
3.2 反向传播过程
上面的过程展示的仅仅是前向计算的过程,那反向传播捏?如何反向传递误差更新权重?
循环神经网络的训练算法:BPTT,大概步骤为:
其中,误差通过交叉熵损失来计算。
至于具体数学是如何实现的,暂时不多讲了,详情见:https://zybuluo.com/hanbingtao/note/541458
4 RNN的变种-LSTM
首先就要回答一个问题了,为什么要有RNN的变种LSTM?为什么要变?是因为简单的RNN有问题么?对!那有什么问题呢?梯度消失和梯度爆炸!
4.1 什么叫梯度消失和梯度爆炸?
- 应用链式规则求导反向传播的时候,如果任何一个梯度接近0,所有的梯度都会成指数倍的迅速变成零。这样将不再有助于网络学习任何东西。这就是所谓的消失梯度问题。
- 梯度爆炸就是由于单个或多个梯度值变得非常高,梯度变得非常大。
- 消失梯度问题与爆炸梯度问题相比,对网络更有威胁性。
如何解决?
- 梯度爆炸比较容易解决。通过一个预定义的阈值可以很容易地解决梯度爆炸问题。
- 梯度消失的问题就可以通过LSTM来进行解决!
那么问题来了,LSTM又是个什么鬼呢?
4.2 什么叫LSTM?
LSTM英文全名为:Long Short-term Memory。关于它的原理,台大李宏毅老师讲的特别好,和大家分享一下:
1、LSTM的参数
首先LSTM输入的参数有4个,输出有1个
输入:
- z z z:输入层的权重
- z i z_i zi:决定Iuput Gate是否open的神经元计算权重
- z f z_f zf:决定Forget Gate是否open的神经元计算权重
- z 0 z_0 z0:决定Output Gate是否open的神经元计算权重
输出:
- a的值
2、涉及3个门的神经元激活函数一般为sigmoid函数!为什么呢?
- 因为sigmoid取值范围为0-1,而涉及到门的运算都是相乘,所以如果为0表示关闭门,为1表示打开门。
- 实际的含义则是决定哪些之前的信息和状态需要保留/记住,而哪些要被抹去。
- 原则:因记忆能力有限,记住重要的,忘记无关紧要的。
3、实际的例子展示LSTM是如何run的?
分两种情况展示:最终Output Gate关闭和打开的情形
Output Gate关闭:
Output Gate打开:
4、LSTM究竟好在哪?为什么能解决梯度消失的问题?
RNN和LSTM对待memory的时候的方式不同:
- RNN:memory和权重是相乘的关系。
- LSTM:memory和权重是叠加的关系。所以LSTM的梯度永远不会消失除非Forget Gate门关闭了,但一般情况下都尽量保持让Forget Gate打开(加比较大的bias)!而且LSTM的第一版本中都没有Forget Gate!
LSTM的变种还有GRU,参数更少,所以更新参数更加robust!
后面再扩充!
4.3 LSTM相关面试题?
1、LSTM结构推导,为什么比RNN好?
因为LSTM可以有效解决梯度消失的问题,具体解释见上。
2、GRU是什么?GRU对LSTM做了哪些改动?
- GRU是Gated Recurrent Units,是循环神经网络的一种。
- GRU只有两个门(update和reset),LSTM有三个门(forget,input,output)
- GRU直接将hidden state 传给下一个单元,而LSTM用memory cell 把hidden state 包装起来。
3、LSTM神经网络输入输出究竟是怎样的?
- 输入:一开始确定四个参数,输入x
- 输出:预测的结果y
4、为什么LSTM模型中既存在sigmoid又存在tanh两种激活函数,而不是选择统一一种sigmoid或者tanh?这样做的目的是什么?
- sigmoid 用在了各种gate上,产生0~1之间的值,这个一般只有sigmoid最直接了,相当于要么是1则记住,要么是0则忘掉。
- tanh 用在了状态和输出上,是对数据的处理,这个用其他激活函数也可以。
5、如何修复梯度爆炸问题?
- 重新设计网络模型。通过重新设计层数更少的网络来解决
- 使用 ReLU 激活函数。
- 使用长短期记忆网络LSTM
- 使用梯度截断(Gradient Clipping)。即在训练过程中检查和限制梯度的大小。这就是梯度截断。
- 使用权重正则化。检查网络权重的大小,并惩罚产生较大权重值的损失函数
5 keras实现RNN
待补充