跟着问题学18——大模型基础transformer模型详解(4)解码器
3 Decoder层
图中可以看到,解码器Decoder其实和编码器Encoder大同小异,核心区别是在最下面额外多了一个掩码多头注意力层masked mutil-head attetion。在解码器中,自注意力层仅被允许“注意”输出序列中前面的单词信息。这是通过在自注意力计算中的softmax步骤之前屏蔽未来位置(将其设置为-inf)来完成的。 下面我们详细介绍一下各部分,尤其是差异点。
3.1 Decode的输入
从图中可以看到,解码器的输入来源有2个,一个是掩码后的词向量+位置编码向量,经由掩码自注意力层和残差正则化传递;第二个输入则是解码层中最后一个解码器的输出,储存着编码层的全部信息(类似seq2seq框架的中间向量)。二者结合经过解码器-编码器的注意力层,再经由残差正则化传递给前馈网络层,再次经由残差正则化结构传递给下个解码器,直至最后的输出。
3.2 Mask
接着我们学习一下Mask机制。Mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。它经常被用于NLP任务中,按照作用总体来说可以分成两类:
- 用于处理非定长序列的padding mask;
- 用于防止标签泄露的sequence mask。
Transformer中同时用到了这两种Mask机制。
其中,padding mask 在所有的 scaled dot-product attention 里面都需要用到(包括前面的编码器),而 sequence mask 只有在解码器decoder 的 self-attention 里面用到。
padding mask
在NLP任务中,文本通常是不定长的,计算注意力得分时attention score会出现偏差,所以在输入一个样本长短不一的批量数据batch(这里的batch指有多个句子)到网络前,要对batch中的样本进行truncating截断/padding补齐操作,以便能形成一个张量的形式输入网络,如下图所示。
具体的做法是,对于一个长度不足的样本,往往采用特殊字符"<PAD>"进行padding,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0!在训练时利用Mask矩阵将补全的位置给mask掉。Mask矩阵中可以用1表示有效字,0代表无效字(也可以用True/False)。值为 false 的地方就是我们要进行处理的地方,也就是说输出矩阵和Mask矩阵为false的对应位置处补一些无穷小(负无穷)的值。
分为如下两步:
1)padding(补齐)操作在batch输入网络前完成,同步生成padding mask矩阵(用于记录后续输出矩阵需要mask的位置);
2)根据padding mask矩阵,Q和K在点积之后,需要先经过mask,将输出矩阵和Mask矩阵为false的对应位置处补一些无穷小(负无穷)的值,再进行softmax.
def attention(query, key, value, mask=None, dropout=None): |
sequence mask
sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。最常见的应用场景是在需要预测下一个词的时候,如果用self attention 或者是其他同时使用上下文信息的机制,会导致模型”提前看到“待预测的内容,这显然不行,所以为了不泄露要预测的标签信息,需要想一个办法,把 t 之后的信息给隐藏起来,就需要 mask 来“遮盖”它。
那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0。把这个矩阵作用在每一个序列上,就可以达到我们的目的。
如下图所示,这也是Transformer中Decoder的Masked Multi-Head self-attention使用的Mask机制。
- 对于 decoder 的 self-attention,里面使用到的 scaled dot-product attention,同时需要padding mask 和 sequence mask 作为 attn_mask,具体实现就是两个mask相加作为attn_mask。
- 其他情况,attn_mask 一律等于 padding mask。
除了在decoder部分加入mask防止标签泄露以外,还有模型利用这种填空机制帮助模型学的更好,比如说BERT和ERNIE模型中利用到的Masked LM(MLM)。(注意:BERT模型只有Transformer的Encoder层,是可以学习上下文信息的)
3.3 Decoder
“编码器-解码器-注意力”层的工作原理与多头自注意力类似,只是它从下面的解码器创建查询矩阵,并从编码器堆栈的输出中获取键和值矩阵。编码器通过处理输入序列,然后将顶部编码器的输出转换为一组注意向量k和v。
每个解码器将在其“encoder-decoder attention”层中使用这些注意向量,这有助于解码器将注意力集中在输入序列中的适当位置。
解码阶段的每个步骤从输出序列(本例中为英语翻译句)输出一个元素。
以下步骤重复此过程,一直到达到表示解码器已完成输出的符号。每一步的输出在下一个时间步被送入底部解码器,解码器像就像我们对编码器输入所做操作那样,我们将位置编码嵌入并添加到这些解码器输入中,以表示每个字的位置。
3.4 输出层linear 和softmax
解码器堆栈输出一个浮点向量。我们如何将其转化为一个词?这是最后一个线性层的工作,后面是Softmax层。假如我们的词典是1w个词,那最终softmax会输入1w个词的概率,概率值最大的对应的词就是我们最终的结果。
线性层是一个简单的全连接神经网络,它将解码器堆栈产生的向量投影到一个更大的向量中,称为logits向量。
让我们假设我们的模型知道10000个独特的英语单词(我们模型的“输出词汇表”),这些单词是从训练数据集中学习的。这将使logits矢量宽度为10000个单元格——每个单元格对应一个唯一单词的分数。这就是我们解释线性层后面的模型输出的方式。
softmax层然后将这些分数转换为概率(全部为正,加起来为1.0)。选择具有最高概率的单元,并产生与其相关联的字作为该时间步长的输出。
4 网络模型框架小结
5 模型训练
现在我们已经通过一个经过训练的Transformer介绍了整个前向传递过程,最后看看模型是如何训练的。
在训练过程中,未经训练的模型会经历完全相同的正向传递。但由于我们在标记的训练数据集上训练它,我们可以将其输出与实际的正确输出进行比较。
为了形象化这一点,假设输出词汇表只包含六个单词(“a”、“am”、“i”、“thanks”、“student”和“<eos>”(“句末”的缩写))。
一旦我们定义了输出词汇表,我们就可以使用相同宽度的向量来指示词汇表中的每个单词。这也被称为一个热编码。例如,我们可以使用以下向量来表示单词“am”: 注意这里的独热编码是监督量,实际上是和decoder层最后softmax输出的预测概率向量作比较的。
示例:我们的输出词汇表的一个热门编码
再讨论一下模型的损失函数——我们在训练阶段优
假设我们正在训练我们的模型。假设这是我们在培训阶段的第一步,我们正在以一个简单的例子进行培训——将“merci”翻译成“谢谢”。
这意味着,我们希望输出是一个概率分布,表示单词“谢谢”。但由于这个模型还没有经过训练,目前还不太可能实现。
由于模型的参数(权重)都是随机初始化的,(未经训练的)模型为每个单元/单词产生具有任意值的概率分布。我们可以将其与实际输出进行比较,然后使用反向传播调整模型的所有权重,使输出更接近所需输出。
你如何比较两种概率分布?我们只是从另一个中减去一个。
但请注意,这是一个过于简单化的例子。更现实地说,我们将使用比一个单词更长的句子。例如,输入:“je suisétudant”,预期输出:“我是一名学生”。这真正意味着,我们希望我们的模型连续输出概率分布,其中:
每个概率分布由宽度为vocab_size的矢量表示(在我们的示例中为6,但更实际的是一个类似30000或50000的数字)
第一个概率分布在与单词“i”相关联的单元处具有最高概率
第二个概率分布在与单词“am”相关联的单元格处具有最高概率
依此类推,直到第五个输出分布指示“<句子结束>”符号,该符号也有一个与10000元素词汇表中的单元格相关联。
我们将在一个样本句子的训练示例中针对目标概率分布来训练我们的模型。
在足够大的数据集上训练模型足够长的时间后,我们希望产生的概率分布如下所示:
希望通过培训,该模型能够输出我们期望的正确翻译。当然,这并不能真正表明这个短语是否是训练数据集的一部分(请参阅:交叉验证)。请注意,每个位置都有一点概率,即使它不太可能是该时间步长的输出——这是softmax的一个非常有用的特性,有助于训练过程。
现在,因为模型一次产生一个输出,我们可以假设模型从概率分布中选择概率最高的单词,然后扔掉其余的。这是一种方法(称为贪婪解码)。另一种方法是抓住前两个单词(例如“I”和“a”),然后在下一步中运行模型两次:一次假设第一个输出位置是单词“I”,另一次假设第二个输出位置为单词“a”,无论哪个版本在考虑位置#1和#2的情况下都会产生较小的错误。我们对位置#2和#3重复此操作…等。这种方法被称为“波束搜索”,在我们的例子中,beam_size是两个(意味着在任何时候,两个部分假设(未完成的翻译)都保存在内存中),而top_beams也是两个(这意味着我们将返回两个翻译)。这两个超参数都可以进行实验。
参考资料
http://jalammar.github.io/illustrated-transformer/
李宏毅transformer视频课程
https://zhuanlan.zhihu.com/p/338817680
Transformer:注意力机制(attention)和自注意力机制(self-attention)的学习总结_注意力机制和自注意力机制-CSDN博客
10.1. 注意力提示 — 动手学深度学习 2.0.0 documentation
跟着问题学18——万字长文详解Transformer-CSDN博客
【深度学习】batch normalization和layer normalization区别_layer normalization和batch normaliza