李宏毅机器学习课程笔记9:Recurrent Neural Network

台湾大学李宏毅老师的机器学习课程是一份非常好的ML/DL入门资料,李宏毅老师将课程录像上传到了YouTube,地址:NTUEE ML 2016 。
这篇文章是学习本课程第25-26课所做的笔记和自己的理解。


Lecture 25,26: Recurrent Neural Network

RNN的基本概念与SimpleRNN

以订票系统中的Slot Filling为例,我们希望订票系统听到用户说:”I would like to arrive Taipei on November 2nd.” 时做好Slot Filling, 即识别出语音中 Taipei 属于 Destination 这个slot, November 2nd 属于 Time of arrival 这个slot, 而其它词汇不属于任何slot。
能否用Feedforward network解决这一问题呢?
先说结论:不能。
为什么呢?我们把word变成vector(e.g. 1-of-N encoding, word hashing)作为Feedforward network的输入,输出是该词汇属于slots(Destination, Time of arrival) 的概率。但是这样是不够的,因为在slot filling的任务中,neural network是需要有记忆的,要记住在Taipei之前出现过的arrive或leave。这种有记忆的neural network叫做Recurrent Neural Network.
李宏毅机器学习课程笔记9:Recurrent Neural Network_第1张图片
在RNN中,hidden layer的neuron产生的output会被存到memory中,对之后的input, hidden layer的neuron不只考虑input, 还会考虑存在memory中的值。memory在没有任何input时需要初始值。
RNN会考虑input sequence的order,改变input sequence的order,output会随之改变。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第2张图片

李宏毅机器学习课程笔记9:Recurrent Neural Network_第3张图片
图中并不是三个neural network, 而是同一个neural network在三个不同的时间点被使用了三次(同样的weight用同样的颜色表示)。

RNN有不同的变形,Elman Network & Jordan Network.
李宏毅机器学习课程笔记9:Recurrent Neural Network_第4张图片
据说 Jordan Network 有更好的performance,因为在Elman Network 中放到memory里的是没有target的,有点难控制它学到什么东西放到memory里面,而在Jordan Network中放到memory里的是有target的,我们比较清楚放到target中的是什么东西。

RNN还可以是双向的。刚才看到的例子中,输入一个句子,RNN从句首读到句尾。其实读的顺序也可以是反过来的。同时训练正向RNN与逆向RNN,将二者的hidden layer都接给一个output layer。用双向RNN的好处是,它产生output时看的范围比较广,看了整个input sequence。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第5张图片

LSTM的基本概念与内部结构

现在常用的memory是LSTM(Long Short-Term Memory), 结构比较复杂,有三个Gate.
当外界想写入memory cell的时候,必须通过input gate,只有在input gate被打开的时候,memory gate才可以被写入,input gate 是打开还是关闭,是neural network自己学的。同理还有一个output gate, 它的开或关也是neural network 学到的。还有一个forget gate, 决定什么时候将memory cell中的内容忘掉,它的开或关也是neural network 学到的。
可以将LSTM看做special neuron(4 inputs, 1 output), 4 inputs指的是外界想要存到memory cell 里的值+控制三个门的信号。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第6张图片

顺便一提,Long Short-term Memory 里的Long 是形容Short-term Memory 的。在最开始看到的最简单的RNN模型中,memory是short-term的,每次有新的输入,memory都会被洗掉。而LSTM的short-term比较long: 只要控制forget gate的信号决定不forget,memory的值就会被存起来。

下面这张图更清晰的表现了LSTM的结构, z,zi,zo,zf 都是scalar, 这4个input scalar 是由input vector与weight vector计算内积再加上bias而来,weight vector与bias是由training data用gradient descent学到的。
函数 f 常选sigmoid,因为sigmoid输出的0-1之间的值可以表示gate打开的程度(1:打开,0:关闭)。 f(zi)=1 时,允许输入; f(zi)=0 时,相当于无输入。 f(zo)=1 时,允许输出; f(zi)=0 时,相当于无法输出。 f(zf)=1 时,相当于记得memory cell中之前的值 c f(zf)=0 时,相当于洗掉 c
memory cell中的值按图中的公式进行更新。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第7张图片

LSTM组成的网络

把之前的网络中的neuron换成LSTM,就是用LSTM的网络的结构。参数量变成了之前的4倍。
这里写图片描述

假设现在一层有n个LSTM,n个memory cell的值组成vector ct1 , 下图中的 z,zi,zf,zo 都是n维vector, 第i维控制第i个LSTM相应的gate。
这里写图片描述

