这个算是在课程学习之外的探索,不过希望能尽快用到项目实践中。在文章里会引用较多的博客,文末会进行reference。
搜索Transformer机制,会发现高分结果基本上都源于一篇论文Jay Alammar的《The Illustrated Transformer》(图解Transformer),提到最多的Attention是Google的《Attention Is All You Need》。
- 对于Transformer的运行机制了解即可,所以会基于这篇论文来学习Transformer,结合《Sklearn+Tensorflow》中Attention注意力机制一章完成基本的概念学习;
- 找一个基于Transformer的项目练手
3.Transformer的一些笔记
今天的文本来自《聊聊 Transformer》https://zhuanlan.zhihu.com/p/47812375 最近学习都会围绕Transformer进行,就算我不会推导公式,但是大致原理要懂,然后找一个demo实现能对得上。
同样也是介绍了Transformer的架构,但是这篇文章拆解得更加清晰。
Encoder
在google论文中,Encoder和Decoder都是由6层相同的层组成。Encoder每一层由2部分构成。
- multi-head self-attention
- position-wise feed-forward network
这两部分由一个残差连接(residual connection),然后接Layer Normalization。
Decoder
- multi-head self-attention mechanism
- multi-head context-attention mechanism
- position-wise feed-forward network
和Encoder一样也是由残差连接,最后接一个Layer Normalization。
注意Decoder和Encoder不同的地方在 multi-head context-attention mechanism
在接下来的三个小节,是从Attention-> self-sttention-> scaled dot-product attention,很细心。
Attention
Attention是Encoder层的输出经过加权平均后再输入到Decoder层中。它主要应用在 seq2seq 模型中,这个加权可以用矩阵来表示,也叫 Attention 矩阵。它表示对于某个时刻的输出 y,它在输入 x 上各个部分的注意力。这个注意力就是我们刚才说到的加权。
attention分为“乘性attention”和“加性attention”
self-attention
attention机制有两个隐状态,和,而self-attention实际上输出序列就是输入序列。因而自己计算自己的 attention 得分。
context-attention
context-attention 是 encoder 和 decoder 之间的 attention,是两个不同序列之间的attention,与来源于自身的 self-attention 相区别。
不管是哪种 attention,我们在计算 attention 权重的时候,可以选择很多方式,常用的方法有additive attention、local-base attention、general attention、dot-product attention、scaled dot-product attention(我一个都没听说过……)
Transformer模型采用的是最后一种scaled dot-product attention
scaled dot-product attention
为什么使用scaled dot-product attention。Google给出的解答就是上一节的Q(Query)、V(Value)、K(Key),注意看看这里的描述。通过query和key的相似性程度来确定value的权重分布。
scaled dot-product attention 和 dot-product attention 唯一的区别就是,scaled dot-product attention 有一个缩放因子, 叫。这个在上一节中也有提到,我略过了,因为没有看懂。 表示 Key 的维度,默认用 64。
对于很大的时候,点积得到的结果维度很大,使得结果处于softmax函数梯度很小的区域。这时候除以一个缩放因子,可以一定程度上减缓这种情况。
multi-head attention
论文提到,他们发现将 Q、K、V 通过一个线性映射之后,分成 h 份,对每一份进行 scaled dot-product attention 效果更好。
然后,把各个部分的结果合并起来,再次经过线性映射,得到最终的输出。
这就是所谓的 multi-head attention。上面的超参数 h 就是 heads 的数量。论文默认是 8。
Layer normalization
normaliztion的目标是把输入转化为均值为0,方差为1的数据。
说到 normalization,那就肯定得提到 Batch Normalization。
BN 的主要思想就是:在每一层的每一批数据上进行归一化。我们可能会对输入数据进行归一化,但是经过该网络层的作用后,我们的数据已经不再是归一化的了。随着这种情况的发展,数据的偏差越来越大,反向传播需要考虑到这些大的偏差,这就迫使我们只能使用较小的学习率来防止梯度消失或者梯度爆炸。
BN 的具体做法就是对每一小批数据做归一化。
而Layer normalization也是归一化数据的一种方式,不过LN是在每一个样本上计算均值和方差,而不是 BN 那种在批方向计算均值和方差。
Mask
mask 表示掩码,它对某些值进行掩盖,使其在参数更新时不产生效果。Transformer 模型里面涉及两种 mask,分别是 padding mask 和 sequence mask。
- padding mask 在所有的 scaled dot-product attention 里面都需要用到
- sequence mask 只有在 decoder 的 self-attention 里面用到。
padding mask,每个批次输入序列长度是不一样的,要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充 0。因为这些填充的位置,其实是没什么意义的,所以我们的 attention 机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。
具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样的话,经过 softmax,这些位置的概率就会接近0。而Transformer的 padding mask 实际上是一个张量,每个值都是一个 Boolean,值为 false 的地方就是我们要进行处理的地方。
文章前面也提到,sequence mask 是为了使得 decoder 不能看见未来的信息。也就是对于一个序列,在 time_step 为 t 的时刻,我们的解码输出应该只能依赖于 t 时刻之前的输出,而不能依赖 t 之后的输出。因此我们需要想一个办法,把 t 之后的信息给隐藏起来。
那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为 1,下三角的值权威0,对角线也是 0。把这个矩阵作用在每一个序列上。(同样没看懂具体的实现方式)
Positional Embedding
现在的 Transformer 架构还没有提取序列顺序的信息,这个信息对于序列而言非常重要,如果缺失了这个信息,可能我们的结果就是:所有词语都对了,但是无法组成有意义的语句。为了解决这个问题。论文使用了 Positional Embedding:对序列中的词语出现的位置进行编码。
在实现的时候使用正余弦函数。
Position-wise Feed-Forward network
这是一个全连接网络,包含两个线性变换和一个非线性函数(实际上就是 ReLU)。
这个线性变换在不同的位置都表现一样,并且在不同的层之间使用不同的参数。这里实现上用到了两个一维卷积。
网友评论