RNN介绍及梯度详细推导
1. RNN简介
RNN(Recurrent Neural Network, 循环神经网络)算得上是极具魅力的一类神经网络。同经典的前馈神经网络相比较(如多层感知器、深度置信网络、卷积神经网络等),RNN允许网络隐层(hidden layer)的输出再以输入的形式作用于该隐层自己。假设一个文本序列“I have a pen”,我们可以用一些方法将其中的每个单词进行向量化,如采用one-hot编码、ti-idf、词嵌入等方法。再假设我们有一个计算单元,它有两个输入。一个输入是上述提到的单词的向量,另一个输入是一个大小为m的向量。该计算单元的输出也是一个大小为m的向量。首先,我们随机初始化一个大小为m的向量,并将该向量和上述文本序列的第一个词“I”的词向量输入给计算单元。计算单元输出一个大小为m的向量。接着我们又将这个刚得到的大小为m的向量和第二个词“have”的向量输入给计算单元,又得到一个大小为m的向量。如此重复,直至对文本序列“I have a pen”进行了一次完整遍历,最终得到一个大小为m的向量。这个最终得到的向量就可以作为对原文本序列的一个表征,用于后续任务。例如,接一个输出层再加softmax用来做文本分类。
上述的计算单元有两个重要性质。首先,不论上述文本序列的长度如何变化,只要完成对该文本进行一次遍历,最终的输出向量大小均为m。因此它非常有利于处理不同长度的序列数据。其次,当前词总是伴随着前一个词的输出一起作为输入参与计算(递归),这就意味这序列本身的顺序能够被计算单元很好的捕捉到。因此,这样的计算单元特别适合于对序列顺序敏感的任务,如时序预测、词性标注等任务。
RNN的基本构成就是这样的计算单元。
从理论上看,RNN的一系列后续变体(如GRU、LSTM等)在设计上非常经验(实际上,必须承认目前大多数的网络在设计上都很经验),但却很容易被人们所接受。这些接受绝不仅仅是因为它们强大的性能表现,也包含其背后设计思路的“合理性”(符合直觉)。而经验式的合理,往往会催生大量后续更加“合理”的设计,这直接导致了一个研究领域的迅速崛起。RNN是这样,CNN是这样,Deep Learning也是这样。从实践上看,RNN在涉及到序列或自然语言的任务上获得了前所未有的成功,圈粉无数。本文的目的是详细介绍RNN的梯度推导过程,便于读者对RNN形成更加理性的认识。在正式进入推导之前,先简单介绍一下RNN的三种常见结构。
2. RNN的几种常见结构
为了方便表述,我们把一个序列中的数据以时刻(time stamp)来进行划分。简单来讲,我们可以认为时刻0对应的就是序列中第一个元素;时刻1对应的是第2个元素,以此类推。如果将之前的递归计算方式用时刻的概念来表述,便能更加容易地对网络进行理解。下面我们采用这种方法来介绍RNN的三种常见结构。
结构一
上图所示的RNN结构中,输入序列为 X = ( x 0 , x 1 , . . . , x l − 1 ) \ X=(x^{0}, x^{1}, ...,x^{l-1} ) X=(x0,x1,...,xl−1)。对于任意时刻 t \ t t, h t \ h^t ht由 h t − 1 \ h^{t-1} ht−1和 x t \ x^t xt决定。同时,时刻 t \ t t对应于目标输出(target) y t \ y^t yt。这样的结构很适合时间序列预测类的任务,因为模型能够通过之前的信息 h t − 1 \ h^{t-1} ht−1和当前的输入 x t \ x^t xt来预测当前时刻的输出 y ^ t \ \hat y^t y^t。该结构最大的问题是时刻 t \ t t的损失 L t \ L^{t} Lt与所有之前时刻的状态 h t − 1 , h t − 2 , . . . , h 0 \ h^{t-1}, h^{t-2},... ,h^{0} ht−1,ht−2,...,h0都相关。这意味着要求得 h t \ h^{t} ht,首先需要求 h t − 1 \ h^{t-1} ht−1;而要求 h t − 1 \ h^{t-1} ht−1,又首先得求出 h t − 2 \ h^{t-2} ht−2,以此类推。我们知道,在使用BP(Back Propagation,反向传播)求梯度的时候,对每一个输入需要一次前向传播过程来计算网络中的activation。而上述RNN是顺序计算的,难以并行化,因此其训练过程通常比较耗时。
结构二
与前文介绍的第一种RNN结构的区别在于:这种结构取消了相邻时刻间状态 h \ h h之间 的连接。取而代之的是前一时刻的输出 o t − 1 \ o^{t-1} ot−1与当前时刻的状态 h t \ h^t ht之间的连接。采用与结构一中类似的分析可知,该RNN结构仍是顺序执行的,似乎除了训练参数可能减少(输出 o {\ o} o的维度通常比 h \ h h要小),没有其它任何区别。不过实际上,这种网络可以采用名为teacher forcing的方法来训练。简单来讲,既然 h t \ h^t ht的输入部分来自 o t − 1 \ o^{t-1} ot−1,而 o t − 1 \ o^{t-1} ot−1本身在训练过程中受 y t − 1 \ y^{t-1} yt−1约束( o t − 1 \ o^{t-1} ot−1要尽可能逼近 y t − 1 \ y^{t-1} yt−1),因此可以直接使用 y t − 1 \ y^{t-1} yt−1来代替 o t − 1 \ o^{t-1} ot−1作为 h t \ h^t ht的输入。而任意时刻的 y t \ y^{t} yt在训练集中已经被提供,所以网络在训练过程中不再需要顺序执行!
不过,这样做的缺点就是 y t \ y^{t} yt中通常包含的信息远少于 h t \ h^{t} ht,因此模型对历史信息的学习能力远不如结构一。
结构三
与结构一的唯一区别是:该结构的RNN仅在最后一个时刻 l \ l l时才会有输出 o l \ o^l ol。显然,这种结构的典型应用就是分本分类。
3. RNN的梯度推导
就求解梯度而言,上述介绍的三种结构的异同如下:
- 在结构一中,当前状态 h t \ h^t ht不但会影响当前时刻的损失 l t \ l^t lt,也会影响所有后续时刻的损失;
- 在结构二中,如果采用teacher forcing的训练方法,当前时刻的状态 h t \ h^t ht只会影响当前时刻的损失 l t \ l^t lt,并不影响后续时刻的损失;
- 在结构三中,所有时刻的状态均只影响最后的损失(因为只有这一个损失)。
由上述分析可知,结构一的梯度求解是最复杂的。因此,本文仅给出结构一的梯度推导,其它两种结构读者可以自行推导。
我们首先假定输出 y ^ ( t ) \ \hat y^{(t)} y^(t)是一个经softmax得到的概率分布。可以把这样的结构想象成一个词性标注问题,即对于每一个输入的词 x ( t ) \ x^{(t)} x(t),需要将其标注为“名词”、“动词”、“数量词”等有限的词性集合中的一个。那么,softmax得到的概率分布中的每一个概率对应于一个词性。在此假设下,给出结构一的形式化定义:
(1) h ( t ) = t a n h ( b + W h ( t − 1 ) + U x ( t ) ) , \ \pmb h^{(t)}=\mathtt{tanh}(\pmb b + \pmb W \pmb h^{(t-1)} + \pmb U \pmb x^{(t)}), \tag{1} hhh(t)=tanh(bbb+WWWhhh(t−1)+UUUxxx(t)),(1)
(2) y ^ ( t ) = s o f t m a x ( c + V h ( t ) ) . \ \hat y^{(t)}=\mathtt{softmax}(\pmb c + \pmb V \pmb h^{(t)}).\tag{2} y^(t)=softmax(ccc+VVVhhh(t)).(2)
我们首先来梳理一下上述各矩阵的大小。观察公式(1),假设输入 x ( t ) \ x^{(t)} x(t)是大小为n的向量(向量均指列向量;即可以看作是大小为(n,1)的矩阵);状态 h ( t ) \ \pmb h^{(t)} hhh(t)和 h ( t − 1 ) \ \pmb h^{(t-1)} hhh(t−1)是大小为k的向量。约定 t a n h \mathtt {tanh} tanh作用于矩阵时相当于对矩阵中的每一个元素 x i , j \ x_{i,j} xi,j分别执行 t a n h ( x i , j ) \mathtt {tanh}(x_{i,j}) tanh(xi,j)。
因为矩阵加法和 t a n h \mathtt {tanh} tanh函数均不会影响矩阵的大小,故可知公式(1)中的 b \ \pmb b bbb、 W h ( t − 1 ) \ \pmb W \pmb h^{(t-1)} WWWhhh(t−1)和