RNN
为了引入RNN ,我们要举的例子是Slot Filling
Slot Filling:你的系统要自动的知道这边的的每一个词汇,它属于哪一个slot
这个问题怎么解呢?
这个问题当然也可以用一个Feedforward 的neural network来解。
input就是一个词汇,把词汇丢到这个neural network里,需要先把它变成一个vector(方法有很多) 。
但是光这样是不够的,没有办法solve 这个problem,为什么呢?
假设现在有一个是使用者说:arrive Taipei… 这时Taipei是目的地
另一个使用者说:leave Taipei…这时Taipei是 出发地
但是对neural network来说,input 一样的东西,output就是一样的东西。
input Taipei的时候要么就都是出发地的几率最高,要么就是目的地的几率最高。
没有办法让他有时候出发地的几率最高,有时候目的地的几率最高。
RNN基本概念
怎么办呢?
如果我们的neural network 是有记忆力的,它记得它在看红色的Taipei之前看过arrive 这个词汇,它就可以根据上下文产生不同的结果。
这种有记忆力的 neural network就叫做 Recurrent Neural Network
在RNN中每一次我们的hidden layer产生output的时候,这个output都会被存到memory里面去。
下一次当有input的时候,这个hidden layer的neuron 不只考虑input 还会考虑memory。
在RNN里面,它会考虑input这个sequence 的order。
RNN在 slot filling里面的
注意是同一个网络被反复使用,不是两个不同的网络。
因为leave 和arrive它们的vector不一样,所以存在memory里面的值,也会不同
虽然x2是一模一样的,但因为memory里面的值不同,所以得到的结果也不同
这就是RNN的基本概念。
RNN的架构,你是可以任意设计的,当然可以是deep的。
RNN的其它变形
Elman Network:把hidden layer的output存起来,在下一个时间点在读出来
Jordan Network:存的是整个network的output的值
RNN还可以是双向的,读取方向可以是反过来的。
你可以同时train一个正向的,一个反向的,把input xt 正向的结果和input xt 逆向的结果都丢到另外一个output layer。
好处是它看的范围是比较广的。
LSTM
理论基础
现在比较常用的memory称之为:Long Short-term Memory
当某个neuron的output想要被写到memory cell里面的时候,它必须通过一道闸门:Input Gate 只有当它打开的时候才能把值写到memory cell里面
输出的地方也有一个 Output Gate :决定外界的其他neuron 可不可以从memory里面把值读出来。
Forget Gate : 决定要不要把过去记得的东西忘掉。
这三个闸门至于什么时候开关,是neural network自己学到的。
整个LSTM,可以看成它有四个input ,一个output。
运行过程(硬核)
如果更仔细来看它的formulation的话,它长得像这样(绝对硬核)
我们假设,
要被存到cell里面的input叫做Z
操作input gate的signal 叫做Zi
操作forget gate 的signal 叫做Zf
操作output gate 的signal 叫做Zo
最后得到的output 叫做 a
所谓的signal 就是一个scalar,这三个signal 的activation function通常选择sigmoid function,sigmoid的值是介于0~1之间的,就代表了这个gate被打开的程度。
假设memory 再输入这个signal之前已经存了值c ,
输入Z 通过activation function得到 g(z), zi 通过activation function得到f(zi)
接下来我们就把g(z) 乘上f(zi)
假设f(zi) =0 那 g(z) *f(zi) 就=0,就相当于没有输入一样,f(zi) =1就等于是直接把g(z)当做输入
Zf 通过activation function得到f(zf)
接下来我们把存在memory里面的值C 乘上f(zf)
假设f(zf) =0 那C *f(zf) 就=0,过去存在memory里面的值就会变成0,f(zf) =1,c会直接通过就等于是还记得过去的值
把 g(z) f(zi) 和 C f(zf) 这两项加起来得到C’ C’** 就是新的存在memory里面的值。
C’ 通过activation function得到h(C’ ) , Zo 通过activation function得到f(zo)
*把h(C’ ) f(zo)得到输出 a
假设f(zo) =0 那h(C’ ) *f(zo) 就=0,就相当于没有输出一样,f(zo) =1 就等于是直接把h(C’ ) 当做输出
如果你还是不太了解,建议看一下教学视频https://www.bilibili.com/video/BV1Wv411h7kN?p=27( 28分钟开始人工运行),绝对硬核
看到这可能会有一个问题,这个东西跟我们原来看到的neural network感觉很不像啊,它跟原来的neural network到底有什么样的关系呢?
你其实只要把那个LSTM的那个memory cell想成是一个neuron 就好
如果我们今天要用一个LSTM的network,你做的事情只是把原来一个简单的neuron换成一个LSTM的cell。
x1 x2 乘上一组weight 去操控第一个LSTM的output gate ,乘上另外一组weight 去操控第一个LSTM的input gate…
LSTM需要的参数量会是一般的neural network的4倍。
yt= h[ g(z) *f(zi) +ct-1 *f(zf) ] * f(zo) 就是上面的过程
LSTM一个simplified的version:
最终模型
真正的LSTM它会把hidden layer的输出接进来,当做下一个时间点的input。
还会加一个peephole,把存在memory cell里面的值也拉过来
所以在操控LSTM的四个gate的时候,你是同时考虑的x 考虑了h 同时考虑了c
把这三个vector并在一起,乘上4个不同的transform,得到这四个不同的vector,再去操控LSTM。
LSTM通常不会只有一层,大概就是长成这个样子
有没有一种很爽的感觉,这种东西居然都能看懂(狗头)