精华内容
下载资源
问答
  • 2020-06-23 11:47:02

    RNN网络

    RNN模型计算分为两步,第一步,计算第t个时间步的隐藏层a;第二步,计算t步的预测值y。

    其中Wax和Waa两组参数分别与前一层的激活a和当前数据x结合,也可将其合二为一,并与x和a的连接计算。

    在RNN网络中最常用激活函数是tanh,有时也用ReLU,一般只在最后一层使用sigmoid或softmax。

    LSTM网络

    相对于基础的RNN,LSTM增加了c(Cell)状态单元,可将其看做在计算激活a的过程中保存的当前状态。它与a都在工作过程中一直向下一步传递。

    公式中的Γ表示门控gate,门控使用sigmoid函数计算得出0-1之间的值,用于过滤(保留或去掉)数据。LSTM中增加的门控分别是:遗忘门f,输入门i和输出门o,它们分别控制在更新当前cell内容时,之前的cell占比,当前的cell占比,以及如何用cell生成a。

    举个简单的例子:用LSTM生成文字,当输入“回车”时,说明本段已结束,之前的内容被遗忘门丢弃;当前输入是“笑脸”时,输入本身没太大意义,被输入门丢弃;如果之前输入了“本段没”,当前时间步又输入了“用”,加在一起是“本段没用”,则输出门将其丢弃。(请领会精神)。

    一般RNN的层数不会特别多(三层就差不多了),除了层数以外,还需要按时间步向后传播,计算量也很大。门控值由前一激活层a和当前时间步的数据x计算得出,每一门控分别对应一组参数w和b,因此,参数比RNN大三倍。这与Attention注意力机制非常相似,用当前输入和当前状态计算权值,给数据流加权。

    GRU网络

    GRU可视为LSTM的变体,它使用了两个门控,更新门u控制当前状态和之前状态的占比(LSTM使用输入门和遗忘门实现);去掉了输出门,用状态值作为激活值,简化算法结构;另外加入了重置门r,用于控制当状状态对前一状态的依赖程度。

    深度神经网络一般都面临梯度爆炸和梯度消失的问题,梯度爆炸问题可以通过加入归一化层或梯度修剪的方式解决,LSTM和GRU主要用于缓解梯度消失问题,如GRU中当更新门趋近0时,当前状态与之前状态相等,类似于用残差网络解决梯度消失问题。它使RNN网络能在更长的时间步中工作,并支持更深层次的网络。

    双向网络

    双向网络在求y时,需要计算向前的激活层和向后的激活层,常用解决类似于完型填空的问题,需要考虑上下文的场景。

    更多相关内容
  • 循环神经网络RNN结构: RNN结构参数说明: 前向传播: 反向传播: 到此所有的参数更新公式推导完毕,欢迎交流学习。 参考1 参考2

    循环神经网络RNN结构:

    在这里插入图片描述

    RNN结构参数说明:

    在这里插入图片描述

    前向传播:

    在这里插入图片描述

    反向传播:

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    待训练参数总数:

    在这里插入图片描述

    到此所有的参数更新公式推导完毕,欢迎交流学习。
    参考1
    参考2
    参考3

    展开全文
  • 深度学习——循环神经网络RNN公式推导 1、循环神经网络引入 1.1 从传统网络到循环网络 对于传统的神经网络,在我们之前介绍的传统的神经网络中,主要包含输入层、隐藏层、输出层三个部分。其基本的图示如下: X表示...

    深度学习——循环神经网络RNN公式推导

    1、循环神经网络引入

    1.1 从传统网络到循环网络

    对于传统的神经网络,在我们之前介绍的传统的神经网络中,主要包含输入层、隐藏层、输出层三个部分。其基本的图示如下:
    在这里插入图片描述
    X表示输入层的向量,H表示隐藏层的向量,O表示输出层的向量。W表示从输入层到隐藏层的权重矩阵,V表示从隐藏层到输出层的权重矩阵。其中,每一层可以有多个神经元。每一层神经元的个数代表的是每一层的维度。

    我们将该网络展开成神经元的形式如下:
    在这里插入图片描述
    我们可以看到的是,对于每一个隐藏层的神经元,其结果是由输入层的向量和权重W来决定的。似乎是有这样的一种可能,每一个隐藏层的神经元是和其排列在前面的神经元之间是有关系的,也就是排列在前面隐藏层的神经元也作为当前隐藏层神经元的一个输入。这就引出来了循环神经网络。

    我们先给出循环神经网络的基本结构:
    在这里插入图片描述

    在上面的结构中,我们能够发现,对于隐藏层的神经元,其中有一个自我传递信息的过程,下面是具体的展开图:
    在这里插入图片描述
    可以理解为,网络的输入通过时间进行向后传播,每次输入一个X,产生一个St和一个O,然后下一个时刻的X和前一个时刻的H作为当前时刻的输入,其中X通过W来控制权重,H通过U来控制权重。我们将上述的神经网络结构成为:单向循环神经网络

    在对于该神经网络进行进一步的展开(这里,我们只展开一个时刻的神经单元)
    在这里插入图片描述

    2 BPTT算法以及前向和后向传播算法

    2.1 前向传播过程

    1. 从输入层神经元到隐藏层神经元。
    2. 从隐藏层神经元到隐藏层神经元。
    3. 隐藏层神经元整合两个部分的输入。
    4. 从隐藏层神经元到输出层神经元。
    2.1.1 从输入层神经元到隐藏层神经元

    这个部分的前向传播主要是输入神经元信息和对应的权重矩阵W来决定的。具体的计算公式为:
    W T X t W^TX_t WTXt
    注意,这个部分中,X是一个向量,W是一个权重矩阵,通过W来将X转换成另外的向量。

    2.1.2 从隐藏层神经元到隐藏层神经元

    这个部分主要是前一个时刻的隐藏层神经元向当前时刻的神经元的信息传递,其值有 S t − 1 S_{t-1} St1和对应的权重矩阵U来决定。公式如下:
    U T S t − 1 U^TS_{t-1} UTSt1
    注意,这个部分中, S t − 1 S_{t-1} St1是一个向量,U是一个权重矩阵,通过U来将 S t − 1 S_{t-1} St1转换成另外的向量。

    2.1.3 隐藏层神经元整合两个部分的输入

    这一部分,主要是当前时刻的神经元 h t h_t ht,将两个部分的输入整合,激活生成当前时刻隐藏层神经元的输出。
    整合的过程就是向量相加,对应的公式为:
    W T X t + U T S t − 1 W^TX_t+U^TS_{t-1} WTXt+UTSt1
    在假设激活函数为f,则激活后生成当前时刻神经元的值:
    S t = f ( W T X t + U T S t − 1 ) S_t = f(W^TX_t+U^TS_{t-1}) St=f(WTXt+UTSt1)

    2.1.4 从隐藏层神经元到输出层神经元

    这一部分的信息传递主要是将当前时刻隐藏层神经元的值传递到当前时刻的输出神经元中去。计算公式为:
    O t = g ( V T S t ) O_t = g(V^TS_t) Ot=g(VTSt)
    其中g表示的也是激活函数。

    2.2 前向过程总结

    前向过程相对来说比较简单,用两个公式就可以总结其基本的传播过程:
    S t = f ( W T X t + U T S t − 1 ) S_t = f(W^TX_t+U^TS_{t-1}) St=f(WTXt+UTSt1)
    O t = g ( V T S t ) = g ( V T f ( W T X t + U T S t − 1 ) ) O_t = g(V^TS_t)=g(V^Tf(W^TX_t+U^TS_{t-1})) Ot=g(VTSt)=g(VTf(WTXt+UTSt1))

    2.3 参数权重说明:

    在整个神经网络中,一共包含的三中权重矩阵,第一个矩阵是W,给矩阵的维度为(N,K),N表示隐藏层神经元值的向量维度,K表示输入神经单元的向量的维度。第二个权重矩阵是V,该矩阵的维度为(L,N),其中P表示输出层的神经元的向量维度。第三个是权重矩阵U,该矩阵的维度是(N,N)。

    2.4 反向传播过程

    2.4.1 误差函数

    关于误差函数的选择,可以根据具体的任务进行,我们这里选择MSE作为误差计算函数:
    J = 1 2 ∑ t = 1 T ∣ ∣ R t − O t ∣ ∣ 2 J=\frac{1}{2}∑_{t=1}^T||R_t-O_t||^2 J=21t=1TRtOt2
    注意,我们这里在算误差的时候, R t 和 O t R_t和O_t RtOt对应的是t时刻真实标签向量是预测输出的向量,所有采用的了取模计算的|| ||

    将上面的式子展开后得到
    J = 1 2 ∑ t = 1 T ∑ j = 1 L ( R t ( j ) − O t ( j ) ) 2 J = \frac{1}{2}∑_{t=1}^T∑_{j=1}^L(R_t(j)-O_t(j))^2 J=21t=1Tj=1L(Rt(j)Ot(j))2
    L表示输入向量的属性值的个数。

    2.4.2 反向传播过程

    对于最后一个时刻的节点 X T , H T , O T X_T,H_T,O_T XT,HT,OT,我们首先计算这一个时刻的相关误差。我们在这里设置两个临时函数:
    n e t o t = V T f ( W T X t + U T S t − 1 ) neto_t = V^Tf(W^TX_t+U^TS_{t-1}) netot=VTf(WTXt+UTSt1)
    n e t h t = W T X t + U T S t − 1 neth_t = W^TX_t+U^TS_{t-1} netht=WTXt+UTSt1

    其中 n e t o ( t ) net_o(t) neto(t)表示t时刻没有激活的输出层的向量值, n e t h ( t ) net_h(t) neth(t)表示t时刻没有激活的隐藏层的向量值。

    为了清晰,我们再之前单个神经元中的结构拿过来:
    在这里插入图片描述
    根据公式和图示,我们能够知道 n e t h ( t ) neth(t) neth(t),表示的是t时刻 [ h 1 , h 2 , h 3 ] [h_1,h_2,h_3] [h1,h2,h3]组成的没有激活时的向量 n e t o ( t ) neto(t) neto(t)表示的是没有激活的 [ o 1 , o 2 ] [o_1,o_2] [o1,o2]构成的向量。

    1. 对于最后时刻T,我们计算出来的误差是J,首先我们计算:
      ∂ J ∂ n e t o 1 ( T ) = ∂ J ∂ O T ( 1 ) ∂ O T ( 1 ) ∂ n e t o T ( 1 ) = ( R T ( 1 ) − O T ( 1 ) ) g ′ ( n e t o T ( 1 ) ) \frac{∂J}{∂neto_1(T)}=\frac{∂J}{∂O_T(1)}\frac{∂O_T(1)}{∂neto_T(1)}=(R_T(1)-O_T(1))g'(neto_T(1)) neto1(T)J=OT(1)JnetoT(1)OT(1)=(RT(1)OT(1))g(netoT(1))
      整理一下有:
      δ T O ( j ) = ∂ J ∂ n e t o T ( j ) = ∂ J ∂ O T ( j ) ∂ O T ( j ) ∂ n e t o T ( j ) = ( R T ( j ) − O T ( j ) ) g ′ ( n e t o T ( j ) ) 其 中 j ∈ [ 1 , L ] δ_T^O(j)=\frac{∂J}{∂neto_T(j)}=\frac{∂J}{∂O_T(j)}\frac{∂O_T(j)}{∂neto_T(j)}=(R_T(j)-O_T(j))g'(neto_T(j)) 其中j∈[1,L] δTO(j)=netoT(j)J=OT(j)JnetoT(j)OT(j)=(RT(j)OT(j))g(netoT(j))j[1,L]

    进一步,转换成矩阵的形式:
    δ T O = ∂ J ∂ n e t o T = ∂ J ∂ O T ∂ O T ∂ n e t o T = ( R T − O T ) ∗ g ′ ( n e t o T ) 公 式 1 δ_T^O=\frac{∂J}{∂neto_T}=\frac{∂J}{∂O_T}\frac{∂O_T}{∂neto_T}=(R_T-O_T)*g'(neto_T) 公式1 δTO=netoTJ=OTJnetoTOT=(RTOT)g(netoT)1

    1. 然后我们计算
      ∂ J ∂ n e t h T ( 1 ) = ∂ J ∂ O T ( 1 ) ∂ O T ( 1 ) ∂ n e t o T ( 1 ) ∂ n e t o T ( 1 ) ∂ h T ( 1 ) ∂ h T ( 1 ) ∂ n e t h T ( 1 ) + ∂ J ∂ O T ( 2 ) ∂ O T ( 2 ) ∂ n e t o T ( 2 ) ∂ n e t o T ( 2 ) ∂ h T ( 1 ) ∂ h T ( 2 ) ∂ n e t h T ( 1 ) \frac{∂J}{∂neth_T(1)}=\frac{∂J}{∂O_T(1)}\frac{∂O_T(1)}{∂neto_T(1)}\frac{∂neto_T(1)}{∂h_T(1)}\frac{∂h_T(1)}{∂neth_T(1)}+\frac{∂J}{∂O_T(2)}\frac{∂O_T(2)}{∂neto_T(2)}\frac{∂neto_T(2)}{∂h_T(1)}\frac{∂h_T(2)}{∂neth_T(1)} nethT(1)J=OT(1)JnetoT(1)OT(1)hT(1)netoT(1)nethT(1)hT(1)+OT(2)JnetoT(2)OT(2)hT(1)netoT(2)nethT(1)hT(2)

    整理一下就是:
    ∂ J ∂ n e t h T ( 1 ) = ∑ i = 1 2 ∂ J ∂ O T ( i ) ∂ O T ( i ) ∂ n e t o T ( i ) ∂ n e t o T ( i ) ∂ h T ( 1 ) ∂ h T ( 1 ) ∂ n e t h T ( 1 ) \frac{∂J}{∂neth_T(1)}=∑_{i=1}^2\frac{∂J}{∂O_T(i)}\frac{∂O_T(i)}{∂neto_T(i)}\frac{∂neto_T(i)}{∂h_T(1)}\frac{∂h_T(1)}{∂neth_T(1)} nethT(1)J=i=12OT(i)JnetoT(i)OT(i)hT(1)netoT(i)nethT(1)hT(1)

    进一步可以推广为:
    ∂ J ∂ n e t h T ( i ) = ∑ i = 1 L ∂ J ∂ O T ( i ) ∂ O T ( i ) ∂ n e t o T ( i ) ∂ n e t o T ( i ) ∂ h T ( j ) ∂ h T ( j ) ∂ n e t h T ( j ) \frac{∂J}{∂neth_T(i)}=∑_{i=1}^L\frac{∂J}{∂O_T(i)}\frac{∂O_T(i)}{∂neto_T(i)}\frac{∂neto_T(i)}{∂h_T(j)}\frac{∂h_T(j)}{∂neth_T(j)} nethT(i)J=i=1LOT(i)JnetoT(i)OT(i)hT(j)netoT(i)nethT(j)hT(j)

    计算出来的结果为:
    δ T h ( j ) = ∂ J ∂ n e t h j ( T ) = ∑ i = 1 L δ T O ( i ) V j i f ′ ( n e t h j ( T ) ) δ_T^h(j)=\frac{∂J}{∂neth_j(T)}=∑_{i=1}^Lδ_T^O(i)V_{ji}f'(neth_j(T)) δTh(j)=nethj(T)J=i=1LδTO(i)Vjif(nethj(T))

    在整理成矩阵的形式:
    δ T h = V T δ T O ∗ f ′ ( n e t h ( T ) ) 公 式 2 δ_T^h=V^Tδ_T^O*f'(neth(T))公式2 δTh=VTδTOf(neth(T))2

    对于其他时刻t的关于 δ t O δ_t^O δtO梯度计算,也最后一个时刻T的计算方式类似:

    δ t O = ∂ J ∂ n e t o t = ∂ J ∂ O t ∂ O t ∂ n e t o t = ( R t − O t ) ∗ g ′ ( n e t o t ) δ_t^O=\frac{∂J}{∂neto_t}=\frac{∂J}{∂O_t}\frac{∂O_t}{∂neto_t}=(R_t-O_t)*g'(neto_t) δtO=netotJ=OtJnetotOt=(RtOt)g(netot)

    注意:最重要的计算部分在于其他时刻关于 δ T h ( j ) δ_T^h(j) δTh(j)的计算,下面进行具体的介绍

    对于不是最后一个时刻T的 δ t h ( j ) δ_t^h(j) δth(j),其主要包含的两个部分,一个部分是从输出层传递回来的误差,另外一个部分是从t+1时刻传递回来的误差。(因为 h t h_t ht计算的结果是 h t + 1 h_{t+1} ht+1的一个输入)

    形式化描述为:
    δ t h ( j ) = [ 输 出 层 误 差 + t + 1 时 刻 的 误 差 ] f ′ ( n e t h t ( j ) ) δ_t^h(j)=[输出层误差 +t+1时刻的误差]f'(neth_t(j)) δth(j)=[+t+1]f(netht(j))
    在之前的计算中,我们已经知道了t时刻从输出层传递回来的误差为:
    V t δ t O ∗ f ′ ( n e t h ( t ) ) V^tδ_t^O*f'(neth(t)) VtδtOf(neth(t))
    则有,原式为:
    δ t h ( j ) = [ V t δ t O + t + 1 时 刻 的 误 差 ] f ′ ( n e t h t ( j ) ) δ_t^h(j)=[V^tδ_t^O +t+1时刻的误差]f'(neth_t(j)) δth(j)=[VtδtO+t+1]f(netht(j))

    下面,我们具体来计算T到T-1时刻的误差传递,根据正向传播的方式有:
    S T = f ( W T X T + U T S T − 1 ) S_{T} = f(W^TX_{T}+U^TS_{T-1}) ST=f(WTXT+UTST1)
    S T − 1 = f ( W T − 1 X T − 1 + U T S T − 2 ) S_{T-1}=f(W^{T-1}X_{T-1}+U^TS_{T-2}) ST1=f(WT1XT1+UTST2)
    根据上面的两个公式我们可以看出,在求 δ T − 1 h ( j ) δ_{T-1}^h(j) δT1h(j)的时候,需要的另外一部分是 δ T h δ T − 1 h ( j ) \frac{δ_{T}^h}{δ_{T-1}^h(j)} δT1h(j)δTh,也就是
    ∑ i = 1 N δ T h ( i ) U j i ∑_{i=1}^Nδ_{T}^h(i)U_{ji} i=1NδTh(i)Uji,则总结上面的公式有
    δ T − 1 h ( j ) = [ ∑ i = 1 L V j i δ t O ( i ) + ∑ i = 1 N δ T h ( i ) U j i ] f ′ ( n e t h T − 1 ( j ) ) δ_{T-1}^h(j)=[∑_{i=1}^LV_{ji}δ_t^O(i)+∑_{i=1}^Nδ_{T}^h(i)U_{ji}]f'(neth_{T-1}(j)) δT1h(j)=[i=1LVjiδtO(i)+i=1NδTh(i)Uji]f(nethT1(j))
    δ T − 1 h = [ V T δ T O + U T δ T h ] ∗ f ′ ( n e t h T − 1 ) δ_{T-1}^h=[V^Tδ_T^O+U^Tδ_{T}^h]*f'(neth_{T-1}) δT1h=[VTδTO+UTδTh]f(nethT1)

    进而可以推广到其他时刻
    δ t − 1 h = [ V T δ t O + U T δ t h ] ∗ f ′ ( n e t h t − 1 ) δ_{t-1}^h=[V^Tδ_t^O+U^Tδ_{t}^h]*f'(neth_{t-1}) δt1h=[VTδtO+UTδth]f(netht1)

    2.5 权重更新

    2.5.1 隐藏层到输出层V更新

    V j i ( n e w ) = V j i ( o l d ) − α ∑ t = 1 T ∂ J ∂ n e t o t ( i ) ∂ n e t o t ( i ) ∂ V j i = V j i − α ∑ t = 1 T δ o t ( i ) h t ( j ) V_{ji}(new)=V_{ji}(old)-α∑_{t=1}^T\frac{∂J}{∂neto_t(i)}\frac{∂neto_t(i)}{∂V_{ji}}=V_{ji}-α∑_{t=1}^Tδ_o^t(i)h_t(j) Vji(new)=Vji(old)αt=1Tnetot(i)JVjinetot(i)=Vjiαt=1Tδot(i)ht(j)
    整理成矩阵的形式:
    V ( n e w ) = V ( o l d ) + α ∑ t = 1 T δ o t h t T V(new)=V(old)+α∑_{t=1}^Tδ_o^th_t^T V(new)=V(old)+αt=1TδothtT
    注意: h t T h_t^T htT中的T表示转置

    2.5.2 输入层到隐藏层的W更新

    W j i ( n e w ) = W j i ( o l d ) − α ∑ t − 1 T ∂ J ∂ n e t h t ( i ) ∂ n e t h t ( i ) ∂ W j i = W j i ( o l d ) − α ∑ t − 1 T δ h t ( i ) X t ( j ) W_{ji}(new)=W_{ji}(old)-α∑_{t-1}^{T}\frac{∂J}{∂neth_t(i)}\frac{∂neth_t(i)}{∂W_{ji}}=W_{ji}(old)-α∑_{t-1}^{T}δ_h^t(i)X_t(j) Wji(new)=Wji(old)αt1Tnetht(i)JWjinetht(i)=Wji(old)αt1Tδht(i)Xt(j)
    整理成矩阵的形式
    W ( n e w ) = W ( o l d ) + α ∑ t = 1 T δ h t X t T W(new)=W(old)+α∑_{t=1}^Tδ_h^tX_t^T W(new)=W(old)+αt=1TδhtXtT
    注意: X t T X_t^T XtT中的T表示转置添加链接描述

    2.5.3 隐藏层到隐藏层的U的更新

    U j i ( n e w ) = U j i ( o l d ) − α ∑ t − 1 T ∂ J ∂ n e t h t ( i ) ∂ n e t h t ( i ) ∂ U j i = U j i ( o l d ) − α ∑ t − 1 T δ h t ( i ) h t − 1 ( j ) U_{ji}(new)=U_{ji}(old)-α∑_{t-1}^{T}\frac{∂J}{∂neth_t(i)}\frac{∂neth_t(i)}{∂U_{ji}}=U_{ji}(old)-α∑_{t-1}^{T}δ_h^t(i)h_{t-1}(j) Uji(new)=Uji(old)αt1Tnetht(i)JUjinetht(i)=Uji(old)αt1Tδht(i)ht1(j)
    整理成矩阵的形式:
    U ( n e w ) = U ( o l d ) + α ∑ t = 1 T δ o t h t − 1 T U(new)=U(old)+α∑_{t=1}^Tδ_o^th_{t-1}^T U(new)=U(old)+αt=1Tδotht1T
    注意: h t − 1 T h_{t-1}^T ht1T中的T表示转置

    3、参考资料

    1. 知乎——RNN前向传播与后向传播公式推导
    展开全文
  • 循环神经网络简介 循环神经网络(recurrent neural network, RNN)源自1982年由Saratha Sathasivam提出的霍普菲尔德网络。霍普菲尔德网络因为实现困难,在提出时并且没有被合适地应用。该网络结构也于1986年后被全...

    循环神经网络简介

    循环神经网络(recurrent neural network, RNN)源自1982年由Saratha Sathasivam提出的霍普菲尔德网络。霍普菲尔德网络因为实现困难,在提出时并且没有被合适地应用。该网络结构也于1986年后被全连接神经网络以及一些传统的机器学习算法所取代。然而:

    • 传统的机器学习算法非常依赖于人工提取的特征,使得基于传统机器学习的图像识别、语音识别以及自然语言处理等问题存在特征提取的瓶颈;
    • 基于全连接神经网络的方法也存在参数太多、无法利用数据中时间序列信息等问题。

    随着更加有效的循环神经网络结构被不断提出,循环神经网络挖掘数据中的时序信息以及语义信息的深度表达能力被充分利用,并在语音识别、语言模型、机器翻译以及时序分析等方面实现了突破。

    1. 原理

    RNN的主要用途是处理和预测序列数据在全连接神经网络或CNN模型中,网络结构都是从输入层到隐含层再到输出层,层与层之间是全连接或部分连接的,但每层之间的节点是无连接的。考虑这样一个问题,如果要预测句子的下一个单词是什么,一般需要用到当前单词以及前面的单词,因为句子中前后单词并不是独立的。比如,当前单词是“很”,前一个单词是“天空”,那么下一个单词很大概率是“蓝”。RNN的来源就是为了刻画一个序列当前的输出与之前信息的关系。从网络结构上,RNN会记忆之前的信息,并利用之前的信息影响后面结点的输出。也就是说,RNN的隐藏层之间的结点是有连接的,隐藏层的输入不仅包括输入层的输出,还包括上一时刻隐藏层的输出。

    下图展示了一个典型的RNN。在每一时刻 t ,RNN会针对该时刻的输入结合当前模型的状态给出一个输出,并更新模型状态。从下图中可以看到,RNN的主体结构 A 的输入除了来自输入\large x_{t},还有一个循环的边来提供上一时刻的隐藏状态(hidden state)\large h_{t-1}。在每一个时刻,RNN的模块A在读取了\large x_{t}\large h_{t-1}之后会生成新的隐藏状态\large h_{t},并产生本时刻的输出\LARGE o_{t},由于模块A中的运算和变量在不同时刻是相同的,因此RNN络理论上可以被看作是同一神经网络结构被无限复制的结果。正如卷积神经网络在不同的空间位置共享参数,循环神经网络是在不同时间位置共享参数,从而能够使用有限的参数处理任意长度的序列。

    将完整的输入输出序列展开,可以得到下图所展示的结构。在图中可以更加清楚地看到RNN在每一个时刻会有一个输入\large x_{t},然后根据RNN前一时刻的状态\large h_{t-1}计算新的状态\large h_{t},并输出\LARGE o_{t}。RNN当前的状态\large h_{t}, 是根据上一时刻的状态\large h_{t-1}和当前的输入\large x_{t}共同决定的。在时刻 t,状态\large h_{t-1}浓缩了前面序列\large x_{0},x_{1},...,x_{t-1}的信息,用于作为输出\LARGE o_{t}的参考。由于序列的长度可以无限延长,维度有限的h状态不可能将序列的全部信息都保存下来,因此模型必须学习只保留与后面任务\large o_{t},o_{t+1},...相关的最重要的信息。

    循环网络的展开在模型训练中有重要意义。从图中可以看到,RNN对长度为N的序列展开之后,可以视为一个有N个中间层的前馈神经网络。这个前馈神经网路没有循环链接,因此可以直接使用反向传播算法进行训练,而不需要任何特别的优化算法。这样的训练方法称为“沿时间反向传播” (Back-Propagation Through Time),是训练循环神经网络最常见的方法。

    2. 应用

    从RNN的结构特征可以很容易看出它最擅长解决与时间序列相关的问题。RNN也是处理这类问题时最自然的神经网络结构。对于一个序列数据,可以将这个序列上不同时刻的数据依次传入RNN的输入层,而输出可以是对序列中下一个时刻的预测,也可以是对当前时刻信息的处理结果(比如语音识别结果)。循环神经网络要求每一个时刻都有一个输入,但是不一定每个时刻都需要有输出。

    以机器翻译为例来介绍RNN是如何解决实际问题的。RNN中每一个时刻的输入为需要翻译的句子中的单词。如图8.3所示,需要翻译的句子为ABCD,那么RNN第一段每一个时刻的输入就分别是A、B、C和D,然后用“_”作为待翻译句子的结束符。在第一段中,循环神经网络没有输出。从结束符“_”开始,循环神经网络进入翻译阶段。该阶段中每一个时刻的输入是上一个时刻的输出(图中虚线所示),而最终得到的输出就是句子ABCD翻译的结果。从图中可以看到句子ABCD对应的翻译结果就是XYZ,当网络输出“_"时翻译结束。

    3. RNN前向传播

    RNN可以看作是同一神经网络结构在时间序列上被复制多次的结果,这个被复制多次的结构被称之为循环体。如何设计循环体的网络结构是循环神经网络解决实际问题的关键。下图展示了一个最简单的循环体结构。这个循环体中只使用了一个类似全连接层的神经网络结构。下面将通过图中所示的神经网络来介绍RNN前向传播的完整流程。

    RNN中的状态是通过一个向量来表示的,这个向量的维度也称为RNN隐藏层的大小,假设其为n。从上图可以看出,循环体中的神经网络的输入有两部分,一部分为上一时刻的状态,另一部分为当前时刻的输入样本。对于时间序列数据来说(比如不同时刻商品的销量),每一时刻的输入样例可以是当前时刻的数值(比如销量值);对于语言模但来说,输入样例可以是当前单词对应的单词向量(word embedding)。

    假设输入向量的维度为x,隐藏状态的维度为n,那么上图循环体的全连接层神经网络的输入大小为n+x。也就是将上一时刻的状态与当前时刻的输入拼接(这里为了简便描述为拼接,实际情况往往是t-1时刻的隐状态和输入分别乘以一个矩阵,详见代码)成一个大的向量作为循环体中神经网络的输入。因为该全连接层的输出为当前时刻的状态,于是输出层的节点个数也为n,循环体中的参数个数为(n+x)∗n+n 个。从图中可以看到,循环体中的神经网络输出不但提供给了下一时刻作为状态,同时也会提供给当前时刻的输出。注意到循环体状态与最终输出的维度通常不同,因此为了将当前时刻的状态转化为最终的输出,RNN还需要另外一个全连接神经网络来完成这个过程。这和CNN中最后的全连接层的意义是一样的类似的,不同时刻用于输出的全连接神经网络中的参数也是一致的。

    4. 前向传播例子

    下图直观的展示了一个RNN前向传播的具体计算过程。

    假设状态地维度为2,输入、输出地维度都为1,而且循环体中地全连接层中的权重为:

    偏置项的大小为\large b_{rnn}=[0.1,−0.1],用于输出的全连接层权重为:

    偏置项的大小为\large b_{output}=0.1。那么在时刻\large t_{0},因为没有上一时刻,所以将状态初始化为\large h_{init}=[0,0],而当前的输入为1,所以拼接得到的向量为[0,0,1],通过循环体中的全连接层神经网络得到的结果为:

    这个结果将作为下一时刻的输入状态,同时RNN也会使用该状态生成输出。将该向盘作为输入提供给用于输出的全连接神经网络可以得到\large t_{0}时刻的最终输出:

    使用\large t_{0}时刻的状态可以类似地推导得出\large t_{1}时刻的状态为[0.860, 0.884],而\large t_{1}时刻的输出为2.73。在得到RNN的前向传播结果之后,可以和其他神经网络类似地定义损失函数。RNN唯一的区别在于因为它每个时刻都有一个输出,所以RNN的总损失为所有时刻(或者部分时刻)上的损失函数的总和。

    以下代码实现了这个简单的循环神经网络前向传播的过程:

    import numpy as np
    
    X = [1,2]
    state = [0.0, 0.0]
    # 分开定义不同输入部分的权重以方便操作
    w_cell_state = np.asarray([[0.1, 0.2], [0.3, 0.4]])
    w_cell_input = np.asarray([0.5, 0.6])
    b_cell = np.asarray([0.1, -0.1])
    
    # 定义用于输出的全连接层参数
    w_output = np.asarray([[1.0], [2.0]])
    b_output = 0.1
    
    # 执行前向传播过程
    for i in range(len(X)):
        before_activation = np.dot(state, w_cell_state) + X[i] * w_cell_input + b_cell
        state = np.tanh(before_activation)
        final_output = np.dot(state, w_output) + b_output
        print("before activation: ", before_activation)
        print("state: ", state)
        print("output: ", final_output)
    before activation:  [0.6 0.5]
    state:  [0.53704957 0.46211716]
    output:  [1.56128388]
    before activation:  [1.2923401  1.39225678]
    state:  [0.85973818 0.88366641]
    output:  [2.72707101]

    RNN(BPTT   Back Propagation Through Time)

    以上情况只是RNN中最简单的情形,它还有许多变种,我们接下来看一个标准的RNN结构,并推导一下它的数学公式

    下图是一个以时间展开的更为具体的结构,【W,V,U】表示顺序与上图表示略有不同

    RNN的几种常见结构

    结构一:


    结构二: 

     


    结构三:


     RNN的一个特点是所有的隐层共享参数(U,V,W),整个网络只用这一套参数。

    RNN前向传导

    上图中左边是RNN模型没有按时间展开的图,如果按时间序列展开,则是上图中的右边部分,我们重点观察右边部分的图,注意区分与之前几幅图的角标的不同,以下讨论都以上图角标为准

    这幅图描述了在序列索引号 t 附近RNN的模型。其中:

    1. \large x^{(t)}代表在序列索引号 t 时训练样本的输入。同样的,\large x^{(t-1)}\large x^{(t+1)}代表在序列索引号 t−1 和 t+1 时训练样本的输入。
    2. \large h^{(t)}代表在序列索引号 t 时模型的隐藏状态。\large h^{(t)}\large x^{(t)}\large h^{(t-1)}共同决定。
    3. \large o^{(t)}代表在序列索引号 t 时模型的输出。\large o^{(t)}只由模型当前的隐藏状态\large h^{(t)}决定。
    4. \large L^{(t)}代表在序列索引号 t 时模型的损失函数。
    5. \large y^{(t)}代表在序列索引号 t 时训练样本序列的真实输出。
    6. \large U,W,V这三个矩阵是我们的模型的线性关系参数,它在整个RNN网络中是共享的。 也正因为是共享了,它体现了RNN的模型的“循环反馈”的思想。  

    有了上面的模型,RNN的前向传播算法就很容易得到了。

    对于任意一个序列时刻 t ,我们隐藏状态\large h^{(t)}\large x^{(t)}\large h^{(t-1)}得到:

                                                                      \large h^{(t)}=\sigma (z^{(t)})=\sigma (Ux^{(t)}+Wh^{(t)}+b)

    其中 σ 为RNN的激活函数,一般为tanh, b为偏置项。

    序列时刻 t ,模型的输出o(t)的表达式比较简单:

                                                                                      \large O^{(t)}=Vh^{(t)}+c

    最终在序列时刻 t 时我们的预测输出为:

                                                                                         \large \widehat{y}^{(t)}=\sigma (o^{(t)})

    通常由于RNN是识别类的分类模型,所以上面这个激活函数一般是softmax。

    通过损失函数\large L^{(t)},比如对数似然损失函数、交叉熵损失函数,我们可以量化模型在当前位置的损失,即\large \widehat{y}^{(t)}\large y^{(t)}的差距。

    反向传播算法推导

    有了RNN前向传播算法的基础,就容易推导出RNN反向传播算法的流程了。通过梯度下降法一轮轮的迭代,得到合适的RNN模型参数 U,W,V,b,c 。由于我们是基于时间反向传播,所以RNN的反向传播有时也叫做BPTT(back-propagation through time)。当然这里的BPTT和DNN也有很大的不同点,即这里所有的 U,W,V,b,c 在序列的各个位置是共享的,反向传播时我们更新的是相同的参数。

    为了简化描述,这里的损失函数我们为交叉熵损失函数,输出的激活函数为softmax函数,隐藏层的激活函数为tanh函数。

    对于RNN,由于我们在序列的每个位置都有损失函数,因此最终的损失L为:

                                                                                          \large L=\sum_{t=1}^{\tau }L^{(t)}

    其中,\large \tau为序列的总时间步

    接下来对V,c求梯度,V,c 的梯度计算比较简单

                                                              \large \frac{\partial L}{\partial c}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial c}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial o^{(t)}}\frac{\partial o^{(t)}}{\partial c}=\sum _{t=1}^{\tau}\widehat{y}^{(t)}-y^{(t)}

                                                      \large \frac{\partial L}{\partial V}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial V}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial o^{(t)}}\frac{\partial o^{(t)}}{\partial V}=\sum _{t=1}^{\tau}(\widehat{y}^{(t)}-y^{(t)})(h^{(t)})^{T}

    但是W,U,b的梯度计算就比较的复杂了。从RNN的模型可以看出,在反向传播时,在某一序列位置 t 的梯度损失由当前位置的输出对应的梯度损失和序列索引位置 t+1 时的梯度损失两部分共同决定。对于 W 在某一序列位置 t 的梯度损失需要反向传播一步步的计算。我们定义序列索引 t 位置的隐藏状态的梯度为: 

                                                                                           \large \delta ^{(t)}=\frac{\partial L}{\partial h^{(t)}}

                            \large \begin{aligned} \delta ^{(t)}=\frac{\partial L}{\partial o^{(t)}}\frac{\partial o^{(t)}}{\partial h^{(t)}}+\frac{\partial L}{\partial h^{(t+1)}}\frac{\partial h^{(t+1)}}{\partial h^{(t)}}=V^{T}(\widehat{y}^{(t)}-y^{(t)})+W^{T}\delta ^{(t+1)}diag(1-(h^{(t+1)})^{2})\end{aligned}

    这样我们就可以根据\large \delta ^{(t+1)}递推\large \delta ^{(t)}

    对于\large \delta ^{(\tau)},由于它的后面没有其他的序列索引了,因此有:

                                                                      \large \delta ^{(\tau)}=\frac{\partial L}{\partial o^{(\tau)}}\frac{\partial o^{(\tau)}}{\partial h^{(t)}}=V^{T}(\widehat{y}^{(\tau)}-y^{(\tau)})

    有了\large \delta ^{(t)},计算W,U,b就容易了,这里给出W,U,b的梯度计算表达式:

                                                    \large \frac{\partial L}{\partial W}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial h^{(t)}}\frac{\partial h^{(t)}}{\partial W}=\sum _{t=1}^{\tau}diag(1-(h^{(t)})^{2})\delta ^{(t)}(h^{(t-1)})^{T}

                                                        \large \frac{\partial L}{\partial U}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial h^{(t)}}\frac{\partial h^{(t)}}{\partial U}=\sum _{t=1}^{\tau}diag(1-(h^{(t)})^{2})\delta ^{(t)}(x^{(t)})^{T}

                                                            \large \frac{\partial L}{\partial b}=\sum _{t=1}^{\tau}\frac{\partial L^{(t)}}{\partial h^{(t)}}\frac{\partial h^{(t)}}{\partial b}=\sum _{t=1}^{\tau}diag(1-(h^{(t)})^{2})\delta ^{(t)}

    根据RNN模型会有些不同,自然前向反向传播的公式会有些不一样,但是原理基本类似。

    需要特别指出的是,理论上RNN可以支持任意长度的序列,然而在实际训练过程中,如果序列过长:

    • 一方面会导致优化时出现梯度消散和梯度爆炸的问题;
    • 另一方面,展开后的前馈神经网络会占用过大的内存

    所以实际中一般会规定一个最大长度,当序列长度超过规定长度之后会对序列进行截断。

    展开全文
  • 【八问八答】循环神经网络

    千次阅读 2022-04-16 15:22:39
    1)延时神经网络 一种简单的利用历史信息的方法是建立一个额外的延时单元,用来存储网络 的历史信息(可以包括输入、输出、隐状态等). 比较有代表性的模型是延时神 经网络(Time Delay Neural Network,TDNN) ...
  • 主流的循环神经网络就是以RNN为基础的各种变体模型 人工神经网络: 卷积神经网络: 循环神经网络: 三种基本类型总览: RNN: 每个序列索引位置t都有一个隐藏状态h(t)。 进一步简化: ...
  • 发明专利说明书。本发明公开了提供基于时空图的发散卷积 循环神经网络的交通流预测方法,基于交通网络 的空间特征构建了路网的有向加权图,接着以该 有向加权图为预测的基本单位
  • 文章目录循环神经网络门控循环单元(GRU)门控循环单元重置门和更新门候选隐藏状态隐藏状态输出结果长短期记忆(LSTM)输入门、遗忘门和输出门候选记忆细胞记忆细胞隐藏状态输出结果深度循环神经网络双向循环神经...
  • 循环神经网络

    2020-04-10 18:55:51
    基本循环神经网络 下图是一个简单的循环神经网络如,它由输入层、一个隐藏层和一个...我们可以用下面的公式来表示循环神经网络的计算方法: 式1是输出层的计算公式,输出层是一个全连接层,也就是它的每个节点...
  • 深度学习——循环神经网络GRU公式推导 0、注意 在整篇的文章中,无论是输入的X向量,还是隐藏层得到的S向量,这些都是列向量 1、从RNN到GRU 在之前的文章中,我们具体推导了循环神经网络RNN的前向和反向传播过程,...
  • 二、循环神经网络(RNN与LSTM)

    千次阅读 2021-12-05 14:57:09
    一、NLP基础 1、常用的神经网络模型 在做深度学习或者是人工智能相关的任务中。...1.1 卷积神经网络(Convolutional Neural Network,CNN) 是一种前馈神经网络, 它包括卷积层(convolutional layer) 和池化层(poo
  • 通俗理解RNN循环神经网络原理

    千次阅读 2021-06-01 16:52:05
    1、RNN的简单介绍        我们前面提到的无论是人工神经网络还是CNN卷积神经网络,他们的前提都是:元素之间是相互独立的,...因此,我们就需要使用循环神经网络了,他的本质是:像
  • 时序模型:循环神经网络(RNN)

    千次阅读 2022-02-20 16:05:26
    1. 循环神经网络(RNN)定义 循环神经网络(recurrent neural network, RNN)是一类专门设计处理不定长序列数据的神经网络。 与使用一种新计算1作为核心的卷积神经网络不同,循环神经网络仍使用特征的线性组合作为...
  • 1、循环神经网络(Recurrent Neural Networks) 2、长依赖存在的问题 3、LSTM 网络 4、LSTMs的核心思想 5、一步一步理解LSTM 6、LSTM的变种 7、总结 1、循环神经网络(Recurrent Neural Networks) 人对一个...
  • 深度学习-循环神经网络TensorFlow循环神经网络结构长短时记忆网络(LSTM)结构TensorFlow实现LSTM双向循环神经网络TensorFlow实现BiLSTM深层循环神经网络TensorFlow实现多层LSTM 循环神经网络结构 下图是一个典型的...
  • 循环神经网络 RNN为语言模型来建模,语言模型就是:给定一个一句话前面的部分,预测接下来最有可能的一个词是什么。 RNN理论上可以往前看(往后看)任意多个词。 2. RNN结构 2.1 最基本的结构: xt&#x...
  • 《深度学习》之 循环神经网络 原理 超详解

    万次阅读 多人点赞 2020-03-20 13:28:26
    循环神经网络 一.研究背景 1933年,西班牙神经生物学家Rafael Lorente de Nó发现大脑皮层(cerebral cortex)的解剖结构允许刺激在神经回路中循环传递,并由此提出反响回路假设(reverberating circuit hypothesis...
  • 长短时记忆网络(Long Short Term Memory Network, LSTM),它有效地解决了原始循环神经网络(RNN)的缺陷,在语音识别、图片描述、自然语言处理等许多领域中成功应用。本文讲解由三个Gate(input、forget、output)和一...
  • 常见的五种神经网络系列第三篇,主要介绍循环神经网络,由于循环神经网络包含的内容过多,分位上下两篇进行介绍,本文主要是循环神经网络(上)篇,主要介绍以下内容: 循环神经网络概述 如何给神经网络增加记忆...
  • 循环神经网络RNN

    千次阅读 2022-02-17 14:26:51
    RNN(Recurrent Neural Network)循环神经网络。 类比血液在体内循环,从过去一直被更新到现在。 RNN具有环路。这个环路可以使数据不断循环。通过数据的循环,RNN一边记住过去的数据,一边更新到最新的数据。 RNN层...
  • 循环神经网络(RNN)

    千次阅读 2022-04-29 23:35:41
    循环神经网络(RNN) 文章目录循环神经网络(RNN)注意!!!!!!!RNN模型的作用为什么要使用RNN而不是用MLP?RNN输入与输出RNN模型简单RNN模型LSTM(Long Short-Term Memory)长短期记忆模型GRU(Gated Recurrent Units...
  • 循环神经网络解决文本分类问题

    千次阅读 2019-09-19 11:30:10
    1.1、循环神经网络 循环神经网络(Recurrent Neural Network, RNN)是一类以序列数据为输入,在序列的演进方向进行递归且所有节点(循环单元)按链式连接的递归神经网络。 卷积网络的输入只有输入数据X,而循环...
  • 常见的五种神经网络系列第三种,主要介绍循环神经网络,分位上中下三篇进行介绍,本文主为(中)篇,涉及内容如下: 循环神经网络中的参数学习 RNN中的长期依赖问题 常见的循环神经网络结构 该系列的其他文章: ...
  • 循环神经网络基础介绍

    千次阅读 2018-10-08 14:19:44
    在应用循环神经网络的过程中,还是会有些地方疑惑,所以还是要回归下问题的本质。学而不思则惘,思而不学则怠。。 1. 循环神经网路简介 首先循环神经网络的主要用途是处理和预测序列数据。在之前的全链接神经网络...
  • 文章目录门控循环神经网络GRU长短期记忆LSTM深度循环神经网络双向循环神经网络 门控循环神经网络GRU 该网络的提出也同样是为了应对普通RNN的梯度问题 基本原理看这一篇就能懂:转载自知乎 简单来说,GRU就是通过一个...
  • 深度学习中的循环神经网络LSTM详解

    千次阅读 2019-09-07 21:17:43
    (一)、什么是循环神经网络LSTM? LSTM指的是长短期记忆网络(Long Short Term Memory),它是循环神经网络的最知名和成功的扩展。由于循环神经网络有梯度消失和梯度爆炸的问题,学习能力有限,在实际任务中的效果很...
  • 但是在很多现实的任务中,网络的输出不仅和当前的输入有关还和之前的输入(当前的状态),甚至是以后的输入有关, 另外前馈神经网络难以处理时序数据,如视频、语音、文本,这类都是一些不固定长度的数据, 而前馈...
  • Lstm(循环神经网络)

    2022-02-18 15:18:55
    算法模型Lstm(循环神经网络):
  • 循环神经网络(RNN)

    千次阅读 2021-02-20 09:36:10
    对于人类而言,以前见过的事物会在脑海中留下记忆...所以接下来要介绍一种在序列问题和自然语言处理等领域取得很大成功的模型——循环神经网络。 一. 循环神经网络(RNN) 具体来讲,卷积神经网络相当于人类的视觉,但
  • 循环神经网络(RNN)简介

    万次阅读 多人点赞 2018-09-01 17:05:51
    人工神经网络介绍参考: https://blog.csdn.net/fengbingchun/article/details/50274471  ... 这里在以上两篇基础上整理介绍循环神经网络: 前馈网络可以分为若干”层”,各层按信号传输先后顺序依次排列...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 22,940
精华内容 9,176
关键字:

循环神经网络公式