我在学习Transformer时,想要更快地学会,所以先在CSDN上搜博客看,有的讲的太冗杂不够精简透彻啥都讲讲抓不住重点,有的又看不太懂,后来去看了李沐老师的讲解,感觉非常到位,但中间还是有一些疑问,发这篇博客是想整理一下Transformer的学习过程,以及记录一下产生的疑问和学习。
整篇博客是参考沐神讲Transformer,按照 Attention Is All You Need 的结构写的,省去了实验和分析部分。
参考论文:Attention Is All You Need
摘要
提出了一种新的简单网络架构——Transformer,它完全基于注意力机制,而不使用循环或者卷积神经网络,并且在机器翻译任务上取得了更好的性能。
1.导言
-
主流的序列模型:RNN、LSTM、GRU,它们存在问题:
-
历史信息是一步一步向后传递的,当时序比较长时,早期的时序信息在后面的时候可能会被丢掉(长期依赖问题)。
-
当前时刻的隐藏状态 依赖于上一时刻的隐藏状态 和当前输入 。
-
-> 计算 的时候需要保证 输入完成
-> 无法并行
-> 计算性能差
-
注意力机制备受瞩目,但更多是与RNN结合使用,使encoder的输出有效的传递给decoder 。
-
Transformer完全基于注意力机制,具有较高的并行度,能在较短的时间内获得更好的结果。
2.相关工作
-
CNN替代RNN处理时序的问题
-
缺点:感受野小,难以对长序列建模。
-
优点:有多个输出通道,提取不同特征。
-
对于缺点:
Transformer的注意力机制每次可以看到整个序列。
对于优点:
Transformer中用Multi-Head Attention。
取其精华,弃其糟粕!
3.模型架构
这块是重中之重。
3.1Encoder-Decoder结构
Encoder-Decoder 结构不是一种算法,而是一种框架。
Encoder
将输入 编码成 。
Decoder
利用编码器的输出 生成输出序列 。
解码器这里还有一个自回归性(auto-regressive):
过去时刻的输出当做当前时刻的输入
...以此类推
这里有两个小点需要注意:
编码器输入序列和解码器输出序列长度不行一定相等。
解码器的词是一个一个生成的,而在编码器中一次性能看全整个句子。
Transformer 使用 encoder-decoder 结构。
3.2Tranformer结构
下图为 Transformer 的模型架构
接下来就一点点阐述每个模块都是干什么的。
3.2.1Encoder和Decoder块
Encoder
Encoder 部分由 个一模一样的层组成,其中每个层包含两个子层,第 1 个子层是多头注意力机制,第 2 个子层是 MLP 。对每一个子层使用残差连接,最后使用 LayerNorm 。
是不是有人不懂什么是多头注意力机制?没关系,这里只是让你对大概得模型架构有个认识,后面会仔细讲每一个小模块的。
每一个子层可以概括为:
指的就是图里的Add&Norm中的Norm, 指的是图里的Add&Norm中的Add, 在第 1 层指的就是 Multi-Head Attetion ,在第二层指的就是 Feed Forward ,这样用公式表达,整个 Encoder 的结构就变得很清楚了。
Decoder
Decoder由 个一模一样的层组成,其中每个层包含三子层,第 2 层和第 3 层与编码器的 1、2 层相同。在解码器预测的时候 时刻的输出不应该看到 时刻之后的输出,为了保证自回归特性,解码器的第 1 层是一个带掩码的多头注意力机制。
我看到这里时就产生了疑问,不是做预测吗,为什么解码器会看到之后的信息?
训练:在训练时,解码器的输入是完整的正确的翻译后的句子,比如:“I love China forever.”的翻译是“我永远爱中国。”,那么编码器的输入是“I love China forever.”,而解码器的输入是“我永远爱中国。”,如果想要预测“永远”,那么解码器的输入就不应该有“爱中国”,所以需要掩码。在Transformer的训练阶段,只会根据已知信息预测下一个词而不是一整句话,通过对比预测的词和应该翻译成的词的差距更新参数。
推理:而在推理时,还以刚刚的例子为例,解码器从<start>开始逐步生成,第一步生成“我”,第二步基于“我”生成“永远”,第三步基于“我 永远”生成“爱”......以此类推。
3.2.2注意力机制
Scaled Dot-Product Attention
再学习这个部分之前,先来了解三个向量:
-
Q(Query)查询向量:Query 是用于查找相关信息的向量。在自注意力机制中,Query向量来自输入序列中的某个词表示。
-
K(Key)键向量:Key 是与Query进行相似性比较的向量。每个输入序列中的词都有一个Key向量,表示该词在输入序列中的特征。
-
V(Value)值向量:Value 是最终将被加权并用于生成输出的表示向量。每个词对应一个Value向量,它代表了输入词的内容或特征。
我直接就把这个部分的公式甩出来:
然后再一点点讲这个公式在做什么。
先对注意力机制有个大概的认知。前一段网上不是有个特别火的挑战,就是一个人让另一个人看一段视频,然后问她一个特别不起眼的东西,基本上是不会有人回答出来的,因为人的注意力总是放在更突出的地方。注意力机制就是模拟人的注意力,权重会更多地分配给跟查询向量强相关的向量,而分配更小的权重给跟查询向量不那么相关的向量。
表示的就是 和 中每个词(这里说每个词是便于理解,实际上是向量)的相关性, 后面再解释,加上 之后就表示权重,最后再乘 ,这样下来注意力就分配完成了。
现在解决两个疑问:
点积为什么能表示相似度?
余弦相似度:
-
当 时,两个向量方向完全相同,点积达到最大值,说明这两个向量非常相似。
-
当 时,两个向量正交,点积为零,表示它们没有相似性。
-
当 时,两个向量方向完全相反,点积为负,表示它们极不相似。
因此,点积可以用来衡量两个向量的方向相似性,方向越接近,相似度越高。
为什么要除以?
当 比较大的时候,两个向量做点积的值也可能会比较大,此时点积值之间的差距可能会比较大,导致值最大的经过softmax后更加接近 1 ,而剩下的值更加接近 0 ,此时梯度值比较小,可能会导致不再更新。
不知道大家注意到没,Scaled Dot-Product Attention图中还有一个叫“Mask”的块,前面已经讲过为什么要有Mask,下面就讲讲Mask到底是怎么做的。
Mask对于 和 及其之后的值换成非常大的负数,经 softmax 之后权重就会变成 0 ,这样就不会将注意力放在它们身上。
Multi-Head Attention
我们来看一下 Multi-Head Attention 在做什么。
做 次 Scaled Dot-Product Attention 后合并在一起再做一次线性投影。
where
作者选择 ,那么 。
为什么用Multi-Head Attention?
Scaled Dot-Product Attention没有可学习的参数。
我的理解是 层就像 个卷积核,不同卷积核学习的特征不一样, 层每一层学习的特征也不一样。
Transformer结构中的注意力机制
-
在编码器的sub-layer1中
-
在解码器的sub-layer1中
-
在解码器的sub-layer2中:Key和Value来自编码器的输出,Query来自输入解码器后经过一个带掩码的注意力机制(自注意力机制)后的输出。
到这里,比较困难的地方就结束啦。
3.2.3Position-wise Feed-Forward Networks
这部分其实就是把一个MLP对每一个词作用一次,对每一个词作用的是同一个MLP。
维度从512 -> 2048 -> 512。
3.2.4Embeddings and Softmax
Embeddings将输入的一个一个词转换成向量,Softmax就不多赘述了。
3.2.5Positional Encoding
注意力机制不会考虑序列信息,意味着给一句话,把词的顺序任意打乱最后输出的结果都是一样的,所以需要添加时序信息。
到这里我就梳理完了,肯定还是有些地方没说清楚,欢迎评论区讨论!
拜拜拜拜啦。