文章目录
神经翻译笔记4扩展c. 2017-2019年间RNN和RNN语言模型的新进展
尽管在本文写作时(2020年4月),基于Transformer结构的预训练语言模型已经大杀四方,BERT都已经成为明日黄花,在其基础上衍生的各种变体,例如RoBERTa、ALBERT、BART等等长江后浪推前浪,使得基于RNN的语言模型更不再是语言模型领域的焦点。但是为了系列文章结构的完备性,本文以及下一篇文章仍然会介绍一些这方面的“新”工作和一些里程碑式的工作。本文将介绍2017至2019三年间,RNN体系结构及基于RNN的语言模型的一些新进展。
QuasiRNN
本文实际上发表于2016年,而且采用了CNN的思想,因此先不在本文介绍。在这里先立个flag,等本系列笔记进行到6时,再概述此工作。采取同样思想的亦有SRU,准备也到时再介绍
FS-RNN
FS-RNN (Fast-Slow RNN) [Mujika2017] 受两类RNN的启发
- 多(时间)尺度RNN:对于堆叠RNN中更高层的若干层,其被更新的次数越少(更不频繁),以此来获得信息的分层表示。由于高层参数更新变慢,因此计算起来更高效,梯度更新路径越短,越能捕捉长距离依赖
- 深度变换RNN (deep transition RNN),其相邻两个隐藏状态之间引入了新的顺序连接层,以此来增加两个时间步之间变换函数的深度,进而学习更复杂的非线性变换
FS-RNN将两类网络结合起来,最简单的方式是
- 对底层RNN,引入深度变换(若干顺序连接层),称为“快层”
- 对高层RNN,降低更新频率,称为“慢层”
更形式化地讲,底层在两个时间步之间插入 k k k个顺序连接的RNN神经元 F 1 , … , F k F_1, \ldots, F_k F1,…,Fk,高层只使用一个神经元 S S S。 F 1 F_1 F1接收第 t t t时间步的输入 x t x_t xt,将输出传给 S S S作为输入, S S S处理后将状态传给 F 2 F_2 F2,然后从 F 2 F_2 F2开始输出逐级传播下去,前一个 F i − 1 F_{i-1} Fi−1的输出作为后一个 F i F_i Fi的输入,到 F k F_k Fk输出概率分布 y t y_t yt,如下图所示
记每个RNN神经元 Q Q Q为一个可微函数 f Q ( h , x ) f^Q(h,x) fQ(h,x),其将上一步的隐藏状态 h h h和输入 x x x一起映射为一个新的隐藏状态,则
h t F 1 = f F 1 ( h t − 1 F k , x t ) h t S = f S ( h t − 1 S , h t F 1 ) h t F 2 = f F 2 ( h t F 1 , h t S ) h t F i = f F i ( h t F i − 1 ) f o r 3 ≤ i ≤ k y t = s o f t m a x ( W h t F k + b ) \begin{aligned} h_t^{F_1} &= f^{F_1}(h_{t-1}^{F_k}, x_t) \\ h_t^{S} &= f^{S}(h_{t-1}^{S}, h_t^{F_1}) \\ h_t^{F_2} &= f^{F_2}(h_{t}^{F_1}, h_t^S) \\ h_t^{F_i} &= f^{F_i}\left(h_t^{F_{i-1}}\right)\ \ {\rm for\ }3\le i \le k \\ y_t &= {\rm softmax}\left(Wh_t^{F_k}+b\right) \end{aligned} htF1htShtF2htFiyt=fF1(ht−1Fk,xt)=fS(ht−1S,htF1)=fF2(htF1,htS)=fFi(htFi−1) for 3≤i≤k=softmax(WhtFk+b)
文章使用LSTM作为基础的RNN神经元,在Penn Treebank和enwik8上均取得了不错的效果
Skip RNN
传统RNN和普通的带门控的RNN(例如LSTM)对长句表现都不好。[Campos2017]的思路是让网络学习输入序列中哪些样本可以解决目标问题,因此可以在训练时跳过一些状态的更新,可以减少对序列的操作
记RNN接受的输入序列 x = ( x 1 , … , x T ) \boldsymbol{x} = (x_1, \ldots, x_T) x=(x1,…,xT),每步向下传递的状态为 s = ( s 1 , … , s T ) \boldsymbol{s}=(s_1, \ldots, s_T) s=(s1,…,sT),有
s t = R N N ( s t − 1 , x t ) s_t = {\rm RNN}(s_{t-1}, x_t) st=RNN(st−1,xt)
本文引入了一个额外的状态更新门 u t ∈ { 0 , 1 } u_t \in \{0,1\} ut∈{ 0,1},该门是完全二值的,只输出0或1,不像LSTM或GRU那样输出一个0到1的浮点数。当 u t = 1 u_t = 1 ut=1时,该时刻状态更新;当 u t = 0 u_t = 0 ut=0时,该时刻从前一时刻直接拷贝状态。 u t u_t ut的结果由上一步产生的概率 u ~ t ∈ [ 0 , 1 ] \tilde{u}_{t} \in [0,1] u~t∈[0,1]决定,具体地
u t = f b i n a r i z e ( u ~ t ) s t = u t ⋅ R N N ( s t − 1 , x t ) + ( 1 − u t ) ⋅ s t − 1 Δ u ~ t = σ ( W p s t + b p ) u ~ t + 1 = u t ⋅ Δ u ~ t + ( 1 − u t ) ⋅ ( u ~ t + min ( Δ u ~ t , 1 − u ~ t ) ) \begin{aligned} u_t &= f_{\rm binarize}(\tilde{u}_t) \\ s_t &= u_t \cdot {\rm RNN}(s_{t-1}, x_t) + (1-u_t)\cdot s_{t-1} \\ \Delta \tilde{u}_t &= \sigma(\boldsymbol{W}_ps_t + \boldsymbol{b}_p) \\ \tilde{u}_{t+1} &= u_t \cdot \Delta\tilde{u}_t + (1-u_t)\cdot (\tilde{u}_t + \min(\Delta\tilde{u}_t, 1-\tilde{u}_t)) \end{aligned} utstΔu~tu~t+1=fbinarize(u~t)=ut⋅RNN(st−1,xt)+(1−ut)⋅st−1=σ(Wpst+bp)=ut⋅Δu~t+(1−ut)⋅(u~t+min(Δu~t,1−u~t))
其中 W p \boldsymbol{W}_p Wp是权重, b p \boldsymbol{b}_p bp是偏置项, σ \sigma σ是sigmoid函数, f b i n a r i z e : [ 0 , 1 ] → { 0 , 1 } f_{\rm binarize}:[0,1] \rightarrow \{0,1\} fbinarize:[0,1]→{ 0,1}是将输入映射为0或1的函数,本文使用了四舍五入法(round),也可以从伯努利分布随机采样。模型隐含了一个信息:如果连续跳过的状态越多,那么下一个状态就更可能被更新:
- 如果当前状态被跳过,那么下一个时间步的“预激活值” u ~ t + 1 \tilde{u}_{t+1} u~t+1会增加 Δ u ~ t \Delta \tilde{u}_t Δu~t
- 如果当前状态被更新,那么累积的“预激活值”清零,重置为 Δ u ~ t \Delta \tilde{u}_t Δu~t
如果在某些场合下,可以为减少计算量额外牺牲精度,即为了让模型更倾向于少更新状态,则可以引入一个额外的损失项
L b u d g e t = λ ⋅ ∑ t = 1 T u t L_{\rm budget} = \lambda \cdot \sum_{t=1}^T u_t Lbudget=λ⋅t=1∑Tut
有趣的是,本工作的三项实验均未在NLP任务上进行
高秩RNN语言模型MoS
[YangZhilin2017]将语言模型看作是一个矩阵分解问题。文章将自然语言 L \mathcal{L} L定义为一个有限集合,集合中每个元素是一个有序对,由上下文和给定上下文后下一个标识符的分布两者组成,即
L = { ( c 1 , P ∗ ( X ∣ c 1 ) ) , … , ( c N , P ∗ ( X ∣ c N ) ) } \mathcal{L} = \{(c_1, P^\ast(X|c_1)), \ldots, (c_N, P^\ast(X|c_N))\} L={ (c1,P∗(X∣c1)),…,(cN,P∗(X∣cN))}
其中 N N