课程链接:
https://youtu.be/xCGidAeyS4M?list=PLJV_el3uVTsPy9oCRY30oBPNLCo89yu49
https://www.youtube.com/watch?v=rTqmWlnwz_0&list=PLJV_el3uVTsPy9oCRY30oBPNLCo89yu49&index=25
RNN的基础概念
以订票系统中的Slot Filling
为例,我们希望订票系统听到用户说:”I would like to arrive Taipei on November 2nd.”或者”I would like to leaveTaipei 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
.
在RNN中,hidden layer的neuron产生的output
会被存到memory中,对之后的input
, hidden layer的neuron不只考虑input
, 还会考虑存在memory中的值。memory在没有任何input
时需要初始值。
RNN会考虑input sequence的order
,改变input sequence的order
,output
会随之改变。
举例如下:
如下图,图中并不是三个neural network, 而是同一个neural network在三个不同的时间点被使用了三次(同样的weight用同样的颜色表示)。
因为memory中的权重不同,所以同样的词的值不相同。如下图所示:
几种不同的RNN
-
RNN有不同的变形,如下图是Elman Network & Jordan Network的区别:
据说Jordan Network
有更好的performance,因为在Elman Network
中放到memory里的是没有target的,有点难控制它学到把什么样子的hidden的信息 放到memory里面,而在Jordan Network
中放到memory里的y
是有target的,我们比较清楚放到target中的是什么东西。 -
RNN还可以是双向的。刚才看到的例子中,输入一个句子,RNN从句首读到句尾。其实读的顺序也可以是反过来的。同时训练正向RNN与逆向RNN,将二者的hidden layer都接给一个output layer。用双向RNN的好处是,它产生output时看的范围比较广,看了整个input sequence。
Long Short-term Memory (LSTM)
以上讲的RNN只是RNN的最简单的版本,SimpleRNN
其实现在常用的memory是
1. LSTM的基本结构
当外界想写入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 里的值+控制三个门的信号。
顺便一提,Long Short-term Memory 里的Long 是形容Short-term Memory 的。在最开始看到的最简单的RNN模型中,memory是short-term的,每次有新的输入,memory都会被洗掉。而LSTM的short-term比较long: 只要控制forget gate的信号决定不forget,memory的值就会被存起来。
下面这张图更清晰的表现了LSTM的结构:
都是scalar, 这4个input scalar
是由input vector
与weight vector
计算内积再加上bias
而来,weight vector
与bias
是由training data用gradient descent学到的。
函数常选sigmoid
,因为sigmoid
输出的0-1
之间的值可以表示gate打开的程度(1:打开,0:关闭)。
- 输入:时,允许输入; 时,相当于无输入。
- 输出:时,允许输出;时,相当于无法输出。
- memory擦除:时,相当于记得memory cell中之前的值; 时,相当于洗掉 。
memory cell中的值按下图中的公式进行更新。
2. LSTM的例子
3. LSTM组成的网络
把之前的网络中的neuron换成LSTM,就是用LSTM的网络的结构。参数量变成了之前的4倍。
假设现在一层有n个LSTM,n个memory cell的值(scalar)组成vector : , 在时间点t,input一个vector:,这个vector首先乘上一个线性变换,变成另一个vector:,这个vector的每一个dimension就代表操控每一个LSTM的input,这个dimension的维度的大小就是memory的数目,
下图中的 都是n维vector, 第i维控制第i个LSTM相应的gate。
以下是理想的简单的LSTM
而实际中要更复杂一点:把每个LSTM在时刻t的output : 接到该LSTM在下一时刻的输入,同时所谓peephole
的意思是把前一时刻memory cell中的值也拉到下一时刻的input中。即,操控LSTM 4个input 时同时考虑了.
如下图。红线即为peephole
一般一层不够,所谓Multiple-layer LSTM就是把前一层各LSTM输出的作为下一层对应LSTM的输入.
Keras支持三种RNN,分别是LSTM
, GRU
(LSTM的简化,只有两个gate,减少了参数避免了过拟合,performance与LSTM差不多), SimpleRNN
(本节最开始的RNN结构)。
RNN 的 learning
1. RNN在Learning时如何定义loss function呢?
以slot filling 为例,对每个输入, 其输出的 与相应的reference vector计算cross entropy, cross entropy之和就是loss function. 训练时word sequence不能打散,要先用 得到, 再用 得到.
2. RNN的训练学习
定义好loss function之后,用gradient descent
做training。gradient descent
的算法从BP进阶为BPTT(Backpropagation through time)
.
但是,很遗憾的,RNN的训练是比较困难的,其error surface
要么很平缓要么很陡峭。这样在做gradient descent
时,参数可能跳到悬崖上,造成loss暴增
,或者跳到悬崖边上(gradient很大),造成参数飞出去(NAN
)。解决办法是clipping
: 当gradient>某个阈值时,令gradient = 阈值。
3. 为何RNN会有rough的error surface?
并不是因为来自sigmoid的gradient vanish,因为换成ReLU也存在相同问题。(RNN中把sigmoid换成ReLU效果往往更差)
其实是因为RNN处理的是time sequence
, 同样的weight在不同时刻被多次使用。
(gradient在w=1处很大,在w=0.99处很小)
4. 有什么技巧可以帮助我们解决这个问题呢?
使用最广泛的技巧是LSTM
.
为什么要把一般的RNN换成LSTM?
因为LSTM可以处理gradient vanishing的问题:LSTM可以让error surface不那么崎岖,把平坦的部分拿掉,这样解决了gradient vanishing的问题,但没有解决gradient explosion的问题。
那么,为什么LSTM可以处理gradient vanishing的问题呢?
在一般的RNN中,每个时刻neuron的output都会被放到memory中去,所以在每个时刻memory中的值都会被洗掉。但在LSTM中,是把memory中原来的值乘上一个数再加上一个数input,放到cell里面去,即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的效果好。
RNN 的 应用
1. Many to one
2. Many to many (output is shorter)
3. Many to many (no limitation)
停止:
4. Beyond Sequence
5. Sequence-to-Sequence Auto-encoder -Text
6. Sequence-to-Sequence Auto-encoder -Speech
7. Attention-based Model
Neural Turing Machine
8. Reading Comprehension
9. Visual Question Answering
10. Speech Question Answering
RNN vs Structured Learning