RNN: (Recurrent Neural Network)循环神经网络
摘要:本节课主要学习了什么是RNN、LSTM,以及如何对RNN进行训练。
目录
举例说明什么是RNN?
1.智慧订票系统的语音识别
Slot filling:槽填充
智慧订票系统:听到用户说:I would like arrive Taipei on November 2nd
可以识别出:目的地是台北,旅行时间是11月2日
如果用前馈神经网络来解决这个问题:
2.如何将word用向量表示?
1-of-n encoding
将输入单词作为vector ,输出是将输入的单词进行分类。
beyond 1-of-n encoding
如果遇到没见过的词汇,那就需要增加一个维度,将没讲过的词汇归到other里面,
也可以用单词字母来表示
Apple,对应到app、ppl、ple 的维度都是1,其他都是0
但是这样出现一个问题:
计算机没办法区分arrive和leave,也就是没办法将Taipei在适当的时候分类到出发地和目的地。这样就希望神经网络是有记忆力的,能够认识arrive和leave,这样,同样输入taipei,可以分别输出目的地和出发地。
3.RNN的原理
每当中间层输出是,都会被存储起来,当下次输入x1,x2时,中间层的神经元不会只是考虑输入,也会考虑存储起来的值a1,a2。
举例:
所有的weight=1,存储的初始值为0,函数为线性
输入(1,1),中间层输出(2,2),输出就是(4,4)这时存储起来的值是(2,2)
继续输入(1,1),这时中间层输出是(6,6)(2+2+2+1),输出就是(12,12),这时存储起来的值就是(6,6)
同样时输入1,1,两次的输出结果不一样,因为存储在中间的数是不一样的。
在rnn中会考虑输入的次序。
同一个神经网络按输入次序的图示。再第二个输入的中间层,就考虑了arrive和taipei的共同影响,这样就可以将taipei分类到更合适的地方。如果taipei前面的输入是leave,将leave存放起来,虽然同样都是输入taipei,但是因为存放的内容不同,输出的结果也是不同的。
4.其他几种RNN类型
这个讲的是Elman network 还有Jordan network
Jordan network是将前一个输出的结果存储下来,当下一输入到中间层时一同考虑。Jordan network通常表现会更好一些,因为很清楚存放的输出是前一个的输出。
Bidirection RNN:方向也可以是反过来的rnn
将正向和反向同列层的输出都存放在一起,这样的好处是network在产生输出时,看的范围更广。只有单方向是yt只看到x1到xt的输入,但是采用双方向时,可以看到x1到xt和从句尾到xt的输入(结合上下文)
Long short-term memory (LSTM)
比较长的短时记忆
1.什么是LSTM?
对存储空间(也叫memory cell)加上一个输入阀门和输出阀门,开启输入阀门,输入才会被存放到存储空间。开启输出阀门,才可以读取存储空间的值。
另外还有一个forget阀门,开启forget阀门,代表不改变存储空间里的内容,关闭forget阀门,代表遗忘掉存储空间的内容。(其实更应该叫记忆阀门)
这三个阀门都是通过神经网络来自己学习什么时候开启,什么时候关闭。
这样的神经元有四个输入(常规的输入,控制三个阀门的三个输入)和一个输出(常规的输出)
已经存储在存储空间的值为c,输入为z,输出为a,输入阀门的输入是zi,输出阀门的输入为zo,forget 阀门的输入为zf,通常选取的激活函数都是sigmoid函数,
对于输入和输出阀门,取0到1之间,0代表阀门开启程度越小,1代表越大。
对于forget gate,0表示遗忘程度越高,受c的影响小,1表示遗忘程度越低,也就是受c的影响大。
新存储的值C、=g(z)*f(zi)+c*f(zf)
输出的值a=h(C、)*f(zo)
当x2为1时,将x1加入到memory中,当x2为-1时,将memory清空
当x3为1时,输出memory中的数字。
输入 | Input | Input gate | Forget gate | Memory | Output gate | Output |
3 1 0 | 3 | 1 | 1 | 3 | 0 | 0 |
4 1 0 | 4 | 1 | 1 | 7 | 0 | 0 |
2 0 0 | 2 | 0 | 1 | 7 | 0 | 0 |
1 0 1 | 1 | 0 | 1 | 7 | 1 | 7 |
3 1 0 | 3 | 0 | 0 | 0 | 0 | 0 |
2.LSTM与神经网络的联系
上述例子看起来并不像神经网络,那么怎么把这两种联系起来呢?
常规的神经网络
LSTM:通过对一个输入加上不同的weight,来对四个输入进行影响
在原来的神经元中,一个输入对应一个输出,
在LSTM中,一个输出乘以四个不同的weight,变成四个输入,对应一个输出。
所以LSTM需要的参数是一般的神经网络的4倍
3.LSTM的实现流程
这里有一排LSTM,将每一个LSTM中memory存放的值取出来,连到一起变成ct-1向量
时间点t,输入一个向量xt,乘以一个矩阵之后的到向量z,z的每个维度代表操控每一个LSTM的输入,所以z的维度等于LSTM的个数。
然后xt乘以另一个矩阵得到zi,zi的每个维度代表操控每一个LSTM的input gate的输入;
对于forget gate 和output gate也是一样。
Zi通过sigmoid方程与z相乘,加上zf通过sigmoid的值,也就是C、,把C、通过sigmoid方程与zo通过sigmoid的值相乘,得到的就是输出。
实际上,真正的LSTM会把yt和memory中的值接到下一个时间点的输入上。
(好复杂,还不了解为什么要把后两个参数也加进来)
Keras支持LSTM 、GRU和简单的LSTM。
如何来对rnn做训练
1.如何定义loss函数
将句子中的每个单词依次当做x1,x2…xi 输入到rnn中,得到的yi与预期的reference vector做交叉熵,从1到i的交叉熵之和就是loss函数。
2.训练方法:梯度下降
Backpropagation through time (BPTT):考虑了时间的因素。
3.rnn的训练时出现的问题
通常情况下,随着训练的次数的增加,总的loss应该是越来越低的。但是在rnn的训练中,有时候反应的结果却是绿线。
发生这种情况的原因:
W1,w2代表两个参数,从图上可以发现,有的地方非常平坦,有的地方非常陡峭。
中间的橙色点代表初始点,经过两次更新,发生了loss函数突然增大
另一种情况就是经过两次更新,,恰好到悬崖边上,此时梯度很大,由于之前的梯度很小,使用比较大的学习率。现在梯度突然变大,而学习率没有及时调整,导致参数更新变了很多,飞出去了。
采用clipping:对梯度加上一个最大的限制x,超过的x梯度,就会被视作x。这样通过限制就可以使梯度不会过大。
4.为什么rnn的图像会出现这种情况
原因是因为有时间序列,就是同一个weight,在不同时间点被反复使用。这样只要weight改动一点点,对整个输出结果的影响都会变得很大,也就是total loss反复跳跃。
LSTM可以处理梯度消失问题:把比较平坦的地方拿掉,可以放心的把学习率设计的小一点。(对于梯度爆炸没什么用,total loss的变换还是很剧烈的)
原理:在rnn中,memory的改变方法是完全洗掉,每次更新,对之前的memory的值进行格式化。
在LSTM中,memory的改变方法是对原有的memory乘上一个zf,再加上输入的值,得到新的memory的值。也就是说一旦weight影响到memory的值,那么这个影响是一直存在的。(除非forget gate要关闭,通常情况下forget gate是不会关闭的)
(和momentum算法相似,每次更新新的移动方向时,看起来考虑的只是上一次移动方向的影响,实际上这个影响是一直存在的,只不过程度越来越小。)
Gated recurrent unit(GRU):简单一点的LSTM,需要的参数比较少,只有两个gate,将input gate和forget gate联动起来,当input gate开启时,forget gate就会自动关闭,就会洗掉memory中的值,也就是只有当想清除memory的值时,才开启input gate。
5.一些其他的rnn结构
总结:
RNN本质上是有记忆的神经网络,LSTM则是在RNN的基础上,对内部结构进行复杂化,可以保证更长时间的记忆时效。