而实际中要更复杂一点:把每个LSTM在时刻t的output ht 接到该LSTM在下一时刻的输入,同时所谓peephole的意思是把前一时刻memory cell中的值也拉到下一时刻的input中。即,操控LSTM4个input z,zi,zf,zo 时同时考虑了 xt+1,ht,ct .
这里写图片描述

一般一层不够,所谓Multiple-layer LSTM就是把前一层各LSTM输出的 ht 作为下一层对应LSTM的输入 xt .

Keras支持三种RNN,分别是LSTM, GRU(LSTM的简化,只有两个gate,减少了参数避免了过拟合,performance与LSTM差不多), SimpleRNN(本节最开始的RNN结构)。

RNN的Learning

RNN在Learning时如何定义loss function呢?以slot filling 为例,对每个输入 xi , 其输出的 yi 与相应的reference vector计算cross entropy, cross entropy之和就是loss function. 训练时word sequence不能打散,要先用 x1 得到 y1 , 再用 x2 得到 y2 .
定义好loss function之后,用gradient descent做training。gradient descent的算法从BP进阶为BPTT(Backpropagation through time).
但是,很遗憾的,RNN的训练是比较困难的,其error surface要么很平缓要么很陡峭。这样在做gradient descent时,参数可能跳到悬崖上,造成loss暴增,或者跳到悬崖边上(gradient很大),造成参数飞出去(NAN)。解决办法是clipping: 当gradient>某个阈值时,另gradient = 阈值。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第8张图片

为何RNN会有rough的error surface?
并不是因为来自sigmoid的gradient vanish,因为换成ReLU也存在相同问题。(RNN中把sigmoid换成ReLU效果往往更差)
其实是因为RNN处理的是time sequence, 同样的weight在不同时刻被多次使用。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第9张图片
(gradient在w=1处很大,在w=0.99处很小)

如何解决这一问题呢?使用最广泛的技巧是LSTM.
为什么要把一般的RNN换成LSTM?因为LSTM可以处理gradient vanishing的问题:LSTM可以让error surface不那么崎岖,把平坦的部分拿掉,这样解决了gradient vanishing的问题,但没有解决gradient explosion的问题。
那么,为什么LSTM可以处理gradient vanishing的问题呢?
在一般的RNN中,每个时刻neuron的output都会被放到memory中去,所以在每个时刻memory中的值都会被洗掉。但在LSTM中,是把memory中原来的值乘上一个数再加上一个数,即memory和input是想加的关系。所以LSTM中如果weight影响了memory中的值,那么这个影响会永远都存在(除非forget gate决定洗掉memory,有说法认为要给forget gate很大的bias以使其多数情况下开启),而不像SimpleRNN中memory的值在每个时刻都会被洗掉。
若使用LSTM出现了过拟合,可考虑改用GRU。GRU的精神是“旧的不去,新的不来”,它将input gate与forget gate联动起来:若input gate 开,则forget gate 关。

其它处理gradient descent的技巧还有clockwise RNN, SCRN……
如果random初始化一般RNN的weight,那么用ReLU的效果要比用sigmoid的效果差。但[Quoc V. Le, arXiv’15]提出,如果用单位矩阵初始化一般RNN的weight,那么用ReLU的效果要比用LSTM的效果好。
李宏毅机器学习课程笔记9:Recurrent Neural Network_第10张图片


李宏毅机器学习课程笔记

李宏毅机器学习课程笔记1:Regression、Error、Gradient Descent
李宏毅机器学习课程笔记2:Classification、Logistic Regression、Brief Introduction of Deep Learning
李宏毅机器学习课程笔记3:Backpropagation、”Hello world” of Deep Learning、Tips for Training DNN
李宏毅机器学习课程笔记4:CNN、Why Deep、Semi-supervised
李宏毅机器学习课程笔记5:Unsupervised Learning - Linear Methods、Word Embedding、Neighbor Embedding
李宏毅机器学习课程笔记6:Unsupervised Learning - Auto-encoder、PixelRNN、VAE、GAN
李宏毅机器学习课程笔记7:Transfer Learning、SVM、Structured Learning - Introduction
李宏毅机器学习课程笔记8:Structured Learning - Linear Model、Structured SVM、Sequence Labeling
李宏毅机器学习课程笔记9:Recurrent Neural Network
李宏毅机器学习课程笔记10:Ensemble、Deep Reinforcement Learning

你可能感兴趣的:(李宏毅机器学习课程)