深度学习(九)-循环神经网络

  前面我们学习了全连接神经网络、卷积神经网络,这些网络的传递都是单向,元素之间相互独立,输入与输出也是毫无关系,这样虽然让神经网络容易学习,但是一定程度上却弱化了神经网络的能力。而我们这一章要介绍的循环神经网络,就是在一些方面对前馈神经网络的一种补充。
  在实际生活中,很多元素都是相互联系的,比如一个人说了:我喜欢《黎明前的黑暗》,请帮我放一下___ ,大家都知道是这里应该补充《黎明前的黑暗》。因为我们自己很容易根据上下文的内容判断,但机器并不知道啊,想做到这一步就非常难了。因此,就有了循环神经网络,他的本质是:像人一样拥有记忆的能力。
  循环神经网络( R N N RNN RNN)是一种具有短期记忆能力的神经网络。在循环神经网络中,神经元不但可以接受其它神经元的信息,也可以接受自身的信息,形成具有环路的网络结构,也就是说它不仅依赖当前特征,而且也比较依赖之前的输入特征来推断后面的结果。循环神经网络经常使用在自然语言处理(语言建模、文本生成)、机器翻译、语音识别、生成图像描述、视频标记、推荐等实际情况中。
  循环神经网络的基本结构特别简单,就是将网络的输出保存在一个记忆单元中,这个记忆单元和下一次的输入一起进入神经网络中 。下图左边为一个简单的循环神经网络结构,右边为其展开:

  但是有时候,比如说语音信号,需要前后的信息来预测,这个时候并不需要创建两个不同方向的单向网络结构,可以直接使用一个双向的循环网络结构来完成任务,网络会从序列的正方向读取数据,再从反方向读取数据,最后将网络输出的两种结果合在一起形成网络的最终输出结果。
  但是记忆有很大的遗忘性,对于短时间的信息, R N N RNN RNN 可以很好的的预测近期的信息,如果时间比较久,记忆信息跟预测的位置之间比较远,那么网络也无法准确记住这些信息,比如说:在一次谈话中,开始我就说比较喜欢听《黎明前的黑暗》,中间又跟别人聊了很久其他信息,那么最后希望放一下《黎明前的黑暗》,这时网络就没办法很好的预测出来。

  针对上面的情况,提出了循环神经网络的变形: L S T M LSTM LSTM G R U GRU GRU

LSTM

   L S T M ( L o n g S h o r t T e r m M e m o r y ) LSTM (Long Short Term Memory) LSTM(LongShortTermMemory) 又称为长短期记忆网络,是目前使用最多的时间序列算法。它相对于简单的 R N N RNN RNN 引入了门来控制信息的传递,共引入输入门、遗忘门、输出门三个门,输入门控制着网络的输入,遗忘门控制着记忆单元,输出门控制着网络的输出 ,其中遗忘门的作用就是决定之前的哪些记忆被保留,哪些记忆被抹掉,由于遗忘门,使得 L S T M LSTM LSTM 具有长时记忆的功能,对于给定的任务,遗忘门能够自己学习保留多少以前的记忆,这使得不再需要人为干扰,网络就能够自主学习。
  所有 R N N RNN RNN 都具有一种重复神经网络模块的链式的形式。在标准的 R N N RNN RNN 中,这个重复的模块只有一个非常简单的结构,可以为 t a n h tanh tanh,也可以为 R e L U ReLU ReLU,结构如下图所示:

   L S T M LSTM LSTM 同样是这样的结构,但是隐藏单元的结构更加复杂,它引入一个新的内部状态 c t c_t ct 专门进行线性的循环信息传递,同时输出信息给隐藏层的外部状态 h t h_t ht。结构如下所示:

  从上图中可以看出,在每个序列索引位置 t t t 时刻向前传播的除了和 R N N RNN RNN 一样的隐藏状态 h t h_t ht ,还多了另一个隐藏状态,如下图中上面的长横线。这个隐藏状态我们一般称为细胞状态,记为 C t C_t Ct。如下图所示:

  细胞状态类似于传送带。直接在整个链上运行,只有一些少量的线性交互。信息在上面传输很容易保持不变。

