4.2 Recurrent Neural Network (RNN) I
1. 问题引入
在NLP领域,存在一个重要的子任务即Slot Filling(槽位填充).比如有一个人对订票系统说“I would like to arrive Taipei on November 2nd”,那么系统要自动识别出Taipei属于Destination这个slot,November 2nd属于Time of arrival这个slot,其它词汇不属于任何slot.
这个问题你当然可以使用一个feedforward neural network来解,也就是说我叠一个feedforward neural network,input是一个词汇(把Taipei变成一个vector)丢到这个neural network里面去(你要把一个词汇丢到一个neural network里面去,就必须把它变成一个向量来表示).
用向量表示word的方法有很多.下面说一个没有介绍过的方法.因为如果只是用1-of-N encoding(独热编码)来描述一个词汇的话你会遇到一些问题,因为有很多词汇你可能都没有见过,所以你需要在1-of-N encoding里面多加dimension,这个dimension代表other.然后所有的词汇,如果它不是在我们词言有的词汇就归类到other里面去(Gandalf,Sauron归类到other里面去).你也可以用每一个词汇的字母来表示它的vector,比如说,你的词汇是apple,apple里面有出现app、ppl、ple,那在这个vector里面对应到app,ple,ppl的dimension就是1,而其他都为0.
言归正传,你会期望model的输出是Probability distribution,这个代表输入的词汇属于每一个slot的概率.
但是只有这样是不够的,Feedforward network不能解决这个问题.假设又有人说:"leave Taipei on November 2nd",这时候Taipei就变成了"place of departure",它应该是出发地而不是目的地.但是对于neural network来说,input一样的东西output就应该是一样的东西(input "Taipei",output要么是destination几率最高,要么就是place of departure几率最高),你没有办法一会让出发地的几率最高,一会让它目的地几率最高.
因此,在Slot Filling的任务中,我们需要neural network是有记忆的,要记住在Taipei之前出现过的arrive和leave,而这种有记忆的neural network叫做Recurrent Neural Network.
2. RNN
2.1 what is RNN
有记忆的neural network就叫做Recurrent Neural network(RNN)。在RNN里面,每一次hidden layer的neuron产生output的时候,这个output会被存到memory里去(用蓝色方块表示memory)。那下一次当有input时,这些neuron不只是考虑\(input\ x_1,x_2\),还会考虑存到memory里的值。对它来说除了\(x_1,x_2\)以外,这些存在memory里的值\(a_1,a_2\)也会影响它的output.
2.1.1 Example
举个例子,假设我们现在图上这个neural network,它所有的weight都是1,所有的neuron没有任何的bias.再假设所有的activation function都是linear(这样可以不要让计算太复杂).再输入\(input\ sequence\)之前,需要先给\(memory\)初始值.先假设初始值都是\(0\).
现在输入第一个\([1,1]\),根据计算会得到绿色那层的输出为\([2,2]\).那么红色那层的输出为\([4,4]\)(\(weight\)都是\(1\)).
接下来Recurrent Neural Network会将绿色neuron的output存在memory里去,所以memory里面的值被update为\(2\)(注意我们之前说的是储存隐藏层输出).接下来再输入\([1,1]\),那么绿色的\(neuron\)输入有4个:\([1,1]\)、\([2,2]\),output为\([6,6]\)(\(weight\)为1).第二层的neural output为\([12,12]\).
所以对Recurrent Neural Network来说,你就算input一样的东西,它的output是可能不一样了(因为有memory)
接下来\([6,6]\)就会储存在memory,输出过程如下:
那在做Recurrent Neural Network时,有一件很重要的事情就是这个input sequence调换顺序之后output不同(Recurrent Neural Network里,它会考虑sequence的order).
2.2 RNN structure
这里注意一下,这里不是三个network,这是同一个network在三个不同的时间点被使用了三次.(我这边用同样的weight用同样的颜色表示).
所以我们有了memory以后,刚才我们讲了输入同一个词汇,我们希望output不同的问题就有可能被解决。比如说,同样是输入“Taipei”这个词汇,但是因为红色“Taipei”前接了“leave”,绿色“Taipei”前接了“arrive”(因为“leave”和“arrive”的vector不一样,所以hidden layer的output会不同),所以存在memory里面的值会不同。现在虽\(x_2\)的值是一样的,因为存在memory里面的值不同,所以hidden layer的output会不一样,所以最后的output也就会不一样。这是Recurrent Neural Network的基本概念.
3. 不同种RNN
3.1 Elman network & Jordan network
Recurrent Neural Networ的架构是可以任意设计的,比如说,它当然是deep(刚才我们看到的Recurrent Neural Networ它只有一个hidden layer),当然它也可以是deep Recurrent Neural Networ.
比如说,我们把\(x^t\)丢进去之后,它可以通过一个hidden layer,再通过第二个hidden layer,以此类推(通过很多的hidden layer)才得到最后的output.每一个hidden layer的output都会被存在memory里面,在下一个时间点的时候,每一个hidden layer会把前一个时间点存的值再读出来,以此类推最后得到output,这个process会一直持续下去.
上述这种\(RNN\)我们称为Elman network,我们当然也存在另一种\(RNN\)称为Jordan network.Jordan network存的是整个network output的值,它把output值在下一个时间点在读进来(把output存到memory里).据说Jordan network会得到好的performance.
Elman network是没有target,很难控制说它能学到什么hidden layer information(学到什么放到memory里),但是Jordan network是有target,今天我们比较很清楚我们放在memory里是什么样的东西.
3.2 Bidirectional neural network
Recurrent Neural Network还可以是双向的,在之前的例子中,输入一个句子,从句首读到句尾,这里的顺序是可以倒转的.现在同时训练正向的RNN和逆向的RNN,把它们的Hidden Layer都接到一个Output Layer,然后输出y.Bidirectional RNN的好处是network产生输出时看到的范围比较广,能看到整个sequence.
3.3 Long Short-term Memory(LSTM)
那我们刚才讲的Recurrent Neural Network其实是Recurrent Neural Network最简单的版本.
这个Long Short-term Memor是有三个gate,当外界某个neural的output想要被写到memory cell里面的时候,必须通过一个input Gate,那个input Gate要被打开的时候,你才能把值写到memory cell里面去,如果把这个关起来的话,就没有办法把值写进去.至于input Gate是打开还是关起来,这个是neural network自己学的.
输出的地方也有一个output Gate,这个output Gate会决定说,外界其他的neural可不可以从这个memory里面把值读出来(把output Gate关闭的时候是没有办法把值读出来,output Gate打开的时候,才可以把值读出来).那么,output Gate什么时候打开什么时候关闭,也是network是自己学到的.
第三个gate叫做forget Gate,forget Gate决定说:什么时候memory cell要把过去记得的东西忘掉.这个forget Gate什么时候会把存在memory的值忘掉,什么时候会把存在memory里面的值继续保留下来),这也是network自己学到的.
整个LSTM你可以看成,它有四个input 1个output,这四个input中,一个是想要被存在memory cell的值(但它不一定存的进去)还有操控input Gate的讯号,操控output Gate的讯号,操控forget Gate的讯号,有着四个input但它只会得到一个output.
注意一下,标题上的Short-term中的"-"的位置,表示长时间的短期记忆.想想我们之前看的Recurrent Neural Network,它的memory在每一个时间点都会被洗掉,只要有新的input进来,每一个时间点都会把memory 洗掉,所以的short-term是非常short的,但如果是Long Short-term Memory,它记得会比较久一点(只要forget Gate不要决定要忘记,它的值就会被存起来).
3.3.1 LSTM的memory cell
将LSTM的\(memory\ cell\)放大来看,结构如下图所示.底下这个是外界传入cell的input,还有input gate,forget gate,output gate。现在我们假设要被存到cell的input叫做z,操控input gate的信号叫做\(z_i\)(一个标量),操控forget gate的信号叫\(z_f\),操控output gate叫做\(z_o\).综合这些东西会得到一个output 记为a。假设cell里面有这四个输入之前,它里面已经存了值c.
当我们输入\(z\)的时候,我们会把\(z\)通过activation function得到\(g(z)\).\(z_i\)也会通过另外一个activation function得到\(f(z_i)\)(\(z_i,z_f,z_o\)通过的activation function 通常我们会选择sigmoid function,选择sigmoid function的意义是它的值是介在0到1之间的。这个0到1之间的值代表了这个gate被打开的程度,比如f的output是1,表示为被打开的状态,反之代表这个gate是关起来的).接下来将\(memory\)里的值\(c\)乘上\(f(z_f)\),再与\(g(z)f(z_i)\)相加.即\(c^{'} = g(z)f(z_i)+cf(z_f)\),这个\(c^{'}\)就是新的存在\(memory\)里面的值.
最后\(c'\)通过activation function得到h(c'),再将其与\(f(z_o)\)相乘.
3.3.2 LSTM Example
我们的network里面只有一个LSTM的cell,那我们的input都是三维的vector,output都是一维的vector.那这三维的vector跟output还有memory的关系如下图.
比如第二个人黄条,当\(x_2\)的值被设为1时,\(memory\)才有\(x_1\)的值3.
接下来就做一下实际的运算.下图是一个\(memory\ cell\).那么输入的4个\(input\ scalar\)怎么来的呢?input的三维vector乘以linear transform以后所得到的结果(\(x_1,x_2,x_3\)乘以权重再加上bias),这些权重和bias是哪些值是通过train data用梯度下降学到的.
假设我已经知道这些值是多少了,那用这样的输入会得到什么样的输出.那我们就实际的运算一下.
接下来,我们实际的input一下看看.我们假设g和h都是linear(因为这样计算会比较方便).假设存到memory里面的初始值是0.
接下来input(4,1,0),传入input的值为4,input gate会被打开,forget gate也会被打开,所以memory里面存的值等于7(3+4=7),output gate仍然会被关闭的,所以7没有办法被输出,所以整个memory的输出为0。
接下来input(2,0,0),传入input的值为2,input gate关闭(≈ 0),input被input gate给挡住了(0 *2=0),forget gate打开(10)。原来memory里面的值还是7(1 *7+0=7).output gate仍然为0,所以没有办法输出,所以整个output还是0.
接下来input(1,0,1),传入input的值为1,input gate是关闭的,forget gate是打开的,memory里面存的值不变,output gate被打开,整个output为7(memory里面存的7会被读取出来)
最后input(3,-1,0),传入input的值为3,input gate 关闭,forget gate关闭,memory里面的值会被洗掉变为0,output gate关闭,所以整个output为0.
3.3.3 LSTM原理
你可能会想这个跟我们的neural network有什么样的关系呢。你可以这样想,在我们原来的neural network里面,我们会有很多的neural,我们会把input乘以不同的weight当做不同neural的输入,每一个neural都是一个function,输入一个值然后输出一个值。但是如果是LSTM的话,其实你只要把LSTM那么memory的cell想成是一个neuron就好了。
LSTM通常不会只有一层,若有五六层的话。大概是这个样子。每一个第一次看这个的人,反映都会很难受。现在还是 quite standard now,当有一个人说我用RNN做了什么,你不要去问他为什么不用LSTM,因为他其实就是用了LSTM。现在当你说,你在做RNN的时候,其实你指的就用LSTM。Keras支持三种RNN:‘’LSTM‘’,“GRU”,"SimpleRNN".
3.4 GRU
GRU是LSTM稍微简化的版本,它只有两个gate,虽然少了一个gate,但是performance跟LSTM差不多(少了1/3的参数,也是比较不容易overfitting)。如果你要用这堂课最开始讲的那种RNN,你要说是simple RNN才行。