[color=rgba(0, 0, 0, 0.3)]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区间带来的影响
那么,如果梯度太大,则参数更新的过快。步子迈的太大就会导致训练非常不稳定(训飞了),甚至最后loss变成「Inf」。梯度爆炸的解决方法:(1)gradient clipping如果梯度大于某个阈值了,就对其进行裁剪,让它不要高于那个阈值。(2) 权重正则化。如果发生梯度爆炸,那么权值的范数就会变的非常大。通过限制正则化项的大小,也可以在一定程度上限制梯度爆炸的发生。2. LSTMVanilla RNN最致命的问题就是,它不能够保留很久之前的信息(由于梯度消失)。这是因为它的隐藏状态在不停的被重写:所以,可不可以有一种RNN,能够有独立的记忆(separated memory)呢?2.1 LSTM 基本思想对于任一时间 t,都有三个概念:
- hidden state: n维向量
- cell state: n维向量,存储长期记忆。cell就像一个小小的计算机系统,可以「读、写、擦除」。
- gates: 「n维向量」,每个元素的大小都是0~1之间(之后做element-wise product)。决定哪些信息可以穿过,哪些需要被挡住。
- update gate: 相当于LSTM中的forget gate(擦除旧信息)和input gate(写入新信息)
- reset gate: 判断哪一部分的hidden state是有用的,哪些是无用的。
- LSTM和GRU并没有明显的准确率上的区别
- GRU比起LSTM来,参数更少,运算更快,仅此而已。
- 所以,在实际应用中,我们用LSTM做default方法,如果追求更高的性能,就换成GRU