参考:
1. Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Łukasz Kaiser, and Illia Polosukhin. 2017. Attention is all you need. In Proceedings of the 31st International Conference on Neural Information Processing Systems (NIPS'17). Curran Associates Inc., Red Hook, NY, USA, 6000–6010.
2. https://blog.csdn.net/qq_48314528/article/details/122160800
3. https://blog.csdn.net/yeen123/article/details/125104680
4. https://blog.csdn.net/nocml/article/details/110920221?spm=1001.2014.3001.5502
5. https://www.bilibili.com/video/BV1Di4y1c7Zm/?spm_id_from=333.337.search-card.all.click
学习背景:
专业非NLP非CV,只是学习Transformer模型,理解各部分功能
如果想要深度理解建议仔细阅读以上的参考博客
本博客基本上是论文翻译,可以快速过一遍原论文,代码块中为个人对Transformer模型的理解
如果有理解不当之处,欢迎批评指正!
Transformer的优势:
- Transformer模型架构避免了循环,它完全依赖注意力机制来刻画输入和输出的全局关系,而且能够显著地提高并行化;
- 关联来自两个任意输入或输出位置的信号所需的操作数量随着位置之间距离的增加而增长,这种增长在ConvS2S中是线性的,在ByteNet中是对数的。这使得学习较远位置的相关性很困难。在Transformer中,操作的数量被减少到一个常数,尽管由于平均注意力权重位置而降低了有效分辨率,但是这种影响可以用多头注意力来抵消。
// 此处为个人对Transformer各个组成部分的简单理解
1. Input Embedding / Output Embedding
相当于复制和扩维操作。复制操作是把input复制三份,用来得到Query, Key and Value;扩维操作是
Query, Key and Value扩大为d_model=512维,再与各自的随机矩阵相乘
2. Positional Encoding
因为Transformer是并发处理的并且不包含任何的循环和卷积,所以它不包含单词的顺序关系,但是一
句话中单词的顺序可想而知很重要,我们需要添加位置信息,所以使用正余弦函数来表示位置信息。位置编
码同样是d_model=512维,因此可以与输入直接相加。
3. Multi-Head Attention
多头注意力有三个输入,就是我们上述提到的乘完权重矩阵的并且添加好位置信息的Query, Key and
Value矩阵。其中Q和K的转置相乘,还需要除以sqrt(d_k),作用是分散注意力,更专业的说法是防止d_k过
大,将softmax函数的梯度限制在很小的范围内,这就是缩放点积。softmax是做归一化处理,使矩阵的每一
行相加为1,最后在与矩阵V相乘。这其实是单一注意力,为什么叫多头注意力呢?因为一共是8个同样的单一
注意力并行进行的,也叫线性投影。这8个结果连接起来,乘以投影权重矩阵,得到最后的结果。
4. Add & Norm
Add是把输入和经过函数处理的输出相加,再做Norm处理,例如LayerNorm(x+Multi_Head_Attention)。
Add也叫做残差连接,作用是防止梯度消失。Norm归一化处理分为BN和Transformer使用的LN,BN是CV中常
用的,它针对的是batch_size,LN针对的是seq_len。简单的将BN是把一批样本归一化,而LN是对每一个样
本进行归一化处理,由于输入序列长度并不固定,自然要用LN。
5. Feed Forward
前馈网络,作用是非线性函数拟合数据,它会把d_model=512维转换为d_ff=2048维,所以还需要第二
个前馈网络再转换回512维。
6. Masked Multi-Head Attention
掩盖多头注意力,简单地讲,如果我们要预测位置i的信息,就要屏蔽包括位置i在内之后的信息,即位
置i的预测只能依赖于位置小于i处的已知输出。
一 编码器和解码器栈
-
编码器:编码器由 N = 6 N = 6 N=6个相同层的堆栈组成。每层有两个子层,第一个子层是多头自注意力机制,第二个子层是位置全连接前馈网络。两个子层都有一个残差连接并进行归一化处理,所以每个子层的输出就是 L a y e r N o r m ( x + S u b l a y e r ( x ) ) LayerNorm(x + Sublayer(x)) LayerNorm(x+Sublayer(x))。为了方便残差连接,模型中的所有子层和嵌入层的输出的维度都是512,即 d m o d e l = 512 d_{model} = 512 dmodel=512。
-
解码器:解码器也由 N = 6 N = 6 N=6个相同层的堆栈组成。除了编码器中的两个子层外,解码器还增加了第三个子层,它对编码器堆栈的输出执行多头注意力。解码器的每个子层同样有残差连接和归一化处理。修改了解码器堆栈中的自注意力子层来防止位置关注后续位置,即确保位置 i i i的预测只能依赖于位置小于 i i i处的已知输出。
二 注意力
\quad\quad
注意力函数可以被描述为将
q
u
e
r
y
query
query和一组
k
e
y
−
v
a
l
u
e
p
a
i
r
s
key-value\,pairs
key−valuepairs映射到输出,其中
q
u
e
r
y
,
k
e
y
s
,
v
a
l
u
e
s
a
n
d
o
u
t
p
u
t
query, keys, values\,and\,output
query,keys,valuesandoutput都是向量。输出是
v
a
l
u
e
s
values
values的权重和,分配给每个
v
a
l
u
e
value
value的权重是通过
q
u
e
r
y
query
query和相应
k
e
y
key
key的兼容性函数计算的。
-
缩放点积注意力:输入由 d k d_k dk维的 q u e r i e s a n d k e y s queries\,and\,keys queriesandkeys和 d v d_v dv维的 v a l u e s values values组成。计算 q u e r y query query和所有 k e y s keys keys的点积,除以 d k \sqrt{d_k} dk,并且使用 s o f t m a x softmax softmax函数来获得 v a l u e s values values上的权重。实际上,同时在一组 q u e r i e s queries queries计算注意力函数,存放在矩阵 Q Q Q中。 k e y s keys keys和 v a l u e s values values同样存放在矩阵 K K K和 V V V之中。
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V) = softmax(\frac{Q{K^T}}{\sqrt{d_k}})V Attention(Q,K,V)=softmax(dkQKT)V
两个最常用的注意力函数是加法注意力和点积注意力。加法注意力使用具有单个隐藏层的前馈网络来计算兼容性函数。两者在理论复杂性上相似,但是点积注意力在实践中更快,空间效率更高,因为可以使用高度优化的矩阵乘法代码来实现。
如果 d k d_k dk的值很小的话,两种机制的表现不相上下,在不缩放较大 d k d_k dk的情况下,加法注意力要优于点积注意力。对于 d k d_k dk的较大值,点积的大小会变大,从而将 s o f t m a x softmax softmax函数推到梯度极小的区域,为了抵消这种影响,将点积缩放到原来的 1 d k \frac{1}{\sqrt{d_k}} dk1。 -
多头注意力
与使用 d m o d e l d_{model} dmodel维 k e y s , v a l u e s a n d q u e r i e s keys,\,values\,and\,queries keys,valuesandqueries的单个注意力函数不同,将 q u e r i e s , k e y s a n d v a l u e s queries,\,keys\,and\,values queries,keysandvalues进行 h h h次线性投影到 d k , d k a n d d v d_k,\,d_k\,and\,d_v dk,dkanddv维是有益的,然后并行执行注意力函数,产生 d v d_v dv维输出值,这些值被连接起来并再次投影以得到最终值,如图2所示。
多头注意力允许模型在不同位置共同关注来自不同表示子空间的信息。对于单一的注意力头,平均值可以起到抑制作用。
M u l t i H e a d ( Q , K , V ) = C o n c a t ( h e a d 1 , . . . , h e a d h ) W O MultiHead(Q,K,V) = Concat(head_1,...,head_h)W^O MultiHead(Q,K,V)=Concat(head1,...,headh)WO
w h e r e h e a d i = A t t e n t i o n ( Q W i Q , K W i K , V W i V ) where\,\, head_i = Attention(Q{W_i^Q},K{W_i^K},V{W_i^V}) whereheadi=Attention(QWiQ,KWiK,VWiV)
其中投影是参数矩阵 W i Q ∈ R d m o d e l × d k , W i K ∈ R d m o d e l × d k , W i V ∈ R d m o d e l × d v a n d W O ∈ R h d v × d m o d e l W_i^Q\in R^{d_{model}\times d_k},W_i^K\in R^{d_{model}\times d_k},W_i^V\in R^{d_{model}\times d_v}\,and\,W^O\in R^{hd_v\times d_{model}} WiQ∈Rdmodel×dk,WiK∈Rdmodel×dk,WiV∈Rdmodel×dvandWO∈Rhdv×dmodel。采用 h = 8 h = 8 h=8并行注意力层或者头,使用 d k = d v = d m o d e l / h = 64 d_k = d_v = d_{model}/h = 64 dk=dv=dmodel/h=64。由于每个头部的维度减小,总计算成本与具有全维度的单一注意力相似。
- 注意力的应用:Transformer采用三种不同的方式使用多头注意力。
在编码器-解码器注意力层, q u e r i e s queries queries来自之前的解码器层, k e y s a n d v a l u e s keys\,and\,values keysandvalues来自编码器的输出,这允许解码器中的每个位置在输入序列中的所有位置上出现。
编码器包含自注意力层。在自注意力层,所有的 k e y s , v a l u e s a n d q u e r i e s keys,\,values\,and\,queries keys,valuesandqueries都来自编码器的前一层,编码器中的每个位置都可以关注编码器前一层中的所有位置。
解码器中的自注意力层允许解码器中的每个位置关注解码器中直到并包括该位置的所有位置。需要防止解码器中的向左信息流,以保持自回归特性。通过屏蔽 s o f t m a x softmax softmax输入中对应于非法连接的所有值来实现缩放点积注意力的内部。
三 位置前馈网络
\quad\quad
除了注意力子层之外,编码器和解码器中的每个层都包含一个完全连接的前馈网络,该网络分别且相同地应用于每个位置。这包括两个线性变换,其间由
R
e
L
U
ReLU
ReLU激活。
F
F
N
(
x
)
=
m
a
x
(
0
,
x
W
1
+
b
1
)
W
2
+
b
2
FFN(x) = max(0,xW_1 + b_1)W_2 + b_2
FFN(x)=max(0,xW1+b1)W2+b2
虽然线性变换在不同位置上是相同的,但是它们在不同层之间使用不同的参数。另一种描述方式是两个内核大小为1的卷积。输入和输出的维度是
d
m
o
d
e
l
=
512
d_{model} = 512
dmodel=512,内层的维度
d
f
f
=
2048
d_{ff} = 2048
dff=2048
四 嵌入和Softmax
\quad\quad
与其他序列传导模型类似,使用学习嵌入将
i
n
p
u
t
t
o
k
e
n
s
input\,tokens
inputtokens和
o
u
t
p
u
t
t
o
k
e
n
s
output\,tokens
outputtokens转换为
d
m
o
d
e
l
d_{model}
dmodel维的向量。使用通常的学习线性变换和
s
o
f
t
m
a
x
softmax
softmax函数将解码器的输出转换为预测
n
e
x
t
−
t
o
k
e
n
next-token
next−token的概率。在两个嵌入层和预
s
o
f
t
m
a
x
softmax
softmax线性变换之间共享相同的权重矩阵,在嵌入层,将权重乘以
d
m
o
d
e
l
\sqrt{d_{model}}
dmodel。
五 位置编码
\quad\quad
因为模型不包含循环和卷积,为了让模型利用序列的顺序,必须加入一些关于序列中
t
o
k
e
n
s
tokens
tokens的相对或者绝对位置信息。为此,在编码器和解码器堆栈底部的输入嵌入中添加位置编码。位置编码与嵌入具有相同的维度
d
m
o
d
e
l
d_{model}
dmodel,因此可以将两者相加。使用不同频率的正弦和余弦函数:
P
E
(
p
o
s
,
2
i
)
=
s
i
n
(
p
o
s
/
1000
0
2
i
/
d
m
o
d
e
l
)
PE_{(pos,2i)} = sin(pos/10000^{2i/d_{model}})
PE(pos,2i)=sin(pos/100002i/dmodel)
P
E
(
p
o
s
,
2
i
+
1
)
=
c
o
s
(
p
o
s
/
1000
0
2
i
/
d
m
o
d
e
l
)
PE_{(pos,2i + 1)} = cos(pos/10000^{2i/d_{model}})
PE(pos,2i+1)=cos(pos/100002i/dmodel)