本文主要介绍理论基础:
1.网络的输入与输出:
我们知道,在深度学习中,常见的输入数据类型有图片、向量、序列。我们考虑,如何用数据表示文字(而文字实质上是一种序列),即如何将文字编码为向量?
A.与图片一样的思路,考虑独热编码(One-hot Encoding),但值得注意的是,此法 一.会带来大量的参数,从而导致空间开销大 二.对于文本来说,顺序也具有具体意义,而独热编码则无法体现这种关系 。
故我们引入B. 词嵌入(Word Embeddings),将词映射到低维连续向量空间,捕捉语义信息。具体的实现手段我们则采用Word2Vec来实现(这里暂不解释,具体原理可以参考 https://zhuanlan.zhihu.com/p/36312907)
下面给出NLP中常见的数据输出类型:1.每个词均有对应的1个值输出 2.所有词对应输出1个值 3.输入输出长度并不对应
2.处理序列数据:
我们知道,文本实际上是一种序列,词与词对应不同的前后关系往往有不同的语义。考虑到这种关系,我们引入3种模型:
A.循环神经网络(RNN)
其核心思想是通过 循环结构 捕捉序列中的时间依赖关系,并采用隐藏状态 ℎ𝑡作为记忆单元用于存储和传递序列信息,缺点:不适用于处理长序列
B.长短期记忆网络(LSTM)
在RNN的基础上过引入 门控机制 解决梯度消失问题和长期依赖问题,其核心结构:
1.遗忘门(Forget Gate):决定哪些信息需要遗忘。
2.输入门(Input Gate):决定哪些新信息需要存储。
3.输出门(Output Gate):决定哪些信息需要输出
但与此同时,门控机制也增加了计算量。并且,无论是RNN还是LSTM,它们都面临着只能进行串行计算的问题,从而引出了我们的重点学习对象:
C.自注意力机制(Self-attention)
它是 Transformer 架构 的核心组件,也是 BERT 模型的基础。它通过计算输入序列中每个元素与其他元素的相关性,捕捉上下文信息。
具体的,
(1) 输入表示
- 输入是一个序列
,其中
是第 𝑖 个元素的向量表示。
- 通过线性变换生成 查询向量(Query)、键向量(Key) 和 值向量(Value):
其中 是可学习的权重矩阵。
值得注意是:Q、K、V是不同的权重矩阵,而非同一个。其原因在于Q矩阵表示当前关注的内容,而K矩阵则表示可供我们关注内容,给予不同的权重矩阵可以表示不同的语义,从而加强模型的表达能力。
(2) 计算注意力分数
- 计算查询向量 Q 和键向量 K 的点积,得到注意力分数矩阵:
- 对注意力分数矩阵进行缩放(除以 𝑑𝑘,其中 𝑑𝑘 是键向量的维度)和 Softmax 归一化:
注:对Attention进行Scale操作的目的是:将点乘结果缩放到一个合理的分布范围内,缓解梯度消失问题。
(3) 加权聚合
- 使用注意力权重对值向量 𝑉 进行加权聚合,得到输出表示:
值得注意的是:
A.模型经过Self-attention后,特征维度不发生变化(具体维度计算在这里不做展示)
B.Transformer计算Attention的过程中,应用的是点乘操作而非加法,是由于:点乘操作可以自然地拓展到高维空间,捕捉到不同特征间的交互关系,加强模型的语义表达能力,适合Transformer这种要处理高维特征的模型
C.Transformer在计算Attention的时候,我们需要对padding(补零)部分进行一个mask(遮盖)操作,其目的是:通过设置一个很大的负值加到点乘结果上,从而使得padding部分的attention score非常小,在softmax操作后无限趋于0,从而减少了padding部分对于我们真正关注部分的attention的干扰(即padding部分的attention,我们是不关注的)
同时,对于自注意力机制,为增强模型的表达能力,我们通常采用多头自注意力机制(Multi-Head Self-Attention):
- 将查询向量、键向量和值向量分别拆分为多个头(如 4个 or 8 个)。
- 对每个头独立计算自注意力。
- 将多个头的输出拼接起来,通过线性变换得到最终输出
相比与RNN、LSTM,Self-Attention机制/Transformer模型具有以下优势:
- 捕捉长距离依赖:自注意力机制能够直接计算序列中任意两个元素的相关性,不受距离限制。
- 并行计算:自注意力机制可以并行计算,加速训练过程。
- 上下文相关表示:每个元素的表示都考虑了整个序列的上下文信息
不过缺点也比较明显:需要大量数据集和大规模计算资源,计算复杂度随序列长度呈平方级增长
3. Bert与Transformer:
Bert 是基于 Transformer 编码器 的预训练语言模型,而 Transformer 的核心组件就是自注意力机制。所以说,Bert与自注意力机制也是息息相关。我们分两部分介绍Bert模型与Transformer模型
Bert:
下面先介绍Bert的架构与预训练任务:
一、Bert的架构:
(1) 输入表示
BERT 的输入是一个序列(如句子或句子对),通过以下三种嵌入表示:
- 词嵌入(Token Embeddings):
- 将每个词转换为固定维度的向量。
- 使用 WordPiece 分词器将词汇表外的词拆分为子词。
- 位置嵌入(Position Embeddings):
- 表示词在序列中的位置信息。
- 由于 Transformer 本身没有位置信息,位置嵌入是必要的。
- 段落嵌入(Segment Embeddings):
- 用于区分句子对中的两个句子(如问答任务中的问题和答案)。
- 对于单句任务,段落嵌入可以忽略。
输入表示的计算公式为:
Input = Token Embeddings + Position Embeddings + Segment Embeddings
ps:Transformer中没有segment embedding这一部分。
这里给出考虑加入位置信息的原因:将位置信息嵌入到每个词的嵌入向量之中,可以使得模型捕捉到输入序列的顺序。
(2) Transformer 编码器
Bert 使用多层 Transformer 编码器(注:Transformer由编码器与解码器组成)堆叠而成,每层包含以下组件:
- 多头自注意力机制(Multi-Head Self-Attention):
- 计算每个词与其他词的相关性,捕捉上下文信息。
- 通过多个注意力头(如 12 个)并行计算,增强模型的表达能力。(解释:每一个注意力头代表一套对应的可学习权重矩阵Q、K、V,也对应了一个子空间,多头即可表示多个不同子空间,使得transformer可以注意到输入序列的不同部分,从而加强模型的泛化能力;另一方面,多头也可以缓解单头带来的维度过高问题)
- 前馈神经网络(Feed-Forward Network, FFN):
- FFN主要是对自注意力机制的输出进行非线性变换。(实际上和全连接层效果差不多)
- FFN的结构有2层线性网络,第一层先将输入维度拓展到一个较大维度,第二层再将大维度压缩回原有维度。
- FFN中的激活函数常是ReLU或GeLU,ReLU计算简单,但容易引发神经元死亡问题;GeLU平滑且非线性强,但计算稍微复杂)
- 残差连接和层归一化(Residual Connection & Layer Normalization):
- 残差连接缓解梯度消失问题。
- 层归一化加速训练过程(LayerNorm是在残差连接后进行归一化)。(注:使用LayerNorm而不是BatchNorm,是由于:BatchNorm依赖于批量统计,在变长序列和小批量上训练效果不是很理想;而LayerNorm则是对于每一个批量的样本特征进行一次归一化,适合长序列与在线学习)
(3) 输出表示
Bert 的输出是每个输入词对应的上下文向量表示。对于分类任务,可以使用第一个词([CLS]
)的向量作为整个序列的表示。
除此之外,还可以考虑采取平均池化、最大池化与其他方式处理后输出(并不常用)。
二、Bert的预训练任务
Bert 通过以下两个任务进行预训练:
(1) 掩码语言模型(Masked Language Model, MLM)
- 目标:通过上下文预测被掩盖的词。
- 方法:
- 随机掩盖输入文本中的部分词(如 15%)。
- 被掩盖的词替换为特殊标记
[MASK]
。 - 模型通过上下文预测被掩盖的词。
- 示例:
- 输入:
The [MASK] is on the table.
- 输出:
The cat is on the table.
- 输入:
(2) 下一句预测(Next Sentence Prediction, NSP)
- 目标:判断两个句子是否是连续的。
- 方法:
- 输入两个句子,用
[SEP]
分隔。 - 模型预测第二个句子是否是第一个句子的下一句。
- 输入两个句子,用
- 示例:
- 输入:
[CLS] The cat is on the table. [SEP] It is sleeping. [SEP]
- 输出:
IsNextSentence
- 输入:
三、 Bert 的输入格式
Bert 的输入是一个序列,格式如下:
- 单句任务:
[CLS] Sentence A [SEP]
- 句对任务:
-
[CLS] Sentence A [SEP] Sentence B [SEP]
其中:
[CLS]
:分类标记,用于分类任务。[SEP]
:分隔标记,用于区分句子。
四、 Bert 的微调
在预训练完成后,Bert 可以通过微调适应具体任务。微调时,只需在预训练模型的基础上添加一个特定的输出层(如分类头),即可在任务数据上进行训练。
Transformer:
一、整体架构:
下图是对Transformer整体结构的一个表达:
从上图也可以知道,Bert与Transformer其实非常相像,毕竟Bert是基于Transformer的Encoder部分(图中左部)实现的,但是两者之间其实也存在差别。
具体差别如下:
模型 | Transformer | Bert |
架构 | Encoder+Decoder | 仅使用Transformer的Encoder |
目标任务 | 序列到序列任务(如机器翻译) | 自然语言理解任务(如文本分类) |
训练方式 | 端到端训练 | 预训练+微调 |
上下文建模 | 单向或双向(取决于任务) | 双向(MLM+NSP) |
输入的处理 | 需要显式的位置编码 | 使用位置编码+分段嵌入(Sgement Embedding) |
应用 | 文本生成、机器翻译 | 文本分类、实体识别 |
二、Decoder部分
Transformer的Decoder通常是由多个相同的层(Layer)堆叠而成,每层包含以下几个核心组件:
- Mask Self-Attention,遮蔽自注意力机制
模型在生成当前时间的输出时,仅关注已经生成了的部分,而不关心未来信息(通过掩码隐藏)。 每个输入序列的位置不允许访问后续位置的信息。
- Cross-Attention,交叉注意力机制:
这层完成了Transformer中Encoder与Decoder两部分的一个交互。我们知道,Encoder的输出可以用于进行下游任务(回归/分类等),但同时它也可以作为权重矩阵K(键)、V(值)。与此同时,我们将Decoder输出的当前时间步作为权重矩阵Q(查询),确保了解码器本身能够利用编码器的上下文信息。
- FFN,前馈神经网络:
与Encoder中使用的前馈网络类似,该网络通常由两个线性变换和一个激活函数(如ReLU或GELU)组成。其功能主要是进行一个特征的提取。
- 残差连接与层归一化:
每层的输出都通过残差连接相加到输入上,并且经过层归一化,以保持信息的顺畅流动和模型训练的稳定性。
- 生成过程:
在模型训练的过程中,会将真实值(标签)作为当前的输入;而在推理阶段,Decoder则会逐步生成目标序列,直至遇到结束符(EOS)。值得注意的一点是,Decoder的推荐阶段是无法并行生成序列的(由于自回归特性,而自回归是一种生成数据的方式,它的思想就是根据已生成的输出序列逐步预测下一个元素,直到达到一定长度)