【史上最本质】序列模型:RNN、双向 RNN、LSTM、GRU、Seq-to-Seq、束搜索、Transformer、Bert

本文介绍了序列模型,它能捕捉数据时序关系和顺序依赖性,适合处理时序数据。还阐述了RNN、双向RNN、LSTM、GRU等结构,分析了各自优缺点。此外,讲解了编码器 - 解码器Seq - to - Seq、Beam Search束搜索,最后提及Transformer和Bert。

 


序列模型优化思路

序列数据:样本与样本之间,存在某种特定关联(时间顺序、上下文语义)排列的数据

不同序列模型其实都在做一件事:给序列每个元素打分或分配权重,然后利用这些权重来进行加权求和,来建立样本与样本之间的关联 。

所有序列模型都在,以 “加权求和” 来捕捉输入之间的关联关系:

  • ARIMA 通过回归系数(权重)和噪声项对历史数据进行线性叠加;
  • RNN 通过隐藏状态和当前输入加权求和;
  • CNN 通过卷积核在局部窗口的加权求和;
  • Transformer 通过注意力分配给序列中各位置,再加权求和得到上下文表示。

他们之间唯一不同的是,在于采用了怎样的机制,来衡量并学习每个元素应当被赋予多大的权重。

每个序列模型,确定/学习各时刻的重要性或贡献度 的方式是不同的。

传统方法强调线性和平稳性,深度方法往往能捕捉非线性和长距离依赖。

算法观察假设加权求和机制核心区别 / 演化要点
ARIMA- 关注平稳的时间序列
- 历史数据(滞后项)的线性依赖
- 过去的值与当前值存在线性关系
- 误差(噪声)同样存在可建模的平均过程
- 将过去若干时刻的值(AR部分)和误差项(MA部分)以线性加权求和的方式建立预测模型- 经典的统计模型
- 强调平稳性与线性假设
- 对于复杂非线性或长依赖数据往往力不从心
RNN- 序列具有时间依赖,需捕捉上下文信息
- 当前时刻的输出往往与前面若干时刻有关
- 当前输出由“当前输入 + 上一时刻隐藏状态”共同决定- 将上一时刻的隐藏状态和当前输入,通过“隐藏权重”进行加权求和,得到新的隐藏状态- 可以在一定程度上捕捉短期依赖
- 容易出现梯度消失/梯度爆炸
- 并行化能力较弱
Deep RNN- 单层 RNN 表达能力有限
- 多层网络可分层抽象信息
- 多层结构有助于捕捉序列中的多层次特征和更复杂依赖- 在基础 RNN 的结构上,额外叠加多层隐藏层
- 每层都是“(上一层输出 + 当前层隐藏状态) 的加权求和”后再非线性变换
- 层数加深,能学到更抽象的表示
- 训练更难,且更容易受梯度消失影响
GRU- RNN 对长序列依赖的捕捉能力不足
- 需要“记忆门”来决定保留或忘却哪些信息
- 通过门控机制(重置门、更新门),可自动学习何时记忆、何时遗忘,从而捕捉重要的长期依赖- 依然是对“上一时刻状态 + 当前输入”的加权求和,但多了重置门和更新门控制信息流动
- 用加权方式融合“候选隐藏状态”与“旧隐藏状态”
- 相比 LSTM 结构更紧凑,只有两个门
- 训练更高效,效果通常与 LSTM 相当
LSTM- 同样意识到长依赖问题
- 希望细粒度地控制信息的“写入、保留、输出”
- 通过输入门、遗忘门、输出门,能对信息流动进行更灵活控制,从而缓解梯度消失并保留长期信息- 记忆单元(cell state) 以加权求和形式保留关键信息
- 各门对信息进行选择性“加权”与“相加”,形成新的 cell state 和 hidden state
- 相比 GRU 结构更复杂,有三个门
- 在长序列任务上表现良好,但计算和参数量更大
BRNN(双向 RNN)- 当前时刻不只与过去有关,也常常需要未来上下文信息(例如文本翻译中,后面词汇会影响对前面词汇的理解)- 若能同时获取前后文信息(双向),对当前时刻的表征更准确- 正向 RNN 和反向 RNN 各自做加权求和,然后将两方向的隐藏状态进行拼接或加权融合- 需要一次性拿到整段序列才能做双向传播
- 无法实时在线预测,但对离线任务效果较好
CNN(应用于序列)- 序列往往局部上下文关联强(如文本中的 n-gram,语音中的局部频谱特征)- 局部卷积可提取局部模式,通过多层卷积 + 池化可获取全局信息- 卷积核在滑动窗口内对局部输入进行“加权求和”(卷积本质为加权求和与偏置的线性操作),然后叠加非线性- 参数共享,局部感受野
- 可并行计算
- 在序列任务(如 NLP)中与 RNN/Transformer 有不同优势和局限
Seq2Seq(Encoder-Decoder)- 机器翻译、对话生成等场景中,需要输入序列到输出序列的映射
- 简单 RNN 难以直接把输入映射到任意长度输出
- 可以用 Encoder 将输入序列编码成向量表示,再用 Decoder 根据该向量解码出目标序列- Encoder 端:对输入序列逐步加权求和到隐藏状态
- Decoder 端:每一步根据上一步隐藏状态 + 编码向量加权求和,输出下一个 token
- 典型基于 RNN 的 Encoder-Decoder 结构
- 后来衍生了注意力机制(Attention) 来增强对输入序列不同部分的加权
Transformer- RNN 结构在捕捉长距离依赖时效率较低,难以并行
- 注意力机制能更灵活地让每个位置“关注”序列各处
- 通过自注意力(Self-Attention) 机制,对序列中任意两个位置的关系进行加权建模,可以更好地捕捉全局依赖- 不再依赖循环或卷积,而是依赖多头自注意力:对序列的所有位置进行“加权求和”得到上下文表示
- 位置编码(Positional Encoding)保留位置信息
- 并行化能力强,易于训练
- 对长序列长依赖的捕捉更高效
- 已成为主流序列建模结构,如 GPT、BERT 等都基于 Transformer

