### Transformer
[点击查看课程链接](https://www.bilibili.com/video/BV1YsqSY8EiW?spm_id_from=333.788.videopod.sections&vd_source=5b20ceba8ceda029b4d352ff81c5dd06&p=55)
Transformer是一种特殊的神经网络,一种机器学习模型。核心任务是理解上下文和序列转换。
传统的RNN网络,每次计算都需要上一个单元的结果,不能并行计算。
#### 注意力机制
self-attention要做的事: 对于一个序列,让序列中的每个元素,搞清楚自己和其它元素之间的关系。例如,对于一句话中的某个词,要搞清其和上下文的关系。
##### self_attention的计算方法
###### 生成 Q, K, V
输入的序列(比如三个单词的词向量)组成一个矩阵 $X$。通过三个不同的权重矩阵 $W^Q, W^K, W^V$ 与 $X$ 相乘,得到三个新的矩阵:
{.alignnone}
$Q$ (Query):要去查询的
$K$ (Key):等待被查询的
$V$ (Value):实际特征信息
$$Q = XW^Q, \quad K = XW^K, \quad V = XW^V$$
###### 计算注意力得分
用 $Q$ 乘以 $K$ 的转置 $K^T$。对于每一个待查的单词,即Q中的每一行向量,与待查的单词,即K中的每一行向量计算内积,就得到了两个词之间的原始相关性得分。对于两个向量,越相关内积越大,完全不相关时,内积为0。
除以 $\sqrt{d_k}$($d_k$ 是向量维度),为了防止向量维度越大点积结果越大。
归一化(Softmax),对每一行做 Softmax。把得分转换成 $0 \sim 1$ 之间的概率,得到注意力权重。
###### 加权求和
$$\text{Attention}(Q, K, V) = \text{softmax}\left(\frac{QK^T}{\sqrt{d_k}}\right)V$$
V即上面的value矩阵
#### Multi-headed机制
单一的注意力机制(单头)很难同时捕捉到多种不同的语义关系,多头机制可以通过不同的head得到多个特征表达,可以类比CNN中的多个卷积核。
我们将原始的 $Q, K, V$ 通过 $h$ 组不同的权重矩阵 $W^Q_i, W^K_i, W^V_i$ 进行线性映射。假设有 8 个头,就会得到 8 组不同的 $Q_i, K_i, V_i$。
这 8 组向量各自独立地进行运算:$$\text{head}_i = \text{Attention}(Q_i, K_i, V_i)$$
把这 8 个头的输出结果横向拼接在一起,变成一个大长矩阵。
通过一个最终的权重矩阵 $W^O$ 进行融合,把多头的信息揉在一起。
#### Decoder与Mask
Decoder端是输出生成端,其目标是生成序列,例如翻译出的英文句子。
主要有两个特征:
1.生成词时,必须依赖前面已经生成的词。
2.不仅要看自己写了什么(Self-Attention),还要结合Encoder端给的信息(Cross-Attention)
Mask 的作用: 强迫模型在计算第 $i$ 个词的注意力时,把第 $i+1$ 个及之后的词全部“挡住”。
#### 多层堆叠与位置编码
##### 多层堆叠
Transformer 并不是只有一层 Encoder 和 Decoder,通常会堆叠很多层。
多层的堆叠可能会导致结果越来越差,所以每一层都要配上残差链接(类比之前CNN中的残差网络)。
##### 位置编码
自注意力机制(Self-Attention)是并行的,失去了词序信息。
为了保留词序信息,我们向词向量中注入位置信息。
Transformer 采用的是 正弦和余弦函数。
#### Transformer整体架构
{.alignnone}
Transformer的最大优势就是并行计算。这个优势主要是通过一下三个方面实现的:
1.消除了时间序列依赖。在 Encoder 的 Self-Attention 层,句子中所有的词同时输入。计算第一个词对全句的注意力,和计算最后一个词对全句的注意力,在数学上是独立的。GPU 可以同时开启几千个线程,瞬间算出整个 $QK^T$ 矩阵。
2.多头注意力(Multi-Head)的并行子空间。多 个头在 GPU 里是作为独立的维度并行运算的。不用互相等待,算完后直接拼接在一起即可。
3.Transformer 的每一层结构都是高度一致的
#### Layer Normalization
层归一化用来稳定神经网络的训练,避免训练中产生梯度消失或梯度爆炸。层归一化会对神经网络某一层的所有神经元的输出结果进行归一化计算
计算公式:
$$\hat{x}_i = \frac{x_i – \mu}{\sqrt{\sigma^2 + \epsilon}}$$
由于$\epsilon$很小,可以将上面公式转化为$$\hat{x}_i = \frac{x_i – \mu}{\sigma}$$
—
**$x_i$**:第i个神经元的输出
**$\mu$ **:所有神经元输出的均值。
$\sigma$:标准差
$\hat{x}_i$:层归一化的计算结果
$\epsilon$:偏置项/平滑项,用于防止分母为0
$$y_i = \gamma \hat{x}_i + \beta$$
—
**$\gamma$**:可学习的缩放参数。
**$\beta$**:可学习的平移参数。
**$y_i$**:LayerNorm 最终的输出结果。
若不进行参数学习,则会以上面的原始公式计算。