🐬门控循环单元 GRU
2021-12-3
| 2023-8-7
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property

 
梯度异常在实践中的意义:
  • 可能会遇到这样的情况:早期观测值对预测所有未来观测值具有非常重要的意义。
    • 考虑一个极端情况,其中第一个观测值包含一个校验和, 目标是在序列的末尾辨别校验和是否正确。 在这种情况下,第一个词元的影响至关重要。 希望有某些机制能够在一个记忆元里存储重要的早期信息。 如果没有这样的机制,就将不得不给这个观测值指定一个非常大的梯度, 因为它会影响所有后续的观测值。
  • 可能会遇到这样的情况:一些词元没有相关的观测值。
    • 例如,在对网页内容进行情感分析时, 可能有一些辅助HTML代码与网页传达的情绪无关。 希望有一些机制来跳过隐状态表示中的此类词元。
  • 可能会遇到这样的情况:序列的各个部分之间存在逻辑中断。
    • 例如,书的章节之间可能会有过渡存在, 或者证券的熊市和牛市之间可能会有过渡存在。 在这种情况下,最好有一种方法来重置内部状态表示。
在学术界已经提出了许多方法来解决这类问题。 其中最早的方法是"长短期记忆"(long-short-term memory,LSTM) 。 门控循环单元(gated recurrent unit,GRU)是一个稍微简化的变体,通常能够提供同等的效果, 并且计算的速度明显更快。

门控隐状态

门控循环单元与普通的循环神经网络之间的关键区别在于: 后者支持隐状态的门控。 这意味着模型有专门的机制来确定应该何时更新隐状态, 以及应该何时重置隐状态。 这些机制是可学习的,并且能够解决了上面列出的问题。 例如,如果第一个词元非常重要, 模型将学会在第一次观测之后不更新隐状态。 同样,模型也可以学会跳过不相关的临时观测。 最后,模型还将学会在需要的时候重置隐状态。

重置门和更新门

把它们设计成 区间中的向量, 这样就可以进行凸组合。 重置门允许控制“可能还想记住”的过去状态的数量; 更新门将允许控制新状态中有多少个是旧状态的副本。
下图描述了门控循环单元中的重置门和更新门的输入, 输入是由当前时间步的输入和前一时间步的隐状态给出。 两个门的输出是由使用sigmoid激活函数的两个全连接层给出。
notion image
对于给定的时间步,假设输入是一个小批量 (样本个数:,输入个数:上一个时间步的隐状态是 (隐藏单元个数:)。 那么重置门 和更新门 的计算如下所示:
其中 是权重参数, 是偏置参数。 在求和过程中会触发广播机制。 使用sigmoid函数将输入值转换到区间
 

候选隐状态

将重置门 与常规隐状态更新机制集成, 得到在时间步候选隐状态
是权重参数, 是偏置项, 符号是Hadamard积(按元素乘积)运算符。 在这里,使用tanh非线性激活函数来确保候选隐状态中的值保持在区间 的元素相乘可以减少以往状态的影响。每当重置门 中的项接近 时, 恢复一个普通的循环神经网络。 对于重置门中所有接近的项, 候选隐状态是以作为输入的多层感知机的结果。 因此,任何预先存在的隐状态都会被重置为默认值。
notion image
 

隐状态

上述的计算结果只是候选隐状态,仍然需要结合更新门的效果。 这一步确定新的隐状态 在多大程度上来自旧的状态和新的候选状态。 更新门仅需要在之间进行按元素的凸组合就可以实现这个目标。 这就得出了门控循环单元的最终更新公式:
每当更新门接近时,模型就倾向只保留旧状态。 此时,来自的信息基本上被忽略, 从而有效地跳过了依赖链条中的时间步。 相反,当 接近时, 新的隐状态就会接近候选隐状态。 这些设计可以帮助处理循环神经网络中的梯度消失问题, 并更好地捕获时间步距离很长的序列的依赖关系。例如,如果整个子序列的所有时间步的更新门都接近于, 则无论序列的长度如何,在序列起始时间步的旧隐状态都将很容易保留并传递到序列结束。
notion image
总之,门控循环单元具有以下两个显著特征:
  • 重置门有助于捕获序列中的短期依赖关系
  • 更新门有助于捕获序列中的长期依赖关系
 
 

从零开始实现

notion image
 

简洁实现

这段代码的运行速度要快得多, 因为它使用的是编译好的运算符而不是Python来处理之前阐述的许多细节
 
 
 
 
notion image
 
  • PyTorch
  • RNN的实现长短期记忆网络 LSTM
    目录