文章目录
- 1 RNN
- 1.1 RNN的前向传播
- 1.2 RNN的后向传播
- 1.3 RNN的类型
- 2 GRU
- 3 LSTM
- 3.1 带窥视孔的LSTM
- 3.2 LSTM的反向传播
- 3.1 how to train LSTM
- lost function
- Training
- Error Surface
- 解决方法
1 RNN
这个循环神经网络的一个缺点就是它只使用了这个序列中之前的信息来做出预测,无法用到之后的信息,可用双向循环神经网络(BRNN)来解决这个问题。
循环神经网络用的激活函数经常是tanh,不过有时候也会用ReLU,但是tanh是更通常的选择,我们有其他方法来避免梯度消失问题,我们将在之后进行讲述。选用哪个激活函数是取决于你的输出,如果它是一个二分问题,那么我猜你会用sigmoid函数作为激活函数,如果是类别分类问题的话,那么可以选用softmax作为激活函数。不过这里激活函数的类型取决于你有什么样类型的输出,对于命名实体识别来说只可能是0或者1,那我猜这里第二个激活函数可以是sigmoid激活函数。
1.1 RNN的前向传播
,它是一个零向量。接着就是前向传播过程,先计算激活值,然后再计算。:
然后用和一起算出和等等,然后从左到右完成前向传播。
简化上面的公式:
若的shape为(100,1),x的shape是(10000,1),则的shape为(100,100),的shape为(100,10000),是将矩阵和矩阵水平并列放置,因此shape为(100,10100)。
RNN前向传播示意图:
1.2 RNN的后向传播
蓝色箭头所指方向为前向传播,红色箭头所指方向为反向传播。
为了计算反向传播,先定义一个损失函数,在单个位置上或者说某个时间步t上某个单词的预测值的损失函数:
整个序列的损失函数L:
RNN反向传播示意图:
1.3 RNN的类型
1 many-to-many
输入和输出长度不同:下图编号5,如机器翻译,首先读入这个句子,读完之后,这个网络就会输出翻译结果。
输入和输出长度相同:下图编号4
2 many-to-one
多个输入,一个输出,如一个电影的评论,“These is nothing to like in this movie.”(“这部电影没什么还看的。”),所以就是一个序列,而输出可能是从1到5的一个数字。神经网络结构见下图编号3
3 one-to-one
下图编号1
4 one-to-many
下图编号2,如给定一个主题,输出一篇文章
2 GRU
RNN也存在梯度消失问题,GRU可以有效地解决梯度消失的问题
在GRU中,c代表记忆细胞的值,a代表输出的激活值,在GRU中两者相等,但在LSTM中两者不相等。
3 LSTM
3.1 带窥视孔的LSTM
和,有时候也可以偷窥一下的值(上图编号13所示),这叫做“窥视孔连接”(peephole connection)
3.2 LSTM的反向传播
3.1 how to train LSTM
lost function
我们需要把model的输出与映射到slot的reference vector求交叉熵,比如“Taipei”对应到的是“dest”这个slot,则reference vector在“dest”位置上值为1,其余维度值为0
RNN的output和reference vector的cross entropy之和就是损失函数,也是要minimize的对象
需要注意的是,word要依次输入model,比如“arrive”必须要在“Taipei”前输入,不能打乱语序
Training
有了损失函数后,训练其实也是用梯度下降法,为了计算方便,这里采取了反向传播(Backpropagation)的进阶版,Backpropagation through time,简称BPTT算法
BPTT算法与BP算法非常类似,只是多了一些时间维度上的信息。
Error Surface
下图中,z轴代表loss,x轴和y轴代表两个参数w1和w2,可以看到loss在某些地方非常平坦,在某些地方又非常的陡峭
如果此时你的训练过程类似下图中从下往上的橙色的点,它先经过一块平坦的区域,又由于参数的细微变化跳上了悬崖,这就会导致loss上下抖动得非常剧烈
如果你的运气特别不好,一脚踩在悬崖上,由于之前一直处于平坦区域,gradient很小,你会把参数更新的步长(learning rate)调的比较大,而踩到悬崖上导致gradient突然变得很大,这会导致参数一下子被更新了一个大步伐,导致整个就飞出去了,这就是学习曲线突然跳到无穷大的原因
想要解决这个问题,就要采用Clipping方法,当gradient即将大于某个threshold的时候,就让它停止增长,比如当gradient大于15的时候就直接让它等于15
为什么RNN会有这种奇特的特性?
在w=1周围gradient几乎是突变的,这让我们很难去调整learning rate。
因此我们可以解释,RNN训练困难,是由于它把同样的操作在不断的时间转换中重复使用。
从memory接到neuron输入的参数w,在不同的时间点被反复使用,w的变化有时候可能对RNN的输出没有影响,而一旦产生影响,经过长时间的不断累积,该影响就会被放得无限大,因此RNN经常会遇到这两个问题:
- 梯度消失(gradient vanishing),一直在梯度平缓的地方停滞不前
- 梯度爆炸(gradient explode),梯度的更新步伐迈得太大导致直接飞出有效区间
解决方法
1、LSTM
LSTM就是最广泛使用的技巧,它会把error surface上那些比较平坦的地方拿掉,从而解决梯度消失(gradient vanishing)的问题,但它无法处理梯度崎岖的部分,因而也就无法解决梯度爆炸的问题(gradient explode)。但由于做LSTM的时候,大部分地方的梯度变化都很剧烈,因此训练时可以放心地把learning rate设的小一些。
为什么LSTM能够解决梯度消失的问题?
RNN和LSTM对memory的处理其实是不一样的:
- 在RNN中,每个新的时间点,memory里的旧值都会被新值所覆盖
- 在LSTM中,每个新的时间点,memory里的值会乘上与新值相加
对RNN来说,w对memory的影响每次都会被清除,而对LSTM来说,除非forget gate被打开,否则w对memory的影响就不会被清除,而是一直累加保留,因此它不会有梯度消失的问题。
2、GRU (Gated Recurrent Unit)
它的基本精神是旧的不去,新的不来,GRU会把input gate和forget gate连起来,当forget gate把memory里的值清空时,input gate才会打开,再放入新的值