“加权求和” 可以被看作是一种“分配注意力/重要性”的过程。

实际上都在尝试确定序列各时刻或各元素对最终输出的‘贡献度’,然后把这些贡献度做加权累加。

不同模型之间的差别,主要在于它们如何去评估并学习这种贡献度的大小 — 这个时刻/这个输入到底有多大用处?。

之所以说“权重”,是因为模型需要判断 “什么时候、对哪些输入施加更大关注度”。

  • ARIMA 用线性系数显式地衡量过去几步的影响
  • RNN 通过隐藏状态与输入的组合来捕捉时序依赖
  • 而注意力机制(如 Transformer)甚至允许模型一次性关注序列的任意位置,等等。

说白了就是“怎么估计哪些时刻(或特征)更关键”,再将这些信息“加权加起来”。

最佳的计算方式是,注意力机制。

 


序列模型是啥

序列数据是,按照时间顺序或者某种逻辑顺序排列的数据集合。

  • 每个数据点通常依赖于前一个数据点,或者至少与之前的数据点有关。

序列模型是,能够捕捉数据中的时序关系或顺序依赖性。

序列模型相比普通模型更适合处理具有时序性质的数据,主要解决以下问题:

  1. 建模时序关系:序列模型能够捕捉序列数据中的时序关系和上下文信息,通过考虑数据点之间的依赖关系,更准确地预测和生成序列。

  2. 处理变长序列:序列模型能够处理变长序列,即序列长度不固定的情况。相比普通模型需要固定长度的输入,序列模型更适合处理语音、文本等长度可变的数据。

  3. 模型内存储信息:序列模型通常具有记忆机制,能够存储和更新之前的状态,使得模型能够处理长期依赖关系,从而更好地理解和预测序列数据。

  4. 应对上下文依赖:序列模型能够捕捉上下文依赖,即当前数据点的输出受到之前数据点的影响。相比普通模型,序列模型能够更好地捕捉数据之间的关联性,适用于语音识别、机器翻译等任务。

序列模型相对于普通模型更适合处理具有时序性质的数据,能够更好地捕捉序列中的时序关系和上下文信息,从而提高模型的性能和效果。

RNN 结构

序列模型有很多,比如 RNN。

在传统神经网络的基础上引入了循环连接,能够通过记忆过去的信息来处理当前的输入,从而能够处理变长序列数据、捕捉序列数据中的上下文关系。

