Update 2.2-图解transformer.md

修改多出错别字及公式格式错误
This commit is contained in:
luzixiao 2021-09-15 20:55:59 +08:00 committed by GitHub
parent 47daf5c0b8
commit fe30d7b886
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 20 additions and 22 deletions

View File

@ -24,7 +24,7 @@
Transformer模型在2017年被google提出直接基于Self-Attention结构取代了之前NLP任务中常用的RNN神经网络结构并在WMT2014 Englishto-German和WMT2014 English-to-French两个机器翻译任务上都取得了当时的SOTA。
与RNN这类神经网络结构相比Transformer一个巨大的优点是模型在处理序列输入时可以对整个序列输入进行并行计算不需要按照时间步循环递归处理输入序列。2.1章节详细介绍了RNN神经网络如何循环递归处理输入序列欢迎读者复习查阅。
与RNN这类神经网络结构相比Transformer一个巨大的优点是**模型在处理序列输入时,可以对整个序列输入进行并行计算,不需要按照时间步循环递归处理输入序列。**2.1章节详细介绍了RNN神经网络如何循环递归处理输入序列欢迎读者复习查阅。
下图先便是Transformer整体结构图与篇章2.1中介绍的seq2seq模型类似Transformer模型结构中的左半部分为编码器encoder右半部分为解码器decoder下面我们来一步步拆解 Transformer。
@ -108,8 +108,9 @@ Transformer最开始提出来解决机器翻译任务因此可以看作是seq
图:位置编码向量
那么带有位置编码信息的向量到底遵循什么模式?原始论文中给出的设计表达式为:
$$
PE_{(pos,2i)} = sin(pos / 10000^{2i/d_{\text{model}}}) \\ PE_{(pos,2i+1)} = cos(pos / 10000^{2i/d_{\text{model}}})$$
$$
PE_{(pos,2i)} = sin(pos / 10000^{2i/d_{\text{model}}}) \\ PE_{(pos,2i+1)} = cos(pos / 10000^{2i/d_{\text{model}}})
$$
上面表达式中的$pos$代表词的位置,$d_{model}$代表位置向量的维度,$i \in [0, d_{model})$代表位置$d_{model}$维位置向量第$i$维。于是根据上述公式,我们可以得到第$pos$位置的$d_{model}$维位置向量。在下图中我们画出了一种位置向量在第4、5、6、7维度、不同位置的的数值大小。横坐标表示位置下标纵坐标表示数值大小。
![位置编码图示](./pictures/2-2-pos-embedding.png)
@ -126,16 +127,15 @@ $$
![输入encoder](./pictures/2-x-encoder.png)
单层encoder的序列向量流动
下面再看一个2个单词的例子
![一层传一层](./pictures/2-multi-encoder.webp)
2个单词的例子$x_1, x_2 \to z_1, z_2 \to r_1, r_2$
#### <h3 id='self-attention'> Self-Attention层 </h3>
### Self-Attention层
下面来分析一下上图中Self-Attention层的具体机制。
##### <h3 id='self-attention-abstract'> Self-Attention概览 </h3>
##### Self-Attention概览
假设我们想要翻译的句子是:
```
@ -151,16 +151,15 @@ The animal didn't cross the street because it was too tired
上图所示的*it*是一个真实的例子是当Transformer在第5层编码器编码“it”时的状态可视化之后显示*it*有一部分注意力集中在了“The animal”上并且把这两个词的信息融合到了"it"中。
##### <h3 id='self-attention-detail'> Self-Attention细节 </h3>
##### Self-Attention细节
先通过一个简单的例子来理解一下什么是“self-attention自注意力机制”假设一句话包含两个单词Thinking Machines。自注意力的一种理解是Thinking-ThinkingThinking-MachinesMachines-ThinkingMachines-Machines共$2^2$种两两attention。那么具体如何计算呢假设Thinking、Machines这两个单词经过词向量算法得到向量是$X_1, X_2$
$$1: q_1 = X_1 W^Q, q_2 = X_2 W^Q; k_1 = X_1 W^K, k_2 = X_2 W^K;v_1 = X_1 W^V, v_2 = X_2 W^V, W^Q, W^K, W^K \in \mathbb{R}^{d_x \times d_k}\\
先通过一个简单的例子来理解一下什么是“self-attention自注意力机制”假设一句话包含两个单词Thinking Machines。自注意力的一种理解是Thinking-ThinkingThinking-MachinesMachines-ThinkingMachines-Machines共$2^2$种两两attention。那么具体如何计算呢假设Thinking、Machines这两个单词经过词向量算法得到向量是$X_1, X_2$
$$
1: q_1 = X_1 W^Q, q_2 = X_2 W^Q; k_1 = X_1 W^K, k_2 = X_2 W^K;v_1 = X_1 W^V, v_2 = X_2 W^V, W^Q, W^K, W^K \in \mathbb{R}^{d_x \times d_k}\\
2-3: score_{11} = \frac{q_1 \cdot q_1}{\sqrt{d_k}} , score_{12} = \frac{q_1 \cdot q_2}{\sqrt{d_k}} ; score_{21} = \frac{q_2 \cdot q_1}{\sqrt{d_k}}, score_{22} = \frac{q_2 \cdot q_2}{\sqrt{d_k}}; \\
4: score_{11} = \frac{e^{score_{11}}}{e^{score_{11}} + e^{score_{12}}},score_{12} = \frac{e^{score_{12}}}{e^{score_{11}} + e^{score_{12}}}; score_{21} = \frac{e^{score_{21}}}{e^{score_{21}} + e^{score_{22}}},score_{22} = \frac{e^{score_{22}}}{e^{score_{21}} + e^{score_{22}}} \\
5-6: z_1 = v_1 \times score_{11} + v_2 \times score_{12}; z_2 = v_1 \times score_{21} + v_2 \times score_{22}
$$
下面我们将上诉self-attention计算的6个步骤进行可视化。
第1步对输入编码器的词向量进行线性变换得到Query向量: $q_1, q_2$Key向量: $k_1, k_2$Value向量: $v_1, v_2$。这3个向量是词向量分别和3个参数矩阵相乘得到的而这个矩阵也是是模型要学习的参数。
@ -169,7 +168,7 @@ $$
Query 向量Key 向量Value 向量是什么含义呢?
其实它们就是 3 个向量,给它们加上一个名称,可以让我们更好地理解 Self-Attention 的计算过程和逻辑。attention计算的逻辑常常可以描述为query和key计算相关或者叫attention得分然后根据attention得分对value进行加权求和。
其实它们就是 3 个向量,给它们加上一个名称,可以让我们更好地理解 Self-Attention 的计算过程和逻辑。attention计算的逻辑常常可以描述为**query和key计算相关或者叫attention得分然后根据attention得分对value进行加权求和。**
第2步计算Attention Score注意力分数。假设我们现在计算第一个词*Thinking* 的Attention Score注意力分数需要根据*Thinking* 对应的词向量,对句子中的其他词向量都计算一个分数。这些分数决定了我们在编码*Thinking*这个词时,需要对句子中其他位置的词向量的权重。
@ -197,11 +196,12 @@ Attention score是根据"*Thinking*" 对应的 Query 向量和其他位置的每
##### Self-Attention矩阵计算
将self-attention计算6个步骤中的向量放一起比如$X=[x_1;x_2]$便可以进行矩阵计算啦。下面依旧按步骤展示self-attention的矩阵计算方法。
$$X = [X_1;X_2] \\
将self-attention计算6个步骤中的向量放一起比如$X=[x_1;x_2]$便可以进行矩阵计算啦。下面依旧按步骤展示self-attention的矩阵计算方法。
$$
X = [X_1;X_2] \\
Q = X W^Q, K = X W^K, V=X W^V \\
Z = softmax(\frac{QK^T}{\sqrt{d_k}}) V$$
Z = softmax(\frac{QK^T}{\sqrt{d_k}}) V
$$
第1步计算 QueryKeyValue 的矩阵。首先我们把所有词向量放到一个矩阵X中然后分别和3个权重矩阵$W^Q, W^K W^V$ 相乘,得到 QKV 矩阵。矩阵X中的每一行表示句子中的每一个词的词向量。QKV 矩阵中的每一行表示 Query向量Key向量Value 向量,向量维度是$d_k$。
![](./pictures/2-qkv-multi.png)图QKV矩阵乘法
@ -215,8 +215,8 @@ Z = softmax(\frac{QK^T}{\sqrt{d_k}}) V$$
Transformer 的论文通过增加多头注意力机制(一组注意力称为一个 attention head进一步完善了Self-Attention。这种机制从如下两个方面增强了attention层的能力
- 它扩展了模型关注不同位置的能力。在上面的例子中,第一个位置的输出$z_1$包含了句子中其他每个位置的很小一部分信息,但$z_1$仅仅是单个向量所以可能仅由第1个位置的信息主导了。而当我们翻译句子`The animal didnt cross the street because it was too tired`时,我们不仅希望模型关注到"it"本身,还希望模型关注到"The"和“animal”甚至关注到"tired"。这时,多头注意力机制会有帮助。
- 多头注意力机制赋予attention层多个“子表示空间”。下面我们会看到多头注意力机制会有多组$W^Q, W^K W^V$ 的权重矩阵(在 Transformer 的论文中,使用了 8 组注意力),,因此可以将$X$变换到更多种子空间进行表示。接下来我们也使用8组注意力头attention heads。每一组注意力的权重矩阵都是随机初始化的但经过训练之后每一组注意力的权重$W^Q, W^K W^V$ 可以把输入的向量映射到一个对应的”子表示空间“。
- **它扩展了模型关注不同位置的能力**。在上面的例子中,第一个位置的输出$z_1$包含了句子中其他每个位置的很小一部分信息,但$z_1$仅仅是单个向量所以可能仅由第1个位置的信息主导了。而当我们翻译句子`The animal didnt cross the street because it was too tired`时,我们不仅希望模型关注到"it"本身,还希望模型关注到"The"和“animal”甚至关注到"tired"。这时,多头注意力机制会有帮助。
- **多头注意力机制赋予attention层多个“子表示空间”**。下面我们会看到,多头注意力机制会有多组$W^Q, W^K W^V$ 的权重矩阵(在 Transformer 的论文中,使用了 8 组注意力),,因此可以将$X$变换到更多种子空间进行表示。接下来我们也使用8组注意力头attention heads。每一组注意力的权重矩阵都是随机初始化的但经过训练之后每一组注意力的权重$W^Q, W^K W^V$ 可以把输入的向量映射到一个对应的”子表示空间“。
![多头注意力机制](./pictures/2-multi-head.png)
图:多头注意力机制
@ -243,7 +243,7 @@ Transformer 的论文通过增加多头注意力机制(一组注意力称为
![放在一起](./pictures/2-put-together.webp)
图:多头注意力机制的矩阵运算
学习多头注意力机制让我们再来看下当我们前面提到的it例子不同的attention heads 注意力头对应的“it”attention了哪些内容。下图中的绿色和橙色线条分别表示2组不同的attentin heads
学习多头注意力机制让我们再来看下当我们前面提到的it例子不同的attention heads 注意力头对应的“it”attention了哪些内容。下图中的绿色和橙色线条分别表示2组不同的attentin heads
![`it`的attention](./pictures/2-it-attention.webp)
图:`it`的attention
@ -357,7 +357,6 @@ print(output.shape)
编码器和和解码器的子层里面都有层标准化layer-normalization。假设一个 Transformer 是由 2 层编码器和两层解码器组成的,将全部内部细节展示起来如下图所示。
![2层示意图](./pictures/2-2layer.png)
2层Transformer示意图
@ -380,7 +379,7 @@ print(output.shape)
## 线性层和softmax
Decoder 最终的输出是一个向量,其中每个元素是浮点数。我们怎么把这个向量转换为单词呢?这是线性和softmax完成的。
Decoder 最终的输出是一个向量,其中每个元素是浮点数。我们怎么把这个向量转换为单词呢?这是线性和softmax完成的。
线性层就是一个普通的全连接神经网络,可以把解码器输出的向量,映射到一个更大的向量,这个向量称为 logits 向量:假设我们的模型有 10000 个英语单词(模型的输出词汇表),此 logits 向量便会有 10000 个数字,每个数表示一个单词的分数。
@ -448,4 +447,3 @@ Transformer训练的时候需要将解码器的输出和label一同送入损
## 致谢
主要由哈尔滨工业大学张贤同学翻译撰写由多多同学、datawhale项目同学重新组织。最后期待您的阅读反馈和star哦谢谢。