照例先规定符号含义,我们此处默认指多层RNN网络。规定 h t l ∈ R n h^l_t\in{R^n} htl∈Rn表示第 l l l层 t t t时间步的因状态,维度为n,当 l = 0 l=0 l=0时, h t 0 h^0_t ht0表示 t t t时刻的外部输入;因为LSTM网络中使用全连接网络作为常规操作,全连接的数学表达为 W x + b Wx+b Wx+b,为了简洁起见,我们直接用一个映射变换 T n , m T_{n,m} Tn,m表示将一个 n n n维的输入映射为 m m m维的输出,即 R n → R m R^n{\rightarrow}R^m Rn→Rm; L L L是网络的层数, h t L h^L_t htL可直接用来预测输出 y t y_t yt。
然后使用以上符号,我们再串一串LSTM的执行机理,如下公式所示。
上面的写法很简洁,如果看不惯,可以参考下面的标准写法,两者是一样的:
f t l = s i g m ( T 2 n , 4 n [ h t l − 1 , h t − 1 l ] ) f^l_t=sigm(T_{2n,4n}[h^{l-1}_t,h^l_{t-1}]) ftl=sigm(T2n,4n[htl−1,ht−1l])
i t l = s i g m ( T 2 n , 4 n [ h t l − 1 , h t − 1 l ] ) i^l_t=sigm(T_{2n,4n}[h^{l-1}_t,h^l_{t-1}]) itl=sigm(T2n,4n[htl−1,ht−1l])
o t l = s i g m ( T 2 n , 4 n [ h t l − 1 , h t − 1 l ] ) o^l_t=sigm(T_{2n,4n}[h^{l-1}_t,h^l_{t-1}]) otl=sigm(T2n,4n[htl−1,ht−1l])
C t l ˇ = t a n h ( T 2 n , 4 n [ h t l − 1 , h t − 1 l ] ) \check{C^l_t}=tanh(T_{2n,4n}[h^{l-1}_t,h^l_{t-1}]) Ctlˇ=tanh(T2n,4n[htl−1,ht−1l])
C t l = f t l ⨀ C l − 1 l + i t l ⨀ C ˇ l − 1 l C^l_t=f^l_t{\bigodot}C^l_{l-1} + i^l_t{\bigodot}\check{C}^l_{l-1} Ctl=ftl⨀Cl−1l+itl⨀Cˇl−1l
h t l = o t l ⨀ t a n h ( C t l ) h^l_t=o^l_t{\bigodot}tanh(C^l_t) htl=otl⨀tanh(Ctl)
先说结论,其实非常简单:把dropout设置在RNN网络的输入位置(在下图中虚线位置),也就是说对上式中的 h t l − 1 h^{l-1}_t htl−1进行随机丢弃或者说置零操作( h t 0 = = x t h^{0}_t{==}x_t ht0==xt)。修改后的公式如下,仅仅做了一处修改:
可以看到,并没有什么高深的地方,非常简单,但作者却把这个问题解决的很漂亮,也就是说大家常说的simple and elegant,下面解释为什么如此设置。作者指出,dropout一定要设置在网络的非循环部分,否则信息将会因循环步的进行而逐渐丢失。比如我们将dropout设置在隐状态上(下图每一个实线位置),那么每经过一次循环,剩余的信息就被做一次dropout,如果是长序列,那么循环到最后,前面的信息早就丢失殆尽了;反之,我们把dropout设置在输入神经元上(下图虚线位置),如下图所示,那么因dropout造成的信息损失则与循环的次数无关,而仅仅与网络的层数相关。