美文网首页鱼的深度学习
深度学习(八)循环神经网络RNN

深度学习(八)循环神经网络RNN

作者: 升不上三段的大鱼 | 来源:发表于2020-08-05 23:54 被阅读0次

    之前所提到的神经网络,处理的都是一个输入对应一个输出的情况,比如一张图片有一种分类,但是还存着一些与时间相关的信号,比如音乐、视频、传感器数据等。对于这样的输入,时间上的顺序十分重要。我们可以选择把整个时序塞进一个大的神经网络作为输入,但是这样的处理会导致网络很难训练,而且不能做到实时输出(比如说翻译),而循环神经网络就很好的解决了这个问题。

    1. 简单的循环神经网络

    在这篇利用Keras搭建LSTM循环神经网络里介绍了简单的循环神经网络的结构。
    循环神经网络通过 hidden state来储存上一个输入对当前输出的影响,从而有了处理时序关系的能力。

    隐藏状态: h_t = tanh(W_hh * h_{t-1} + W_xh *x_t+b_h)
    输出: y_t = \sigma(o_t)=\sigma(W_hy *h_t + b_y)

    Basic RNN unfolded

    反向传播 Backpropagation through Time (BPTT)
    训练RNN的过程包括在前向中计算整个序列并得到loss,在反向中计算整个序列的梯度并更新权重值。
    需要计算的梯度值如下:
    \nabla o_t = \sigma'(o_t) \cdot \frac{\partial L}{\partial \hat{y_t} }(\hat{y_t}, y_t)
    \nabla W_{hy,t}= \nabla o_t h_t^T
    \nabla b_{y,t}=\nabla o_t
    \nabla h_t = (\frac{\partial h_{t+1}}{\partial h_t})^T \nabla h_{t+1}+(\frac{\partial o_t}{\partial h_t})^T \nabla o_t
    =W_{hh}^T \cdot tanh'(W_{hh}h_t+W_{xh}X_{t+1}+b_h) \cdot \nabla h_{t+1} + W_{hy}^T \nabla o_t
    \nabla W_{hh,t} = \nabla h_t \cdot tanh'(\mu_{t}) \cdot h_{t-1}^T
    \nabla W_{xh,t} = \nabla h_t \cdot tanh'(u_t) \cdot x_t^T
    \nabla b_{h,t} = \nabla h_t \cdot tanh'(u_t)
    可以看到梯度都与时间t有关,对于每个梯度,需要把所有时间上的值加起来。
    RNN存在的问题是不能很好地处理长时间的依赖关系,在每一个时间点上隐藏状态都会被覆盖;并且容易出现梯度爆炸和梯度消失(因为累乘)。

    1. LSTM, Long Short-Term Memory Units

    LSTM解决了梯度消失的问题以及学会了长时程的依赖,主要思想是使用门来控制记忆的读写。
    LSTM的单元包括:

    • 输入x
    • 隐藏状态 hidden stateh_{t_1} / h_t
    • 单元状态 cell stateC_{t-1}/C_t
    • 输出 y_t

    需要迭代的状态有:

    • 遗忘门:忘记单元状态里的旧信息
    • 输入门:决定单元信息的输入
    • 计算更新单元信息
    • 计算隐藏状态

    单元状态 C_t是时间点t的单元状态, 只会发生线性变换,没有激活函数,可以在多个时间点之后保持不变。

    cell state

    遗忘门:忘记旧信息。主要思想是在不同的步骤里忘记和记忆信息。f_t控制前一个单元状态是否被遗忘:f_t = \sigma(W_f \cdot [h_{t-1}, x_t]+b_f)

    forget gate

    输入门:决定新的输入。
    i_t = \sigma(W_i \cdot [h_{t-1}, x_t]+b_i)
    \tilde{C}_t = tanh(W_c \cdot [h_{t-1}, x_t]+b_C)

    input gate

    更新单元状态:新的单元状态C_{t-1} 是前一个时间剩下的单元状态,隐藏状态与新输入的信息之和。
    C_t = f_t \cdot C_{t-1}+i_t \cdot \tilde{C}_t
    这里是线性的关系,单元状态是可以保持不变的,f_t如果取值为1, i_t为0

    update unit state

    更新隐藏状态与输出:从结构图中可以看到隐藏状态和单元状态是两条不同的通路,而输出与隐藏状态有关。
    o_t = \sigma(W_{\sigma}[h_{t-1}, x_t]+b_o)
    h_t = o_t \cdot tanh(C_t)
    y_t = \sigma(h_t)

    hidden state and output
    1. GRU, Gated Recurrent Units

    LSTM的缺点是参数太多,很难训练,GRU作为LSTM的变体,结构更加简单,参数数量更少。


    GRU

    最主要的区别是没有多余的单元状态,记忆的操作只通过隐藏状态实现。
    隐藏状态的更新包括:

    • 重置门:上一个时间的隐藏状态的影响
    • 更新门:新算出来的更新的影响
    • 建议更新隐藏状态
    • 计算更新的隐藏状态

    重置门:r_t = \sigma(W_r \cdot [h_{t-1},x_t]+b_r)

    reset gate

    更新门:z_t = \sigma(W_z \cdot [h_{t-1}, x_t]+b_z)

    update gate

    隐藏状态更新:把输入和重置的隐藏状态结合在一起,r_t如果接近0,说明以前的隐藏状态影响很小。
    \tilde{h}_t = tanh(W_h \cdot [r_t \cdot h_{t-1}, x_t] + b_n)

    proposing an update

    更新的隐藏状态是旧状态与建议更新的结合,h_t = (1-z_t) \cdot h_{t-1}+z_t \cdot \tilde{h}^T
    \hat{y}_t = \sigma(h_t)

    update hidden state
    学习短期的关系时限制重置门, r_t接近0,忽略以前的隐藏状态;学习长期的关系时限制更新门,z_t接近0,忽略输入。
    1. 简单RNN, LSTM 与GRU的比较

    简单RNN在训练中会遇到梯度爆炸/消失的问题,由于指数减小的梯度短期依赖关系隐藏了长期依赖关系,隐藏状态在每个时间步中都被覆盖。对此LSTM和改进版的GRU被提了出来。

    LSTM和GRU的相似之处在于都使用了门来控制信息流,能够得到不同时间尺度上的依赖关系,反向传播过程中都有加法计算保持误差。

    不同之处在于LSTM将隐藏状态和单元状态分开处理,而GRU将二者合在了一起。LSTM通过输出门控制记忆内容,新的记忆内容独立于当前存储的记忆;而GRU存内容的完全无需控制,新的记忆内容取决于当前记忆。

    参考:
    [1] Long short-term memory
    [2] Learning the Long-Term Structure of the Blues
    [3] Learning phrase representations using RNN encoder-decoder for statistical machine translation

    相关文章

      网友评论

        本文标题:深度学习(八)循环神经网络RNN

        本文链接:https://www.haomeiwen.com/subject/imkarktx.html