持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
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' ) 当做输出==
如果你还是不太了解,建议看一下教学视频www.bilibili.com/video/BV1Wv… 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通常不会只有一层,大概就是长成这个样子
有没有一种很爽的感觉,这种东西居然都能看懂(狗头)