社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

【深度学习】基础知识--循环神经网络 RNN(下)

机器学习初学者 • 3 年前 • 611 次点击  
作者:华校专

作者信息:

华校专,曾任阿里巴巴资深算法工程师、智易科技首席算法研究员,现任腾讯高级研究员,《Python 大战机器学习》的作者。

编者按:

算法工程师必备系列更新啦!继上次推出了算法工程师必备的数学基础后,小编继续整理了必要的机器学习知识,全部以干货的内容呈现,哪里不会学哪里,老板再也不用担心你的基础问题!

注意:【深度学习】基础知识--循环神经网络 RNN(上)

四、常见 RNN 变种

4.1 双向 RNN

  1. 前面介绍的RNN 网络隐含了一个假设:时刻 t 的状态只能由过去的输入序列 ,以及当前的输入 来决定。

    实际应用中,网络输出 可能依赖于整个输入序列。如:语音识别任务中,当前语音对应的单词不仅取决于前面的单词,也取决于后面的单词。因为词与词之间存在语义依赖。

    双向 RNN 就是为了解决这种双向依赖问题,它在需要双向信息的应用中非常成功。如:手写识别、语音识别等。

  2. 典型的双向 RNN 具有两条子RNN

  • 代表通过时间向未来移动的子 RNN的状态,向右传播信息; 代表通过时间向过去移动的子 RNN 的状态,向左传播信息。

  • t 时刻的输出 同时依赖于过去、未来、以及时刻 t 的输入

  • 模型的数学表示:

  • 单个样本的损失:

  • 更新方程:其中输入到隐状态的权重为 ,隐状态到输出的权重为 ,隐状态到隐状态的权重为 为输入偏置向量和输出偏置向量。





  • 如果输入是 2 维的(如图像),则双向 RNN 可以扩展到4个方向:上、下、左、右。

    每个子 RNN 负责一个时间移动方向,t 时刻的输出 同时依赖于四个方向、以及时刻 t 的输入

    CNN 相比:

    • RNN 可以捕捉到大多数局部信息,还可以捕捉到依赖于远处的信息;CNN 只能捕捉到卷积窗所在的局部信息。
    • RNN计算成本通常更高,而CNN 的计算成本较低。

    4.2 深度 RNN

    1. 前述RNN中的计算都可以分解为三种变换:从输入 到隐状态 的变换、从前一个隐状态 到下一个隐状态 的变换、从隐状态 到输出 的变换。这三个变换都是浅层的,即:由一个仿射变换加一个激活函数组成。

      事实上,可以对这三种变换中引入深度。实验表明:引入深度会带来好处。

    • 方式一:通过将RNN的隐状态分为多层来引入深度。
    • 方式二:在这三种变换中,各自使用一个独立的MLP(可能是较浅的,也可能是较深的)。
    • 方式三:在第二种方式的基础上,类似ResNet 的思想,在 “隐状态-隐状态” 的路径中引入跳跃连接。
  • 通过将RNN的隐状态分为多层来引入深度:如下所示,隐状态有两层: 。隐状态层中层次越高,对输入提取的概念越抽象。

    • 模型的数学表示:

    • 单个样本的损失:

    • 更新方程:其中输入到隐状态的权重为 ,隐状态到输出的权重为 ,隐状态到隐状态的权重为 为输入偏置向量和输出偏置向量。


  • 在这三种变换中,各自使用一个独立的MLP(可能是深度的),如下图所示。

    该方法有一个主要问题:额外深度将导致从时间步 t 到时间步 t+1 的最短路径变得更长,这可能导致优化困难而破坏学习效果。

  • 4在第二种方式的基础上,类似ResNet 的思想,在 “隐状态-隐状态” 的路径中引入跳跃连接,从而缓解最短路径变得更长的问题。

    4.3 LSTM 和 GRU

    1. 目前实际应用中最有效的序列模型是门控RNN,包括基于LSTM: long short-term memory 的循环网络,和基于门控循环单元GRU: gated recurrent unit 的循环网络。

      围绕门控RNN 这一主题可以设计更多的变种。然而一些调查发现:这些 LSTMGRU架构的变种,在广泛的任务中难以明显的同时击败这两个原始架构。

    2. 门控RNN 的思路和渗漏单元一样:生成通过时间的快捷路径,使得梯度既不消失也不爆炸。

    • 可以手动选择常量的连接权重来实现这个目的,如跳跃连接。权重为固定的常量,且不随时间改变。
    • 可以使用参数化的连接权重来实现这个目的,如渗漏单元。权重是样本的函数,且不随时间改变。
    • 门控RNN 将其推广为:连接权重在每个时间步都可能改变。权重是样本和时间的函数,随时间改变。
  • 渗漏单元允许网络在较长持续时间内积累信息,但它有个缺点:有时候希望一旦某个信息被使用(即:被消费掉了),那么这个信息就要被遗忘(丢掉它,使得它不再继续传递)。

    门控RNN 能够学会何时清除信息,而不需要手动决定。

  • 4.3.1 LSTM

    1. LSTM 在手写识别、语音识别、机器翻译、为图像生成标题等领域获得重大成功。

    2. LSTM循环网络除了外部的 RNN 循环之外,还有内部的 LSTM cell循环(自环)。LSTMcell代替了普通 RNN 的隐单元,而LSTMcell 的一个输出。LSTM引入cell循环以保持梯度长时间持续流动。其中一个关键是:cell循环的权重视上下文而定,而不是固定的。具体做法是:通过gate 来控制这个cell循环的权重,而这个gate 由上下文决定。

    • 注意:cell 输出是 ,而不是整个RNN 单元的输出
    • cell 之间的连接是通过 来连接的。


    3.LSTM 最重要的就是cell 状态 ,它以水平线在图上方贯穿运行。





    4.sigmoid 函数 ( ) 的输出在 01 之间,描述每个部分有多少量可以通过。它起到门gate 的作用:0 表示不允许通过,1 表示允许全部通过,0~1 之间表示部分通过。LSTM 拥有三个门:遗忘门、输入门、输出门。

    5.遗忘门:控制了cell上一个状态 中,有多少信息进入当前状态 。与渗漏单元类似,LSTM cell 也有线性自环。遗忘门 控制了自环的权重,而不再是常数 :

    写成向量形式为:( 为逐元素的sigmoid 函数)

    其中: 为遗忘门的偏置, 为遗忘门的输入权重, 为遗忘门的循环权重。





    6.输入门:控制了输入 中,有多少信息进入cell当前状态 。输入门 的方程:写成向量的形式为:( 为逐元素的sigmoid 函数)其中: 为输入门的偏置, 为输入门的输入权重, 为输入门的循环权重。

    图中的 就是




    7.输出门:控制了cell 状态 中,有多少会进入cell 的输出 。输出门 的更新方程: 写成向量的形式:( 为逐元素的sigmoid 函数)其中: 为输出门的偏置, 为输出门的输入权重, 为输出门的循环权重。




    8.cell 状态更新:cell状态 由两部分组成:

      • 一部分来自于上一次的状态 :它经过了遗忘门 的控制,使得只有部分状态进入下一次。
      • 一部分来自于输入(包括 :输入需要经过 非线性层变换之后,然后经过输入门 的控制,使得只有部分输入能进入状态更新。因此cell 状态更新方程为: 写成向量的形式为:( 为逐元素的函数, 为逐元素的向量乘积)其中:cell的偏置, cell的输入权重, cell的循环权重。
    1. cell 输出更新:cell 输出就是 ,它是将cell 状态经过了 非线性层之后,再通过输出门 控制输出的流量。写成向量的形式:( 为逐元素的函数, 为逐元素的向量乘积)

      1. 一旦得到了cell 的输出 ,则获取整个RNN 单元的输出 就和普通的 RNN相同。 令节点 ,根据激活函数的性质:,则有:
      • 考虑到 的后续节点为:当 为最后一个节点时,后续节点为 ;当 不是最后一个节点时,后续节点为 。因此有: 考虑到:因此有:

      • 由于 中存在常量部分 ,因此 LSTM 可以缓解梯度消失。

      • 由于各种门的存在,因此 中的非常量部分会被缩小,因此可以缓解梯度爆炸。

      • 考虑到 的后续节点为:当 为最后一个节点时,后续节点为 ;当 不是最后一个节点时,后续节点为 。因此有

      • 考虑到 对于每个输出 都有贡献,则有:其中 表示 的第 i 个分量。

      • 考虑到 对于每个状态 都有贡献,则有:其中 表示 的第 i 个分量。

      • 考虑到 对于每个遗忘门 都有贡献,则有:其中 表示 的第 i 个分量。

      • 考虑到 对于每个输入门 都有贡献,则有:其中 表示 的第 i 个分量。

      • 考虑到 对于每个输出门 都有贡献,则有:其中 表示 的第 i 个分量。

      1. 也可以选择使用cell 状态 作为这些门的额外输入。此时 就多了额外的权重参数,这些参数对应于 的权重和偏置。

      4.3.2 GRU

      1. 门控循环单元GRULSTM 模型更简单:

      • GRU 的单个门控单元同时作为遗忘门和输入门,整个 GRU 模型只有两个门:更新门、复位门。
      • GRU 不再区分cell的状态 cell 的输出


    2. 更新门:控制了新的信息 ( 由 生成)、旧的信息 中各有多少信息进入了 。更新门 的更新方程:写成向量的形式为:( 为逐元素的sigmoid 函数)其中: 为更新门的偏置, 为更新门的输入权重, 为更新门的循环权重。

    3. 复位门:控制了新的信息 中, 之间的比例。它表示在新的信息中,旧的信息多大程度上影响新的信息。如果 r=0 ,则旧的信息不影响新的信息,可以理解为复位。复位门 的更新方程:写成向量的形式为:( 为逐元素的sigmoid 函数) 其中: 为复位门的偏置, 为复位门的输入权重, 为复位门的循环权重。

    4. cell输出:cell 输出就是 cell 更新方程:写成向量的形式:(其中 为逐元素的向量乘积; 为逐元素的函数) ,它刻画了本次的更新。于是cell 的输出更新方程为:其中:cell的偏置, cell的输入权重, cell的循环权重。

    5. 一旦得到了cell 的输出 ,则获取整个RNN 单元的输出 就和普通的 RNN相同。令节点 ,根据激活函数的性质:,则有:

      • 考虑到 的后续节点为:当 为最后一个节点时,后续节点为 ;当 不是最后一个节点时,后续节点为 。记 ,因此有:考虑到: 因此有:

      • 由于 中存在常量部分 ,因此 GRU 可以缓解梯度消失。* 由于各种门的存在,因此 中的非常量部分会被缩小,因此可以缓解梯度爆炸。

      • 考虑到 对于每个输出 都有贡献,则有: 其中 表示 的第 i 个分量。

      • 考虑到 对于每个状态 都有贡献,则有:其中 的第 i 个分量。

      • 考虑到 对于每个复位门 都有贡献,则有:其中 表示 的第 i 个分量。

      • 考虑到 对于每个更新门 都有贡献,则有:

      其中 表示 的第 i 个分量。

      4.3.3 讨论

      1. LSTMGRU 中有两种非线性函数:sigmoidtanh

      • sigmoid用于各种门,是因为它的阈值为 0~1,可以很好的模拟开关的关闭程度。

      • tanh 用于激活函数,是因为它的阈值为 ,它的梯度的阈值为

      • 如果使用sigmoid 作为激活函数,则其梯度范围为 ,容易发生梯度消失。

      • 如果使用relu 作为激活函数,则前向传播时,信息容易爆炸性增长。另外relu 激活函数也会使得输出只有大于等于0 的部分。

    6. 前面给出的 LSTMGRU 中, 是通过 feature map 直接相加,如 LSTM 中的状态更新方程:事实上,也可以通过 feature map 进行拼接,如:

      其中 : 表示将两个向量进行拼接。



    7. 4.4 编码-解码架构

      1. 前面介绍的多长度输入序列的模式中,输出序列和输入序列长度相同。实际任务中,如:语音识别、机器翻译、知识问答等任务,输出序列和输入序列长度不相等。编码-解码 架构就是为了解决这类问题。设输入序列为 ,输出序列为 。长度 。设 C 为输入的一个表达representation ,包含了输入序列的有效信息。

      • 它可能是一个向量,也可能是一个固定长度的向量序列。

      • 如果 C 是一个向量序列,则它和输入序列的区别在于:序列C 是定长的、较短的;而输入序列是不定长的、较长的。整个编码-解码 结构分为:编码器,解码器。

      • 编码器(也叫作读取器,或者输入RNN):处理输入序列。编码器的最后一个状态 通常就是输入序列的表达C, 并且作为解码器的输入向量。

      • 解码器(也叫作写入器,或者输出RNN):处理输入的表达C 。解码器有三种处理C 的方式:输入 C 作为每个时间步的输入、输入 C 作为初始状态 且每个时间步没有额外的输入、结合上述两种方式。

      • 训练时,编码器和解码器并不是单独训练,而是共同训练以最大化 :

    8. 编码-解码架构中:

      • 输入序列长度 \tau_x 和输出序列长度 \tau_y 可以不同。
      • 对于编码器与解码器隐状态是否具有相同尺寸并没有限制,它们是相互独立设置的。
    9. 编码-解码架构的主要缺点:编码器RNN输出的上下文C的维度太小,难以恰当的概括一个长的输入序列的完整信息。可以通过引入attention机制来缓解该问题。



    10. 4.5 attention

      1. attention 是一种提升 encoder - decoder 模型效果的机制,一般称作 attention mechanism

      • attention 被广泛用于机器翻译、语音识别、图像标注Image Caption 等领域。如:机器翻译中,为句子中的每个词赋予不同的权重。

      • attention 本身可以理解为一种对齐关系,给出了模型输入、输出之间的对齐关系,解释了模型到底学到了什么知识。

      • 在机器翻译中,解释了输入序列的不同位置对输出序列的影响程度。如下图所示为机器翻译中,输入-输出的 attention 矩阵。



      • 在图像标注中,解释了图片不同区域对输出文本序列的影响程度。如下图所示为图像标注中,影响输出单词的图像块。



    11. 设输入序列为 ,输出序列为 ,长度 。设encoder 的隐向量为 decoder 的隐向量为

      • 对于传统的 encoder-decoder 模型,decoder 的输入只有一个向量,该向量就是输入序列经过encoder编码的上下文向量 。通常将 encoder 的最后一个隐单元的隐向量 作为上下文向量。

      • 对于 attention encoder-decoder 模型,decoder 的输入是一个向量序列,序列长度为 decoder位置 i 的输入是采用了 attention 机制的上下文向量 ,不同位置的上下文向量不同。

      • 上下文向量 encoder 的所有隐向量加权得到: 。其中

      • 权重 刻画了:在对第 i 个输出进行解码时,第 t 个输入的重要程度。一个直觉上的方法是:首先计算 的相关性,然后对所有的 归一化即可得到权重系数。即: 其中 score 由多种计算方式,不同的计算方式代表不同的 attention 模型( 为待学习的参数,n 为向量的维度):

      4.5.1 local attention

      1. 上述的 attention 机制中为了计算上下文向量 , 需要考虑 encoder 的所有隐向量。当输入序列较长时(如一段话或一篇文章),计算效率较低。local attention 在计算上下文向量 时只需要考虑 encoder 的部分隐向量:首选预测encoder 端对齐的位置 ,然后基于位置 选择一个窗口来计算上下文向量 其中 为待学习的参数, d 为人工指定的固定常量。虽然 local attention 可以提高计算效率,但是会带来两个问题:

      • encoder 的输入序列长度 \tau_x 并不是很长时,计算量并没有显著减小。
      • 位置 的预测并不是非常准确,这就直接影响了计算 attention 的准确性。

      4.5.2 self attention

      1. 传统的 attention 是基于encoder 端和 decoder 端的隐向量来计算 attention 的,得到的是输入序列的每个 input 和输出序列的每个 output 之间的依赖关系。self attention 计算三种 attention

      • encoder 端计算自身的 attention,捕捉input 之间的依赖关系。
      • decoder 端计算自身的 attention,捕捉output 之间的依赖关系。
      • encoder 端得到的 self attention 加入到 decoder 端得到的 attention 中,捕捉输入序列的每个 input 和输出序列的每个 output 之间的依赖关系。

        \


    12. 设输入序列为 ,输出序列为 ,长度

      • encoder 端的 self attention

      • 首先经过 映射得到 key 向量序列 、经过 映射得到 query 向量序列

      • 然后计算归一化的 self attention 其中 表示各输入与第 i 个输入的相关因子,

      • 最后得到经过加权的 encoder 输出向量:

      • decoder 端的 self attention:考虑到解码时 s 时刻不知道 s 时刻及其之后的结果,因此仅考虑 s 时刻之前的 attention,这被称作 masked attention 。因此对于时刻 s :

      • 首先经过 映射得到 key 向量序列 、经过 映射得到 query 向量序列

      • 然后计算归一化的 self attention其中 表示各输入与第 i 个输入的相关因子,

      • 最后得到经过加权的 encoder 输出向量:

      • encoderdecoderattention

      • 计算归一化的 self attention其中 表示各输入与第 i 个输出的相关因子,

      • 最后得到经过加权的 attention 上下文向量:

      • 最后将上下文向量 作为一个前馈神经网络的输入,其输出就是

    13. 上述 self attention 机制完全抛弃了 RNN 的架构,著名的 Transformer 架构就是基于它来构建的。

      self attention 未能考虑到输入序列的先后顺序,因此 Transformer 架构中引入了位置 embedding 来解决该问题。

    14. 理论上序列的 self attention 只需要简单计算:

      引入两个映射矩阵是为了更好的泛化:attention 并不仅仅考虑序列的原始信息,而是考虑了从序列中抽取的信息。

    15. 4.5.3 Hierarchical attention

      1. 在论文《Hierarchical Attention Networks for Document Classification》 中提出了分层 attention 用于文档分类。论文提出了两个层次的 attention

      • 第一个层次是对句子中每个词进行 attention,即 word attention
      • 第二个层次是对文档中每个句子进行 attention,即 sentence attention


    16. 层次 attention 涉及到四个部分:

      其中 表示这个单词序列的总信息,称作单词上下文。它是随机初始化并从网络训练得到。

      其中 表示这个句子序列的总信息,称作句子上下文。它是随机初始化并从网络训练得到。

      • sentence attention
      • sentence encoder
      • word encoder:(对于句子 i )

      • word embedding

      • GRU 隐向量(原始论文中采用双向 GRU ):

      • word attention


        

      
      
      
          
      
      往期精彩回顾





      Python社区是高质量的Python/Django开发社区
      本文地址:http://www.python88.com/topic/135473
       
      611 次点击