输入:并不是一整句输入,而是一个一个词的输入

RNN的计算可以简单地描述为以下几个步骤:

  1. 第1次处理:将第一个词作为输入传递给RNN,并根据权重参数计算隐藏状态和输出。

  2. 第2次处理:将第二个词作为输入传递给RNN,同时使用前一个时间步的隐藏状态计算当前时间步的隐藏状态和输出。

  3. 第3次处理:将第三个词作为输入传递给RNN,同时使用前一个时间步的隐藏状态计算当前时间步的隐藏状态和输出。

  4. 第4次处理:将第四个词作为输入传递给RNN,同时使用前一个时间步的隐藏状态计算当前时间步的隐藏状态和输出。

  5. 第5次处理:将第五个词作为输入传递给RNN,同时使用前一个时间步的隐藏状态计算当前时间步的隐藏状态和输出。

将前一个时间步的输出,作为后一个时间步的输入,RNN能够逐渐积累和传递信息。

从而对整个序列进行建模和预测。

这样,RNN能够捕捉到序列数据中的上下文关系和时序信息。

双向 RNN

但 RNN 这种结构也有局限。

ta只依赖前面输入的单词,而没有看后面的单词。

但有些句子,后面的单词会直接反转整个句子的意思。

  • 我不是个好父亲,不是个好丈夫,不是个好儿子,但那又怎样呢?我是个小仙女呀。
  • 我每天都坚持做仰卧起坐,晚上一个仰卧,早上一个起坐
  • 无论最后我们疏远到什么样子,一个红包就能回到最初

或者有些句子,不通过后面的词,无非判断是人名,还是物名:

  • 胃,你能不能别疼了?第一我不叫胃,我叫楚雨荨!

双向 RNN 结构:

分为前向、反向:

  • 前向:从左到右计算一组激活值,是当前步之前的激活值叠加
  • 反向:从右到左计算一组激活值,是当前步之后的激活值叠加
  • 预测值:获取整个句子的所有时间步激活值

双向 RNN 准确性提高了,但必须等整个句子输入完全才可以预测。

长短期记忆递归神经网络 LSTM

RNN 在处理长序列时,由于梯度消失或梯度爆炸的问题,确实可能导致随着时间的推移,之前的输入对当前步的影响逐渐减弱。

这是由于在反向传播过程中,梯度信息的传递过程中出现的问题导致的。

这样的问题限制了传统RNN在捕捉长期依赖关系方面的能力。

  • RNN 的设计机制,让越晚的输入对当前步的影越大,越早的输入影响越小,但在长序列关联关系处理的不好

Here is the extracted text from the image:

LSTM 是在简单 RNN 的基础上增加了细胞状态(cell state),来直接传递相关部分之间的信息,是借鉴了 ResNet 的残差思想。

由于在细胞状态传递不同传输的模块不会消失,因此 LSTM 继承了简单 RNN 模型稳定的问题。

同时,LSTM 还引入了不同 Sigmoid 激活的门控机制(遗忘门,输入门与输出门),来分别控制上一时刻的细胞状态、输入信息及当前信息的选择性,从而实现对信息的长期记忆和选择性忘记。

LSTM 的思想就是,划重点,保留长序列中重要信息,遗忘不重要的

在这里插入图片描述

LSTM 通过引入了记忆单元和门控机制来解决这个问题。

  • 记忆单元可以记住长期的信息
  • 并通过门控机制来控制信息的流动

门控机制可以选择性地保留和遗忘信息,从而更好地控制梯度的流动,避免梯度消失或梯度爆炸的问题。

三个门控机制包括遗忘门、输入门和输出门,负责决定哪些信息需要保留、丢弃或输出:

  • 遗忘门:决定了前一个记忆状态中哪些信息需要忘记,去掉一些不重要的
  • 输入门:决定了当前输入中哪些信息需要被记忆,添加一些新的重要信息
  • 输出门:决定了记忆单元中哪些信息需要输出

如果输入门全部关闭(激活值为0),遗忘门、输出门全部打开,本时间步等于上一步,绕过本步,把上一步传给下一步,很像残差连接。

这样就可以把前面的激活值传递到后面去,避免梯度消失或梯度爆炸的问题。

因此,LSTM相对于传统的 RNN 在处理长序列数据时表现更优秀,尤其在涉及到长期依赖关系的任务中,如机器翻译、语言建模等。

