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结构
上图所示的RNN结构中,输入序列为   X = ( x 0 , x 1 , . . . , x l − 1 ) \ X=(x^{0}, x^{1}, ...,x^{l-1} )  X=(x0,x1,...,xl1)。对于任意时刻   t \ t  t   h t \ h^t  ht   h t − 1 \ h^{t-1}  ht1   x t \ x^t  xt决定。同时,时刻   t \ t  t对应于目标输出(target)   y t \ y^t  yt。这样的结构很适合时间序列预测类的任务,因为模型能够通过之前的信息   h t − 1 \ h^{t-1}  ht1和当前的输入   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}  ht1,ht2,...,h0都相关。这意味着要求得   h t \ h^{t}  ht,首先需要求   h t − 1 \ h^{t-1}  ht1;而要求   h t − 1 \ h^{t-1}  ht1,又首先得求出   h t − 2 \ h^{t-2}  ht2,以此类推。我们知道,在使用BP(Back Propagation,反向传播)求梯度的时候,对每一个输入需要一次前向传播过程来计算网络中的activation。而上述RNN是顺序计算的,难以并行化,因此其训练过程通常比较耗时。

结构二

第二种RNN结构
与前文介绍的第一种RNN结构的区别在于:这种结构取消了相邻时刻间状态   h \ h  h之间 的连接。取而代之的是前一时刻的输出   o t − 1 \ o^{t-1}  ot1与当前时刻的状态   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}  ot1,而   o t − 1 \ o^{t-1}  ot1本身在训练过程中受   y t − 1 \ y^{t-1}  yt1约束(   o t − 1 \ o^{t-1}  ot1要尽可能逼近   y t − 1 \ y^{t-1}  yt1),因此可以直接使用   y t − 1 \ y^{t-1}  yt1来代替   o t − 1 \ o^{t-1}  ot1作为   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的梯度推导

就求解梯度而言,上述介绍的三种结构的异同如下:

  1. 在结构一中,当前状态   h t \ h^t  ht不但会影响当前时刻的损失   l t \ l^t  lt,也会影响所有后续时刻的损失;
  2. 在结构二中,如果采用teacher forcing的训练方法,当前时刻的状态   h t \ h^t  ht只会影响当前时刻的损失   l t \ l^t  lt,并不影响后续时刻的损失;
  3. 在结构三中,所有时刻的状态均只影响最后的损失(因为只有这一个损失)。

由上述分析可知,结构一的梯度求解是最复杂的。因此,本文仅给出结构一的梯度推导,其它两种结构读者可以自行推导。

我们首先假定输出   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(t1)+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(t1)是大小为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</

  • 10
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
RNN(循环神经网络)是一种能够处理序列数据的神经网络模型。它通过自循环的方式将前一时刻的隐藏状态信息传递给下一时刻,以此来建模序列中的时序关系。 RNN的反向传播算法主要包含以下几个步骤: 1. 初始化:首先,我们需要初始化模型的参数,包括权重和偏置。这些参数会在反向传播过程中根据损失函数来进行调整。 2. 前向传播:在反向传播之前,我们需要先进行一次前向传播。假设我们有一个包含T个时刻的序列数据,每个时刻的输入是一个D维的向量,隐藏状态的维度为H。对于每个时刻t,我们先计算当前时刻的隐藏状态,根据当前时刻的输入数据和前一时刻的隐藏状态: ht = activation(Wx * Xt + Wh * ht-1 + b) 其中,Wx和Wh分别是输入与隐藏状态之间的权重矩阵,b是偏置项,activation是激活函数。 3. 计算损失函数:根据预测结果和真实结果计算损失函数,常见的损失函数包括均方差误差和交叉熵等。损失函数衡量了模型的预测与真实结果之间的差距。 4. 反向传播:在RNN中,由于隐藏状态之间存在时序关系,我们需要考虑到每个时刻的梯度对前一时刻的梯度的影响。首先,我们计算当前时刻的梯度: dht = dout + dht+1 其中,dout是损失函数对当前时刻的输出的导数。然后,我们利用当前时刻的梯度来计算当前时刻的权重矩阵和偏置项的梯度: dWx += Xt * dht dWh += ht-1 * dht db += dht 接下来,我们计算对前一时刻隐藏状态的梯度: dht-1 = Wh * dht 最后,我们利用当前时刻的梯度和前一时刻的梯度来计算损失函数对输入的导数: dXt = Wx * dht + dXt+1 这样就完成了一个时刻的反向传播。重复以上步骤,可以依次计算每个时刻的梯度,从而完成整个反向传播的过程。 5. 更新参数:最后,利用计算得到的梯度信息更新模型的参数。采用梯度下降法,通过调整参数,使得损失函数尽可能地减小。 总结起来,RNN的反向传播算法通过自循环的方式将梯度从当前时刻传递到前一时刻,并利用当前时刻和前一时刻的梯度来计算参数的梯度,然后通过梯度下降法来更新参数,从而优化模型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值