文章目录
写在前面
最近在跟着Datawhale一起组队学习,学的是fun-transformer,因为入职后可能也会涉及到大模型和深度学习的内容,所以对这个还蛮感兴趣的。这一篇是引言部分的学习,主要是一些基础性的介绍,我会根据学习内容结合我自己的视角讲一下Seq2Seq的目的(定义),Encoder-Decoder的模型组成和一些其他的知识。不是计算机出身,有些理解会写的比较偏向统计。有很多地方结合了李宏毅老师的课程和一些我问GPT的学习点(ps.感觉GPT真的是学习利器!)。
Embedding:词汇到向量空间的映射
引入 Embedding 的意义
这部分其实对应这次Task的“从低维到高维”,但我自己觉得在说Transformer前,应该先说什么是Embedding,为什么要Embedding,所以就放前面啦。我个人的理解是,文字是人类自然而然的语言,数学是机器能接受的人类语言,所以Embedding起到了一种桥梁的作用——它将离散的输入(如单词、子词或字符)转化为连续的向量表示,使得这些输入能够被深度学习等模型处理。
高维稀疏表示(比如one-hot)是否属于 Embedding?
我一开始学自然语言处理的时候,先接触到的这种桥梁是高维稀疏表示,比如 One-hot Encoding,这次看教程再去查,了解到它其实不属于典型意义上的 Embedding,主要原因是:
1. Embedding 的定义
- Embedding 是一种将离散符号(如词汇)映射为低维、稠密向量的方式,目标是通过学习到的向量表示捕捉符号之间的语义关系,使模型能够处理输入的语义特征。
- Embedding 具有语义连续性,即在向量空间中,语义相似的符号(如词汇)通常会在空间中靠得更近。
2. 高维稀疏表示的特点
- 高维:高维稀疏表示的维度等于词汇表的大小。例如,对于一个包含 10,000 个单词的词汇表,每个单词的表示是一个 10,000 维的向量。
- 稀疏:One-hot Encoding 是最典型的稀疏表示,其中只有一个位置为 1,其余位置为 0。这种表示方法没有捕捉词汇之间的任何语义关系。
- 无语义信息:在高维稀疏表示中,不同词汇之间是离散的、等距的,没有明确的语义连续性。因此,模型无法直接从这种表示中学习到词汇的语义特征。
3. 区别
特性 | 高维稀疏表示(词典) | Embedding |
---|---|---|
维度 | 高维 | 低维 |
表示方式 | 稀疏向量(大部分为 0) | 稠密向量(所有位置都有值) |
语义信息 | 无语义信息 | 通过训练学习到语义信息 |
适用场景 | 简单的词汇索引、统计模型 | 深度学习模型中的输入表示 |
所以呢,Embedding 的意义不仅在于表示单词,还在于捕捉输入的语义特征,引入 Embedding 不仅解决了离散的文字等输入无法直接参与计算的问题,还能让Transformer 的注意力机制提供了一个语义丰富的基础,帮助模型在训练中更好地学习输入序列之间的复杂关系。
1. 什么是Embedding
再把上面的区别结合一下,Embedding就是:
- 定义:Embedding 是一种将离散的符号(如单词、字母或字符)映射到连续向量空间的方式,目标是让语义相似的符号在向量空间中靠近。
- 目的:将高维、稀疏的离散特征(如词汇)转化为低维、稠密的向量表示,从而便于在机器学习模型中使用。
示例:
"cat" → [0.3, 0.5, -0.2]
"dog" → [0.35, 0.45, -0.25]
2. Embedding 的作用
- 降维:将高维的词汇特征映射到低维连续空间,降低模型的计算复杂度。
- 稠密表示:通过向量表示捕捉词汇的语义信息,向量中的每个维度可以理解为潜在的语义特征。
- 语义相似性:Embedding 使得语义相近的词(如“猫”和“狗”)在向量空间中更接近,而语义不同的词(如“猫”和“汽车”)距离更远。
3. 一些常见的Embedding方法
- 基于统计的词向量方法:
- Word2Vec:通过 Skip-Gram 或 CBOW 模型学习词的向量表示。
关键词:上下文窗口、共现信息
(这个我自己做项目的时候用过,感觉有时候笨笨的,有的词汇明明在表里但是得不到Embedding,后来也没解决TUT) - GloVe:通过矩阵分解和全局共现统计信息生成词向量。
关键词:共现矩阵、矩阵分解
- Word2Vec:通过 Skip-Gram 或 CBOW 模型学习词的向量表示。
- 基于深度学习的 Embedding:
- FastText:考虑到子词信息,能够处理未见过的词。
- ELMo:基于双向 LSTM,生成上下文相关的动态词向量。
- BERT Embedding:使用预训练的 Transformer 模型,生成深层次的动态词向量。
4. 代码示例
可以很简单的python来生成Embedding(R也可以),里面都有现成的包,比如:
from gensim.models import Word2Vec
sentences = [["I", "like", "cats"], ["I", "love", "dogs"]]
model = Word2Vec(sentences, vector_size=10, window=3, min_count=1, workers=4)
print(model.wv['cats']) # 输出“cats”的词向量
5. 一些拓展
- 高维空间可视化:可以用 PCA 或 t-SNE 对词向量进行降维和可视化~
- 评估 Embedding 的质量:介绍常见的评估方法,如语义类比任务(“king - man + woman = queen”)和词相似性计算(余弦相似度)。
- 动态 Embedding 与静态 Embedding 的区别:强调 BERT 等模型生成的上下文相关词向量是动态的,针对不同的句子会有不同的表示,而 Word2Vec、GloVe 等生成的是静态词向量。
Seq2Seq
Seq2Seq 模型其实就是输入一个序列,输出一个序列,输入、输出的序列长度都可变。这样的一个模型,根据李宏毅老师的说法,就很适合做一些Question-Answer(翻译、摘要、情感分析、分类、对话等等等等)的任务,
Seq2Seq的优缺点
之前没深入思考过它的优劣,这次学习了下,优点包括:
编号 | 优势 | 描述 |
---|---|---|
1 | 端到端学习 | Seq2Seq 模型实现了从原始输入数据(如文本、语音等)到期望输出序列的直接映射,无需人工进行显式特征提取或复杂的工程化步骤。 |
2 | 处理可变长度序列 | 模型能够适应不同长度的输入和输出序列,灵活处理变长数据,无需固定长度。 |
3 | 信息压缩与表示 | 编码器将输入序列压缩为一个固定维度的上下文向量,作为输入序列的抽象表示,解码器基于该向量生成目标输出序列。 |
4 | 可扩展性 | Seq2Seq 模型具有良好的模块化特性,可以与其他神经网络架构(如 CNN、RNN)无缝集成,从而应对更加复杂和多样化的数据处理任务。 |
特别地,在 Seq2Seq 框架提出之前,深度神经网络在在图像分类等问题上有很好的效果,在这些模型中,输入和输出通常都可以表示为固定长度的向量,如果长度稍有变化,会使用填充(Padding)等操作,其目的是将序列数据转换成固定长度的格式,以便于输入到需要固定长度输入的神经网络中。但是,实际中还有很多问题序列长度是未知的,就需要Seq2Seq很好地适应了这种情况。
Tips:为什么EOS和BOS可以减少padding依赖?
-
Padding 的问题:
Padding 填充的位置实际上包含了具体的值(通常是 0 或某个特殊的标记 ),虽然这些值本身没有语义,但它们会被模型视为输入的一部分,尤其是在 RNN、Transformer 等处理序列的模型中。如果模型不能很好地识别填充位置,就可能学习到与这些无意义填充值相关的模式,从而降低模型的效果。
当然啦,在计算损失时可能需要特殊的处理来忽略这些补零的元素,以免它们影响模型的训练效果。这通常通过使用掩码(Mask)来实现,掩码可以指示哪些位置是补零的,以便在计算过程中忽略这些位置。 -
BOS 和 EOS 的作用:
BOS 和 EOS 只是起到标记序列边界的作用,模型可以利用它们来明确知道序列从哪里开始、在哪里结束。这样一来,即使输入序列被填充到固定长度,模型也只会关注从 BOS 到 EOS 之间的部分,而忽略后续的 padding,从而避免无意义的噪声影响模型的学习。
所以,BOS 和 EOS 是逻辑上的标记,而 padding 是实际的数值填充,两者的作用是不同的。使用 BOS 和 EOS 后,可以让模型更好地识别出有效的序列部分,减少对填充值的依赖。
缺点包括:
编号 | 缺点 | 描述 |
---|---|---|
1 | 上下文向量信息压缩 | 输入序列的全部信息需要被编码成一个固定维度的上下文向量,导致信息压缩和细节信息丢失的问题,尤其影响长序列的生成效果。 |
2 | 短期记忆限制 | 由于 RNN 的固有特性,Seq2Seq 模型在处理长序列时存在短期记忆限制,难以有效捕获和传递长期依赖性,影响模型对长距离依赖的建模能力。 |
3 | 暴露偏差(Exposure Bias) | 在训练时通常采用“teacher forcing”策略,导致模型在推理阶段由于缺乏真实输出提示而表现不佳。这种训练与推理方式的不一致性,导致错误累积。 |
Tips:Seq2Seq 中的信息压缩与固定维度的上下文向量
缺点里说的”上下文向量信息压缩 “,指的不是 Embedding 的固定维度,而是指编码器输出的上下文向量(Context Vector)维度是固定的。
1. Embedding 维度是否固定?
- Embedding 维度可以是固定的,也可以是动态的,具体取决于模型的设计和使用的词向量类型。比如:
- 在经典的 Seq2Seq 模型中,输入序列中的每个词通常会被映射为一个固定维度的稠密向量(例如 300 维的 Word2Vec 或 768 维的 BERT 表示)。
- 这个固定维度的 Embedding 仅仅是每个词的表示维度,它不等于整个输入序列的表示。
2. 上下文向量的固定维度
在经典的 RNN-based Seq2Seq 模型中,编码器(RNN、LSTM 或 GRU)将整个输入序列编码成一个固定长度的上下文向量
h
context
h_{\text{context}}
hcontext
,其维度是模型的隐层大小。例如,如果隐层大小为 512,则上下文向量是一个 512 维的向量。
- 信息压缩问题:无论输入序列多长,最终都会被编码为一个固定维度的向量(即上下文向量)。这意味着模型需要将所有的输入信息浓缩到一个固定长度的表示中,这就带来了信息丢失的问题,特别是当输入序列较长时,较早的细节可能会被“遗忘”或覆盖。
- 细粒度信息丢失:因为上下文向量的维度固定,而输入序列可能包含大量细节信息,编码器无法在有限的维度中保留所有细节,从而导致模型在解码时难以准确地生成对应的输出。
3. 对比 Embedding 和上下文向量
特性 | Embedding | 上下文向量(Context Vector) |
---|---|---|
表示内容 | 输入序列中每个词的稠密表示 | 输入序列整体的压缩表示 |
维度 | 通常固定(如 300 维、768 维) | 固定(编码器隐层维度,如 512 维) |
是否动态变化 | 对于静态 Embedding(如 Word2Vec)不变;动态 Embedding(如 BERT)会随上下文变化 | 固定的 Seq2Seq 中不变,Attention 中动态变化 |
信息丢失的原因 | 维度固定,但不会直接导致信息压缩 | 将整个序列压缩成一个固定长度向量导致信息压缩 |
Attention机制
所以呢,为了解决“上下文向量信息压缩 ” 这个问题,聪明的科学家们引入了 Attention 机制。Attention 的核心思想是,解码器不依赖一个固定的上下文向量,而是动态地选择编码器输出中的重要信息:
- 编码器在每个时间步输出一个隐状态
h
t
h_{\text{t}}
ht
,这些隐状态共同构成了一个序列表示,而不是一个固定的向量。 - 在解码时,Attention 机制会根据当前解码器状态,对编码器的每个隐状态进行加权求和,从而得到一个动态的上下文向量,使得模型能够更好地利用输入序列的所有信息。
有一个简单的解释,就像人在看一张图片的时候首先会关注到里面自己比较感兴趣/值得关注的地方一样,Attention的作用就是让机器把注意力从那些不重要的东西上挪开。
Attention 的分类与解释
Attention 机制根据不同的维度可以进行多种分类,主要从以下几个方面进行划分:
1. 按计算区域划分
-
Soft Attention (Global Attention):
计算整个输入序列的权重,对所有位置进行加权求和。这种方式适用于大多数序列建模任务,权重是连续的,可以直接通过反向传播优化。
示例:常见于经典的 Seq2Seq + Attention 模型。 -
Local Attention:
只关注输入序列的一部分(局部区域),通常通过窗口机制选择局部区域。这种方式计算效率更高,但可能会丢失全局信息。
示例:局部注意力机制在处理长序列时常用,如图像处理中的局部特征提取。 -
Hard Attention:
对输入序列的某些位置进行离散选择(通过采样确定关注的位置),而不是对所有位置计算连续权重。这种方式不可直接通过反向传播优化,通常使用强化学习方法。
示例:在一些需要明确选择注意力位置的任务中,如视觉领域中定位目标区域。
2. 按所用信息划分
-
General Attention:
使用上下文信息(通常是编码器输出)计算注意力权重。最常见于传统 Encoder-Decoder 架构中。 -
Self Attention:
输入序列中的每个位置与序列中的其他位置进行交互,计算自注意力权重,常用于 Transformer 模型中。 -
串联方式:
将输入特征与其他信息串联后计算注意力权重,这种方式可以结合多种信息源。
3. 按使用模型划分
-
CNN + Attention:
在卷积神经网络中引入注意力机制,用于特征增强或特征选择。 -
RNN + Attention:
在循环神经网络的基础上添加注意力机制,常用于机器翻译等序列生成任务。 -
LSTM + Attention:
特指基于 LSTM 编码器和解码器的 Seq2Seq 模型中添加的注意力机制。 -
纯 Attention 模型(Pure Attention):
指完全基于注意力机制的模型,如 Transformer 模型,彻底抛弃了 RNN 或 CNN 的结构。
4. 按权值计算方式划分
-
点乘算法(Dot-product Attention):
直接计算查询和键的点积,然后通过 softmax 归一化得到注意力权重。
示例:常用于 Scaled Dot-Product Attention。 -
矩阵相乘(Additive Attention):
通过向量拼接或其他方式计算注意力权重,常见于 Bahdanau Attention。 -
Cos 相似度:
使用向量的余弦相似度计算权重,适用于需要度量角度相似性的任务。
5. 按模型结构划分
-
One-Head Attention:
单个注意力头,即对查询、键和值计算一次注意力。 -
Multi-layer Attention:
多层堆叠的注意力机制,每一层可以捕获不同层次的信息。 -
Multi-head Attention:
多个注意力头并行计算,每个头使用不同的投影矩阵,捕获不同的特征空间。
总结
分类维度 | 类型 | 描述 |
---|---|---|
计算区域 | Soft Attention (Global Attention) | 对整个输入序列进行加权求和,连续权重,可反向传播优化 |
Local Attention | 只关注输入序列的一部分,使用窗口机制,计算效率更高 | |
Hard Attention | 离散选择注意力位置,需使用强化学习方法进行优化 | |
所用信息 | General Attention | 使用上下文信息计算注意力权重 |
Self Attention | 输入序列中各位置之间的交互,常用于 Transformer 模型 | |
串联方式 | 将输入特征与其他信息串联后计算注意力权重 | |
使用模型 | CNN + Attention | 在卷积神经网络中引入注意力机制 |
RNN + Attention | 在循环神经网络中添加注意力机制 | |
LSTM + Attention | 基于 LSTM 的注意力机制,常见于 Seq2Seq 模型 | |
纯 Attention 模型(Pure Attention) | 完全基于注意力机制的模型,如 Transformer | |
权值计算方式 | 点乘算法(Dot-product Attention) | 查询和键的点积,通过 softmax 归一化得到权重 |
矩阵相乘(Additive Attention) | 通过向量拼接或其他方式计算注意力权重 | |
Cos 相似度 | 使用余弦相似度计算注意力权重 | |
模型结构 | One-Head Attention | 单个注意力头 |
Multi-layer Attention | 多层堆叠的注意力机制 | |
Multi-head Attention | 多个注意力头并行计算,每个头捕获不同的特征空间 |
之所以要引入 Attention 机制,主要是3个原因:
参数少:模型复杂度跟 CNN、RNN 相比,复杂度更小,参数也更少。所以对算力的要求也就更小。
速度快:Attention 解决了 RNN 不能并行计算的问题。Attention机制每一步计算不依赖于上一步的计算结果,因此可以和CNN一样并行处理。
效果好:在 Attention 机制引入之前,有一个问题大家一直很苦恼:长距离的信息会被弱化,就好像记忆能力弱的人,记不住过去的事情是一样的。
Seq2Seq 与Encoder-Decoder
觉得教程里的这段很有意思,所以也贴上来~
Seq2Seq模型是Encoder-Decoder架构的一种具体应用,Seq2Seq 更强调目的,Encoder-Decoder 更强调方法。
Seq2Seq 模型(强调目的):不特指具体方法,而是以满足“输入序列、输出序列”的目的。而 Seq2Seq 使用的具体方法基本都属于Encoder-Decoder 模型(强调方法)的范畴。
Encoder-Decoder(强调方法):将现实问题转化为数学问题,通过求解数学问题,从而解决现实问题。 Encoder 又称作编码器。它的作用就是“将现实问题转化为数学问题”。 Decoder 又称作解码器,他的作用是“求解数学问题,并转化为现实世界的解决方案”。所以它更像一种架构,先把人类世界的问题编码成数学世界的问题,再把输出的答案解码为人类世界的解决方案。
下面大概先根据教程总结一下Encoder-Decoder的流程,再总结一下Seq2Seq的工作流程,具体怎么实施看后面的学习文章啦。
Encoder-Decoder 的流程
1. Encoder 部分:
- 向量化: 输入序列(如单词序列或字符序列)首先通过 Embedding 层映射为高维空间中的稠密向量表示。
- 序列处理:编码器(通常是一个 RNN、LSTM 或 GRU)逐步处理输入序列的每个元素,并在每个时间步生成一个隐状态 h t h_{\text{t}} ht。
- 生成上下文向量:编码器在最后一个时间步输出一个上下文向量 h context h_{\text{context}} hcontext,它是输入序列的浓缩表示,包含了输入的整体信息。
2. Decoder 部分:
- 参数初始化:对W和Bias初始化。参数的初始化通常涉及对它们赋予随机的小数值,以防止网络在训练初期对特定输出产生偏好。常用的初始化策略包括Xavier初始化(适用于Sigmoid或Tanh激活函数)和He初始化(通常用于ReLU激活函数),这两种方法旨在维持各层激活值和梯度的大致稳定性,从而优化训练过程。
- 解码器接收编码器生成的上下文向量 h context h_{\text{context}} hcontext作为初始输入状态。
- 在每个时间步,解码器根据当前的隐状态和上一步的输出(在训练时是目标序列的真实值,在推理时是上一步的预测结果)生成下一个输出。
- 解码过程是自回归的,即解码器的输出会作为下一时间步的输入,直到生成结束标记(EOS)。
3. 输出生成:
- 解码器输出的每个时间步通常经过一个全连接层和 softmax,生成一个概率分布,选择概率最大的词作为输出。
Seq2Seq 的工作流程
-
输入处理
输入序列通过 Embedding 层映射为稠密向量,随后由编码器逐步处理,输出上下文向量。 -
编码阶段(Encoding)
编码器(通常是 RNN、LSTM 或 GRU)对输入序列进行处理,输出一个固定维度的上下文向量 h context h_{\text{context}} hcontext,表示输入序列的整体信息。 -
解码阶段(Decoding)
解码器接收上下文向量并逐步生成输出序列。在每个时间步,解码器根据当前隐状态、上一步的输出以及上下文向量,生成当前时间步的输出。 -
输出处理
解码器输出的每个时间步通过 softmax 转换为概率分布,选择概率最大的词作为当前时间步的输出,直到生成结束标记(EOS)或达到最大长度。
总结
- 输入序列 → 上下文向量 → 输出序列:Seq2Seq 模型通过 Encoder-Decoder 架构实现从输入序列到输出序列的端到端映射。
- 自回归解码:解码器通过自回归方式生成序列,每个时间步依赖上一步的输出。
- 适用于变长序列:Seq2Seq 能够处理不同长度的输入和输出序列,非常适用于机器翻译、文本摘要等任务。
终于写完啦!
标签:Task1,transformer,模型,Attention,输入,Embedding,序列,打卡,向量 From: https://blog.csdn.net/weixin_50513012/article/details/145123638