遗忘门

  遗忘门的作用是决定丢弃什么信息,其结构与数学表示如下:

f t = δ ( W f [ h t − 1 , x t ] + b f ) {{\text{f}}_t} = \delta ({W_f}[{h_{t - 1}},{x_t}] + {b_f}) ft=δ(Wf[ht1,xt]+bf)
   h t − 1 {h_{t - 1}} ht1 表示上一时刻信息, x t x_t xt 表示当前输入的新信息, f t {{\text{f}}_t} ft 为一个在 0 0 0~ 1 1 1 之间的数值, 0 0 0 表示完全舍弃, 1 1 1 表示全部保留。

输入门

  输入门的作用是确定什么样的新信息被存放在细胞状态中。

  数学表达式表示为:
i t = δ ( W t [ h t − 1 , x t ] + b i ) {i_t} = \delta ({W_t}[{h_{t - 1}},{x_t}] + {b_i}) it=δ(Wt[ht1,xt]+bi)

C ~ t = tanh ⁡ ( W C [ h t − 1 , x t ] + b C ) {\widetilde C_t} = \tanh ({W_C}[{h_{t - 1}},{x_t}] + {b_C}) C t=tanh(WC[ht1,xt]+bC)
   i t {i_t} it 为当前信息的衰减系数,用来决定更新什么值, C ~ t {\widetilde C_t} C t 为当前学习到的信息。有了这两个条件,我们就可以更新当前信息:

C t = f t ∗ C t − 1 + i t ∗ C t ~ {C_t} = {f_t}*{C_{t - 1}} + {i_t}*\widetilde {{C_t}} Ct=ftCt1+itCt
  首先把旧状态 C t − 1 {C_{t - 1}} Ct1 与 衰减 f ( t ) f(t) f(t) 相乘,丢掉确认需要丢弃的信息,然后加上衰减 i t {i_t} it 乘以当前时候学习到的信息 C t ~ \widetilde {{C_t}} Ct ,这样便得到了 t t t 时刻下的更新信息 C t C_t Ct

输出门

  当前时刻 t t t 的网络输出 h t h_t ht 取决于当前时刻 t t t 的记忆状态 C t C_t Ct t t t 时刻的输入 x t x_t xt t − 1 t-1 t1 时刻的输出 h t − 1 h_{t-1} ht1

o t = δ ( W o [ h t − 1 , x t ] + b o ) {o_t} = \delta ({W_o}[{h_{t - 1}},{x_t}] + {b_o}) ot=δ(Wo[ht1,xt]+bo)

h t = o t ∗ tanh ⁡ ( C t ) {h_t} = {o_t}*\tanh ({C_t}) ht=ottanh(Ct)

  首先使用类似于计算记忆衰减系数的方法计算得到输出门的系数 o t o_t ot, 这个系数决定了输出的信息,最后得到网络输出 h t {h_t} ht

GRU

   G R U GRU GRU L S T M LSTM LSTM 最大的不同在于 G R U GRU GRU 将遗忘门和输入门合成新的更新门,同时网络不再额外给出记忆状态 C t C_t Ct,而是将输出结果作为记忆状态不断向后循环传递,网络的输人和输出都变得特别简单。其网络结构如下图所示:

z t = o t ( W z [ h t − 1 , x t ] ) {z_t} = {o_t}({W_z}[{h_{t - 1}},{x_t}]) zt=ot(Wz[ht1,xt])

r t = o t ( W z [ h t − 1 , x t ] ) {r_t} = {o_t}({W_z}[{h_{t - 1}},{x_t}]) rt=ot(Wz[ht1,xt])

h ~ t = tanh ⁡ ( W [ r t ∗ h t − 1 , x t ] ) {\widetilde h_t} = \tanh ({W_{}}[{r_t}*{h_{t - 1}},{x_t}]) h t=tanh(W[rtht1,xt])

