社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

深度学习基础 | RNN家族全面解析

AINLP • 4 年前 • 602 次点击  

首先,请阅读先修知识:深度学习基础 | 从Language Model到RNN

1. 梯度消失和梯度爆炸

1.1 梯度消失

【定义】当很多的层都用特定的激活函数(尤其是sigmoid函数),损失函数的梯度会趋近于0,因此模型更加不容易训练。(As more layers using certain activation functions are added to neural networks, the gradients of the loss function approaches zero, making the network hard to train.)

以最简单的网络结构为例,假如有三个隐藏层,每层的神经元个数都是1,且对应的非线性函数为sigmoid:


每个节点的输出 , 那么

梯度消失的罪魁祸首是sigmoid函数,在sigmoid函数靠近0和1的位置,其导数很小。很多小的值相乘,导致最终的梯度很小。

sigmoid函数和其导数

由于我们初始化的网络权值通常都小于1,因此当层数增多时,小于0的值不断相乘,最后就导致梯度消失的情况出现。同理,当权值过大时,导致大于1的值不断相乘,就会产生梯度爆炸。

如果一个深层网络有很多层,梯度消失导致网络只等价于后面几层的浅层网络的学习,而前面的层不怎么更新了:

深层网络

在RNN中,也会出现梯度消失的问题,比如下面这个例子:

这里应该填"ticket",但是如果梯度非常的小,RNN模型就不能够学习在很久之前出现的词语和现在要预测的词语的关联。也就是说,RNN模型也不能把握长期的信息。

「梯度消失有几种常见的解决方法:」

  • 用下文提到的LSTM/GRU
  • 加上一些skip-connection, 让梯度直接流过而不经过bottleneck。例如resnet:


  • 用Relu、Leaky relu等激活函数
    • ReLu:让激活函数的导数为1
    • LeakyReLu:包含了ReLu的几乎所有优点,同时解决了ReLu中0区间带来的影响

1.2 梯度爆炸

回忆梯度更新的公式:


那么,如果梯度太大,则参数更新的过快。步子迈的太大就会导致训练非常不稳定(训飞了),甚至最后loss变成「Inf」

梯度爆炸的解决方法:

(1)gradient clipping

如果梯度大于某个阈值了,就对其进行裁剪,让它不要高于那个阈值。

(2) 权重正则化。如果发生梯度爆炸,那么权值的范数就会变的非常大。通过限制正则化项的大小,也可以在一定程度上限制梯度爆炸的发生。

2. LSTM

Vanilla RNN最致命的问题就是,它不能够保留很久之前的信息(由于梯度消失)。这是因为它的隐藏状态在不停的被重写:

所以,可不可以有一种RNN,能够有独立的记忆(separated memory)呢?

2.1 LSTM 基本思想

对于任一时间 t,都有三个概念:

  • hidden state: n维向量
  • cell state: n维向量,存储长期记忆。cell就像一个小小的计算机系统,可以「读、写、擦除」
  • gates: 「n维向量」,每个元素的大小都是0~1之间(之后做element-wise product)。决定哪些信息可以穿过,哪些需要被挡住。

「(1)三个gate的计算」

首先,计算三个gate,它们都由上一个hidden state的输出 和当前的input 计算得到。gate是n维向量:

「(2) cell 和 hidden state 的更新」

「cell」存放长期记忆,t时刻的长期记忆 由两部分组成:①旧信息 遗忘一部分;②新信息 写入一部分。

t时刻的「hidden state」 就是选择一部分长期记忆 输出的结果。

LSTM图示:

LSTM图示

图中,每一个绿色方块是一个timestep。和普通的RNN一样,LSTM也是每一步有输入 ,有隐藏状态 作为输出。

2.2 为什么LSTM能够解决梯度消失

LSTM能够让RNN一直保留原来的信息(preserve information over many timesteps)。如果LSTM的遗忘门被设置成1,那么LSTM会一直记住原来每一步的旧信息。相比之下,RNN很难能够学习到一个参数矩阵 能够保留hidden state的全部信息。

所以,可以说LSTM解决梯度消失的主要原因是因为它有「skip-connection」的结构,能够让信息直接流过。而vanilla RNN每一步backprop都要经过 这个bottleneck,导致梯度消失。

3. GRU(gated recurrent unit)

3.1 GRU的基本思想

跟LSTM不同的是,GRU没有cell state,只有hidden state和两个gate。

「(1)gate的计算:」


  • update gate: 相当于LSTM中的forget gate(擦除旧信息)和input gate(写入新信息)
  • reset gate: 判断哪一部分的hidden state是有用的,哪些是无用的。

「(2)hidden state的计算」

3.2 为什么GRU能解决梯度消失?

就像LSTM一样,GRU也能够保持长期记忆(想象一下把update gate设置成0,则以前的信息全部被保留了),也是一种增加skip-connection的方法。

3.3 LSTM vs GRU

  • LSTM和GRU并没有明显的准确率上的区别
  • GRU比起LSTM来,参数更少,运算更快,仅此而已。
  • 所以,在实际应用中,我们用LSTM做default方法,如果追求更高的性能,就换成GRU

4. Bidirectional RNN

4.1 单向RNN的局限性

4.2 双向RNN

把forward RNN和backward RNN的hidden state都拼接在一起,就可以得到包含双向信息的hidden state。

【注意】只有当我们有「整句话」的时候才能用双向RNN。对于language model问题,就不能用双向RNN,因为只有左边的信息。

5. Multi-layer RNNs

多层RNN也叫 stacked RNNs .

5.1 多层RNN结构

下一层的hidden state作为上一层的输入:

5.2 多层RNN的好处

多层RNN可以让RNN网络得到词语序列更加复杂的表示(more complex representations)

  • 下面的RNN层可以得到低阶特征(lower-level features)
  • 上面的RNN层可以得到高阶特征(higher-level features)

5.3 多层RNN的应用

【注意】如果multi-layer RNN深度很大,最好用一些skip connection

本文参考资料

[1]

cs224n-2019-lecture07: https://web.stanford.edu/class/cs224n/slides/cs224n-2019-lecture07-fancy-rnn.pdf


- END -


进技术交流群请添加AINLP小助手微信(id: ainlper)
请备注具体方向+所用到的相关技术点

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLPer(id:ainlper),备注工作/研究方向+加群目的。


阅读至此了,分享、点赞、在看三选一吧🙏

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/121794