门控循环单元 GRU

GRU 对 LSTM 进行了简化,将细胞状态和隐藏状态合为一体,将遗忘门与输入门合为一个-更新门。


GRU 将 LSTM 三个门,简化为 2 个(重置门、更新门)。

  • 重置门:从上一步中复制多少信息
  • 更新门:从上一步隐藏状态中更新多少信息

相对于 LSTM,GRU 减少了计算复杂度。

门控机制有助于模型决定哪些信息应该被保留或忽略,从而使得这些模型能够较好地处理序列数据中的长期依赖问题。

更新门完全打开(即Sigmoid激活为1)时,可以减少梯度消失的问题,因为它允许梯度在长序列中无障碍地流动。

然而,由于LSTM和GRU较为复杂,在实践中,一般会选择一些不那么复杂的模型(即 RNN 或单层的LSTM)来解决特定的任务需求。

比如,任务是预测文本中的下一个词,如果这个文本非常短,比如一个短句或者标题,使用复杂的LSTM或GRU可能是不必要的,因为简单的模型就能够捕捉到足够的序列信息来进行有效的预测。

编码器-解码器 Seq-to-Seq

编码器-解码器:将输入数据转换为另一种输出数据。

实现可能是这样:

  • 英文转中文:一个 RNN 后,再接一个 RNN
  • 文字转图像:一个 RNN 后,再接一个 CNN

为什么要这样?

输入数据转换为另一种输出数据,他们之间存在一个概率关系。

那能不能直接找到一个函数描述: y = f ( x ) y=f(x) y=f(x)

但发现不知道函数映射具体是什么样的, f f f 找不到,因为 x 、 y x、y xy 不固定,输入输出长度都不相等。

可以先把输入数据 x 转为中间数据 z,再把 z 输出映射到 y 上,就实现了 x 到 y 映射。

 

举个例子,我们要将一张图片中的物体识别出来,并给出物体的类别。这个任务的输入是一张图片,输出是物体的类别标签。

如果我们直接将图片像素作为输入,并尝试找到一个函数 y = f ( x ) y = f(x) y=f(x) 来将像素映射为类别标签,会非常困难,因为图片的像素值是一个二维数组,无法直接映射为类别标签。

为了解决这个问题,我们可以先将图片经过一个卷积神经网络(CNN)转换为中间特征表示 z z z,这个中间特征可以捕捉到图片中的重要信息。

然后,我们可以将 z z z 作为输入,通过一个全连接层将其映射到类别标签 y y y 上,从而实现图片到类别标签的映射。

通过引入中间状态或中间数据,我们可以更好地处理输入和输出之间的关系,解决输入输出长度不固定的问题,并且能够更好地捕捉到输入数据的重要特征。

 

编码器:把不定长的输入,变成定长的上下文变量

解码器:解码上下文变量,生成输出序列

Beam Search 束搜索:选择最佳翻译结果

解码器会根据编码器生成的变量来一个一个时间步生成每个单词,如果词表有1000单词,就会生成1000单词对应的概率。

从这1000个概率中选出一个作为当前时间步的输出,那怎么保证每次是最佳结果呢?

第一反应,肯定是选概率最大的。

最大概率是有什么问题吗?

最大概率仅仅考虑了当前时间步的概率分布,而忽略了整个序列的全局信息。

大部分时候,最大概率的选择会导致整个序列的不连贯或者不合理。

这是因为生成序列的概率分布通常是一个复杂的非凸函数,存在多个局部最大值。

因此,仅仅依靠最大概率可能会陷入局部最优解,而无法得到整个序列的最佳结果。

为了解决这个问题,常用的方法是使用集束搜索(beam search)算法。

集束搜索会在每个时间步保留多个候选结果,然后根据一定的规则进行扩展和剪枝,最终选出整个序列概率最大的结果作为最佳结果。

通过保留多个候选结果,集束搜索能够充分利用全局信息,从而获得更好的结果。

但ta的问题也很明显,同时生成多个序列计算量太大。

Transformer

请猛击:《从【注意力机制】开始,到【Transformer】的零基础【大模型】系列

Bert

请猛击:【史上最小白】Bert 分析类大模型:双向 Transformer 编码器

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值