h t = ( 1 − z t ) ∗ h t − 1 + z t ∗ h t ~ {h_t} = (1 - {z_t})*{h_{t - 1}} + {z_t}*\widetilde {{h_t}} ht=(1zt)ht1+ztht
  其中, r t {r_t} rt 表示重置门, z t {z_t} zt 表示更新门。重置门决定是否将之前的状态忘记,相当于合并了 L S T M LSTM LSTM 中的遗忘门和输入门。当 r t {r_t} rt ​趋于 0 0 0 的时候,前一个时刻的状态信息 h t − 1 {h_{t - 1}} ht1 会被忘掉,隐藏状态 h ~ t {\widetilde h_t} h t ​会被重置为当前输入的信息。更新门决定是否要将隐藏状态更新为新的状态 h ~ t {\widetilde h_t} h t

总结

   L S T M LSTM LSTM 网络是目前为止最成功的循环神经网络模型,成功应用在很多领域,比如语音识别、机器翻译、语音模型以及文本生成。 L S T M LSTM LSTM 网络通过引入线性连接来缓解长距离依赖问题。虽然 L S T M LSTM LSTM 网络取得了很大的成功,其结构的合理性一直受到广泛关注。人们不断有尝试对其进行改进来寻找最优结构,比如减少门的数量、提高并行能力等。
   G R U GRU GRU L S T M LSTM LSTM 的一种变体,两者的性能在很多任务上基本没有区别,不同的是 G R U GRU GRU 参数相对较少更容易收敛,但是在数据集较大的情况下, L S T M LSTM LSTM 性能更好。

pytorch API

标准RNN

   n n . R N N ( i n p u t _ s i z e , h i d d e n _ s i z e , n u m _ l a y e r s , n o n l i n e a r i t y , b i a s , b a t c h _ f i r s t , d r o p o u t , b i d i r e c t i o n a l ) nn.RNN(input\_size, hidden\_size, num\_layers, nonlinearity, bias, batch\_first, dropout, bidirectional) nn.RNN(input_size,hidden_size,num_layers,nonlinearity,bias,batch_first,dropout,bidirectional)
  参数解释:
     i n p u t _ s i z e input\_size input_size:输入的特征维度
     h i d d e n _ s i z e hidden\_size hidden_size:输出的特征维度
     n u m _ l a y e r s num\_layers num_layers:网络的层数
     n o n l i n e a r i t y nonlinearity nonlinearity:非线性激活函数,默认是 t a n h tanh tanh
     b i a s bias bias:是否使用偏置,默认使用
     b a t c h _ f i r s t batch\_first batch_first:输入数据的形式,默认是 F a l s e False False,即 ( s e q , b a t c h , f e a t u r e ) (seq, batch, feature) (seq,batch,feature) T r u e True True ( b a t c h , s e q , f e a t u r e ) (batch, seq, feature) (batch,seq,feature)
     d r o p o u t dropout dropout:是否在输出层应用 dropout
     b i d i r e c t i o n a l bidirectional bidirectional:是否使用双向的 r n n rnn rnn,默认是 F a l s e False False 为单向

  输入 ( i n p u t , h 0 ​ ) (input, h_0​) (input,h0)
     i n p u t input input ​ [ s e q , b a t c h _ s i z e , i n p u t _ s i z e ] ​[seq, batch\_size, input\_size] [seq,batch_size,input_size]
     h 0 h_0 h0 [ n u m _ l a y e r s ∗ d i r e c t i o n , b a t c h _ s i z e , h i d d e n _ s i z e ] [num\_layers*direction, batch\_size, hidden\_size] [num_layersdirection,batch_size,hidden_size]

  输出 ( o u t p u t , h n ) (output, h_n) (output,hn)
     h n h_n hn ​ [ n u m _ l a y e r s ∗ d i r e c t i o n , b a t c h _ s i z e , h i d d e n _ s i z e ] ​[num\_layers*direction,batch\_size, hidden\_size] [num_layersdirectionbatch_size,hidden_size]
     o u t p u t output output [ s e q , b a t c h _ s i z e , h i d d e n _ s i z e ∗ d i r e c t i o n ] [seq, batch\_size, hidden\_size*direction] [seq,batch_size,hidden_sizedirection]

LSTM

   n n . L S T M ( i n p u t _ s i z e , h i d d e n _ s i z e , l a y e r _ n u m . . . ) nn.LSTM(input\_size, hidden\_size, layer\_num ...) nn.LSTM(input_size,hidden_size,layer_num...), 后面参数与标准 R N N RNN RNN 相同,这里就不介绍了。

  输入 ( i n p u t , ( h 0 , c 0 ) ​ ) (input, (h_0, c_0)​) (input,(h0,c0))
     i n p u t input input ​ [ s e q , b a t c h _ s i z e , i n p u t _ s i z e ] ​[seq, batch\_size, input\_size] [seq,batch_size,input_size]
     ( h 0 , c 0 ) ​ (h_0, c_0)​ (h0,c0) [ n u m _ l a y e r s ∗ d i r e c t i o n , b a t c h _ s i z e , h i d d e n _ s i z e ] [num\_layers*direction, batch\_size, hidden\_size] [num_layersdirection,batch_size,hidden_size]

  输出 ( o u t p u t , ( h n , c n ) ) (output, (h_n, c_n)) (output,(hn,cn))
     o u t p u t output output [ s e q , b a t c h _ s i z e , h i d d e n _ d i m ∗ d i r e c t i o n ] [seq, batch\_size, hidden\_dim*direction] [seq,batch_size,hidden_dimdirection]
     ( h n , c n ) (h_n, c_n) (hn,cn) ​ [ n u m _ l a y e r s ∗ d i r e c t i o n , b a t c h _ s i z e , h i d d e n _ s i z e ] ​[num\_layers*direction,batch\_size, hidden\_size] [num_layersdirectionbatch_size,hidden_size]

GRU

   n n . G R U ( i n p u t _ d i m , h i d d e n _ s i z e , l a y e r _ n u m . . . ) nn.GRU(input\_dim, hidden\_size, layer\_num...) nn.GRU(input_dim,hidden_size,layer_num...)
  参数解释:
     i n p u t _ s i z e input\_size input_size:输入的特征维度
     h i d d e n _ s i z e hidden\_size hidden_size:输出的特征维度
     n u m _ l a y e r s num\_layers num_layers:网络的层数

  输入 ( i n p u t , ( h 0 , c 0 ) ​ ) (input, (h_0, c_0)​) (input,(h0,c0))
     i n p u t input input ​ [ s e q , b a t c h _ s i z e , i n p u t _ s i z e ] ​[seq, batch\_size, input\_size] [seq,batch_size,input_size]
     ( h 0 , c 0 ) ​ (h_0, c_0)​ (h0,c0) [ n u m _ l a y e r s ∗ d i r e c t i o n , b a t c h _ s i z e , h i d d e n _ s i z e ] [num\_layers*direction, batch\_size, hidden\_size] [num_layersdirection,batch_size,hidden_size]

  输出 ( o u t p u t , ( h n , c n ) ) (output, (h_n, c_n)) (output,(hn,cn))
     o u t p u t output output [ s e q , b a t c h _ s i z e , h i d d e n _ s i z e ∗ d i r e c t i o n ] [seq, batch\_size, hidden\_size*direction] [seq,batch_size,hidden_sizedirection]
     ( h n , c n ) (h_n, c_n) (hn,cn) ​ [ n u m _ l a y e r s ∗ d i r e c t i o n , b a t c h _ s i z e , h i d d e n _ s i z e ] ​[num\_layers*direction,batch\_size, hidden\_size] [num_layersdirectionbatch_size,hidden_size]

参考

  1. RNN, LSTM 理解
  2. 廖星宇:《深度学习之pytorch》
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值