【阅读笔记】最通俗易懂的 transformer 笔记

这里写目录标题

  • 前言
  • 第 1 节 · N 元文法语言模型
  • 第 2 节 · 感知器(Perceptron)
    • 2.1、线性回归(Linear Regression)
    • 2.2、逻辑回归(Logistic Regression)
    • 2.3、Sigmoid 回归
    • 2.4、Softmax 回归
    • 2.6、多层感知器(Multi-Layer Perceptron)
    • 2.7、简述如何训练一个模型:正向传播与反向传播
  • 第 3 节 · 卷积神经网络(CNN)
  • 第 4 节 · 循环神经网络(RNN)
    • 4.1、经典结构的 RNN(N vs N RNN)
    • N vs.1 的 RNN
    • 1 vs. N 的 RNN
    • 4.4、LSTM(Long Short-Term Memory)长短时记忆网络
    • 4.5、双向 RNN 和双向 LSTM
    • 4.6、堆叠循环神经网络(Stacked RNN)、堆叠长短时记忆网络(Stacked LSTM)
    • 4.7、N vs. M 的 RNN (Encoder-Decoder)
  • 第 5 节 · 为什么说 RNN 模型没有体现「注意力」?
  • 第 6 节 · 基于 Attention 机制的 Encoder-Decoder 模型
  • 第 7 节 · 自注意力机制(Self-Attention)
  • 第 8 节 · 多头注意力(Multi-Head attention)
  • 第 9 节 · 退化现象、残差网络与 Short-Cut
  • 第 10 节 · Transformer 的位置编码(Positional Embedding)
    • 10.2、绝对位置编码
    • 10.3、相对位置编码与其他位置编码
  • 第 11 节 · Transformer 的编码器 Encoder 和解码器 Decoder
    • 11.1、Encoder 和 Decoder 的图示结构
      • 第一个 masked multi-head attention
      • 第二个 multi-head attention
    • 11.2、Decoder 的第一个输出结果
    • 11.3、Decoder 后续的所有输出
    • 11.4、Decoder 之后的 Linear 和 Softmax
  • 第 12 节 · Transformer 模型整体

前言

这篇文章是关于《如何从浅入深理解transformer》 的一个阅读笔记。

因为是第一次接触 transformer,找了半天,感觉这篇文章作为入门来说还不错,可以将整个发展的历程串联起来讲。

但是这毕竟是一篇阅读笔记,我只会对个人不太清楚的概念详细了解。

第 1 节 · N 元文法语言模型

n-Gram 模型的主体思想就是:下一个词出现的概率只依赖于它前面 n-1 个词,也被称为 n 阶马尔科夫链。

文中出现的公式: P ( w t ∣ w 1 , w 2 , . . . , w t − 1 ) = C ( w 1 , w 2 , . . . , w t ) C ( w 1 , w 2 , . . . , w t − 1 ) P(w_t|w_1, w_2,...,w_{t-1}) = \frac{C(w_1, w_2,...,w_{t})}{C(w_1, w_2,...,w_{t-1})} P(wtw1,w2,...,wt1)=C(w1,w2,...,wt1)C(w1,w2,...,wt) 其中的参数 C ( w 1 , w 2 , . . . , w t ) C(w_1, w_2,...,w_{t}) C(w1,w2,...,wt) 表示词序列 w 1 , w 2 , . . . , w t w_1, w_2,...,w_{t} w1,w2,...,wt 在训练语料中出现的次数(count)。 C ( w 1 , w 2 , . . . , w t − 1 ) C(w_1, w_2,...,w_{t-1}) C(w1,w2,...,wt1) 也是一样的含义。但是根据条件概率的定义的,本来的公式应该是: P ( w t ∣ w 1 , w 2 , . . . , w t − 1 ) = P ( w 1 , w 2 , . . . , w t ) P ( w 1 , w 2 , . . . , w t − 1 ) P(w_t|w_1, w_2,...,w_{t-1}) = \frac{P(w_1, w_2,...,w_{t})}{P(w_1, w_2,...,w_{t-1})} P(wtw1,w2,...,wt1)=P(w1,w2,...,wt1)P(w1,w2,...,wt)也就是应该使用词序列在训练语料里出现的概率来进行计算的。

为什么第一个公式使用了次数(count)来代替概率(probability)来计算条件概率呢?

由于在实际应用中,直接计算词序列的联合概率 P ( w 1 , w 2 , . . . , w t ) P(w_1, w_2,...,w_{t}) P(w1,w2,...,wt) 通常不可行,因为它们涉及到整个词序列的概率计算,而这些概率往往非常小,容易导致数值下溢。因此,通常使用词频来近似这些概率。
根据大数定律,当语料库足够大时,词频可以近似为概率。因此,可以将上述公式中的概率用词频来替代:

接着,我们就可以对词序列 w 1 , w 2 , . . . , w t w_1, w_2,...,w_{t} w1,w2,...,wt 的概率 P ( w 1 , w 2 , . . . , w t ) P(w_1, w_2,...,w_{t}) P(w1,w2,...,wt) 进行计算了: P ( w 1 , w 2 , . . . , w t ) = P ( w t ∣ w 1 , w 2 , . . . , w t − 1 ) ⋅ P ( w t − 1 ∣ w 1 , w 2 , . . . , w t − 2 ) … P ( w 1 ) = ∏ t − 1 i = 1 P ( w i ∣ w 1 : i − 1 ) \begin{align*} P(w_1, w_2,...,w_{t}) &= P(w_t|w_1, w_2,...,w_{t-1}) \cdot P(w_{t-1}|w_1, w_2,...,w_{t-2}) \dots P(w_1) \\ &=\prod_{t-1}^{i=1} P(w_i|w_{1:i-1}) \end{align*} P(w1,w2,...,wt)=P(wtw1,w2,...,wt1)P(wt1w1,w2,...,wt2)P(w1)=t1i=1P(wiw1:i1) 上面这个是 n-gram 模型计算词序列概率的式子,也就是第 n 个词只依赖于它前面的 n-1 个词。

如果是 n = 2 的情况,也就是二元文法 bi-gram 模型的情况呢,第 n 个词只依赖于它前面的第 n-1 个词,也就是当前词语出现的概率只由上一个词决定。我们可以稍微简化一下上面的公式,就可以得到: P ( w 1 , w 2 , . . . , w t ) = ∏ i = 1 t − 1 P ( w i ∣ w i − 1 ) = ∏ i = 1 t − 1 C ( w i − 1 , w i ) C ( w i − 1 ) P(w_1, w_2,...,w_{t}) = \prod_{i=1}^{t-1} P(w_i|w_{i-1}) = \prod_{i=1}^{t-1}\frac{C(w_{i-1}, w_i)}{C(w_{i-1})} P(w1,w2,...,wt)=i=1t1P(wiwi1)=i=1t1C(wi1)C(wi1,wi) 这就是二元文法 bi-gram 模型计算词序列出现概率的公式。

  • 如果有词出现次数为了 0,这一串乘出来就是 0 了,咋办?
  • 因为基于马尔科夫假设,所以 N 固定窗口取值,对长距离词依赖的情况会表现很差。
  • 如果把 N 值取很大来解决长距离词依赖,则会导致严重的数据稀疏(零频太多了),参数规模也会急速爆炸(高维张量计算)。

文中提出了上面 3 个问题,这个三个问题其实是有某种递进关系的,归纳起来就是

  • 零频
  • N 取值过小
  • N 取值过大

首先我们可以观察上面的 n-gram 公式,如果连乘的概率中出现一个词序列的概率为 0 的话,就会导致整个结果都变为 0。这个问题要怎么尽可能避免了呢,通过减少 N 的取值?尽可能杜绝零频率词序列的出现?但是这会导致长距离词依赖(Long-Range Dependencies)变现变差的问题,如果为了解决长距离词依赖的问题,将 N 值取得很大呢,这又会导致参数爆炸和数据稀疏的问题(也就是回到了问题一,出现词序列零频的问题)。所以这三个问题就像是一个恶性循环,如果尝试解决一个问题,就会引入另一个问题。

所以我们要另辟蹊径,通过外部的手段解决零频的问题,而不是简单的通过调整 N 值的大小。

1.2、平滑(Smoothing)

词序列零频的问题是普遍存在的:

  • 未登录词:N 值比较大的时候,可能导致的未登录词问题(Out Of Vocabulary,OOV),N 越大,代表着词序组合的长度越长,很多词序组合可能在训练数据中可能就出现了一两次,甚至没有出现过,并不具备统计学意义。
  • 有限的训练数据:训练数据很可能也不是 100% 完备覆盖实际中可能遇到的词的。

为了解决零频的问题,我们引入是平滑(smoothing)的概念。

简单来说就是

1.2.1、加 1 平滑 / 拉普拉斯平滑(Add-One Smoothing / Laplace Smoothing)

bi-gram 的加 1 平滑公式: P ( w i ∣ w i − 1 ) = C ( w i − 1 , w i ) + 1 ∑ j = 1 V ( C ( w i − 1 , w j ) + 1 ) = C ( w i − 1 , w i ) + 1 C ( w i − 1 ) + V P(w_i|w_{i-1}) = \frac{C(w_{i-1}, w_i) +1}{ {\textstyle \sum_{j=1}^{V}} (C(w_{i-1}, w_j) + 1)} = \frac{C(w_{i-1}, w_i)+1}{C(w_{i-1}) + V} P(wiwi1)=j=1V(C(wi1,wj)+1)C(wi1,wi)+1=C(wi1)+VC(wi1,wi)+1 其中:

  • C ( w i − 1 , w i ) C(w_{i-1}, w_i) C(wi1,wi): 表示词序列 w i − 1 , w i w_{i-1}, w_i wi1,wi 的词频
  • ∑ j = 1 V ( C ( w i − 1 , w j ) + 1 ) {\textstyle\sum_{j=1}^{V}} (C(w_{i-1}, w_j) + 1) j=1V(C(wi1,wj)+1):因为 j j j 是从 1 到 V,其中 V 表示的是词汇表的数量,也就是说 w j w_j wj 是词汇表中出现的每一个词。 w i − 1 , w j w_{i-1}, w_j wi1,wj 表示第一个词为 w i − 1 w_{i-1} wi1 的情况下,后面跟着不同词的总次数,所以化简之后可以得到最后部分的式子。

其中 N N N 表示所有词的词频之和, V V V 表示词汇表的大小。

原文中提到上面这句话,这个 N N N 可能是指原文公式的求和的上标 n n n,表示 token 的数量,但是我觉得公式里求和的上标应该是词汇表(vocabulary)的大小。

uni-gram 的加 1 平滑公式是: P ( w i ) = C ( w i ) + 1 N + V P(w_i) = \frac{C(w_i) + 1}{N+V} P(wi)=N+VC(wi)+1这里涉及的 N N N 就是训练的 token 总数,即便是有重复的词语,都会被计算在内, V V V 是词汇表的大小,表示在训练数据中唯一的存在,相当于 set 处理之后的 token。

1.2.2、 δ \delta δ 平滑(Add-K Smoothing / Delta Smoothing)

这是对加 1 平滑的优化,对于某些

bi-gram 的加 δ \delta δ 平滑公式: P ( w i ∣ w i − 1 ) = C ( w i − 1 , w i ) + δ ∑ j = 1 V ( C ( w i − 1 , w j ) + δ ) = C ( w i − 1 , w i ) + δ C ( w i − 1 ) + δ V P(w_i|w_{i-1}) = \frac{C(w_{i-1}, w_i) +\delta}{ {\textstyle \sum_{j=1}^{V}} (C(w_{i-1}, w_j) + \delta)} = \frac{C(w_{i-1}, w_i)+\delta}{C(w_{i-1}) + \delta V} P(wiwi1)=j=1V(C(wi1,wj)+δ)C(wi1,wi)+δ=C(wi1)+δVC(wi1,wi)+δ 和加 1 平滑基本一样,就是将 1 换成了 δ \delta δ

与加 1 平滑相比,加 δ \delta δ 平滑允许对于低频词的平滑程度进行更灵活的控制。当 δ \delta δ 较小时,对低频事件的平滑效果较小,而 δ \delta δ 较大时,平滑效果更加显著。这使得模型在平滑概率时能够更好地适应不同的数据特点。

δ \delta δ 是一个超参数,如果可以寻找到最优的值,就可以使得模型的效果更好,原文中说确定这个 δ \delta δ 值需要用到困惑度(Perplexity),但是其实个人觉得,只是一种比较间接的影响关系。

首先加 δ \delta δ 平滑操作的对象都是训练集,然后训练出一个语言模型,然后困惑度是用来评价语言模型在测试集上的性能的。通过调整 δ \delta δ 值,进行多次训练,使得语言模型在特定测试集的困惑度最小,这样便能得到最优的模型。

1.2.3、困惑度(Perplexity)

(在这里突然插入一个评价指标有点奇怪)

困惑度:评价一个概率模型预测测试集的能力,困惑度越低,表示模型越好。

下面是针对单一词序列 w 1 , w 2 , … , w N w_1, w_2, \dots ,w_N w1,w2,,wN 的困惑度计算公式,并不是整个测试集的: Perplexity ( W ) = P ( w 1 , w 2 , … , w N ) − 1 N = 1 P ( w 1 , w 2 , … , w N ) N \text{Perplexity}(W) =P(w_1, w_2, \dots ,w_N)^{-\frac{1}{N} }= \sqrt[N]{\frac{1}{P(w_1, w_2, \dots, w_N)}} Perplexity(W)=P(w1,w2,,wN)N1=NP(w1,w2,,wN)1 我们可以看到,公式里是将这段词序列的出现概率开了 N 次根,然后再求了倒数。

为什么要进行开 N 次方根的操作?
为了将不同长度的词序列归一化到一个统一的尺度来进行比较。我们将联合概率标准化为每个词的平均概率,即平均每个词的预测概率。这样,我们可以更好地比较模型在不同长度序列上的性能,而不受序列长度的影响。

我们将前面的联合概率的公式代入进去,就可以得到: Perplexity ( W ) = ∏ i = 1 N 1 P ( w i ∣ w 1 , w 2 , … , w i − 1 ) N \text{Perplexity}(W) = \sqrt[N]{\prod_{i=1}^{N} \frac{1}{P(w_i|w_1,w_2,\dots ,w_{i-1})} } Perplexity(W)=Ni=1NP(wiw1,w2,,wi1)1 也可以得到 bi-gram 的单一词序列困惑度计算公式: Perplexity ( W ) = ∏ i = 1 N 1 P ( w i ∣ w i − 1 ) N \text{Perplexity}(W) = \sqrt[N]{\prod_{i=1}^{N} \frac{1}{P(w_i| w_{i-1})} } Perplexity(W)=Ni=1NP(wiwi1)1

1.3、回退(Back-off)

在回退模型中,计算一个3-gram的概率时,如果这个3-gram在训练数据中存在,则直接使用其概率;如果不存在,则回退到2-gram,然后再回退到1-gram,依此类推。这样,即使某个组合在3-gram中没有观察到,仍然可以通过回退到2-gram等较低阶的模型来估计其概率。

这个感觉还是挺好理解的,一句话来说就是:退而求其次

公式也挺好理解的: P ( w i ∣ w i − 2 , w i − 1 ) = { P ( w i ∣ w i − 2 , w i − 1 ) C ( w i − 2 , w i − 1 , w i ) > 0 P ( w i ∣ w i − 1 ) C ( w i − 2 , w i − 1 , w i ) = 0     and     C ( w i − 1 , w i ) > 0 P(w_i|w_{i-2},w_{i-1}) = \begin{cases} P(w_i|w_{i-2},w_{i-1}) & C(w_{i-2},w_{i-1},w_i)>0 \\ P(w_i|w_{i-1}) & C(w_{i-2},w_{i-1},w_i)=0 \space\space\space\space \text{and} \space\space\space\space C(w_{i-1},w_i)>0 \end{cases} P(wiwi2,wi1)={P(wiwi2,wi1)P(wiwi1)C(wi2,wi1,wi)>0C(wi2,wi1,wi)=0    and    C(wi1,wi)>0

1.4、插值(Interpolation)

在计算 n-gram 的概率的时候,也考虑 n-1-gram,甚至是 n-2-gram 的概率:
P ( w i ∣ w i − 2 , w i − 1 ) = λ 1 P ( w i ∣ w i − 2 , w i − 1 ) + λ 2 P ( w i ∣ w i − 1 ) + λ 3 P ( w i ) P(w_i|w_{i-2},w_{i-1}) = \lambda_1P(w_i|w_{i-2},w_{i-1}) + \lambda_2P(w_i|w_{i-1}) + \lambda_3P(w_i) P(wiwi2,wi1)=λ1P(wiwi2,wi1)+λ2P(wiwi1)+λ3P(wi)

第 2 节 · 感知器(Perceptron)

感知器一般用于处理二分类问题: y = { 1 ,  if  w x + b > 0 0 , othrewise y = \begin{cases} 1, & \text{ if } wx + b > 0 \\ 0, & \text{othrewise} \end{cases} y={1,0, if wx+b>0othrewise其中 w w w 是权重, b b b 是偏置项。

2.1、线性回归(Linear Regression)

上面的公式中 w x + b wx+b wx+b 的计算结果是需要映射到 0,1 两个结果中,是离散值,解决的是分类问题。但是如果我们直接将 w x + b wx+b wx+b 的计算结果拿过来使用,而不进行映射的话,结果将会是一个连续值,问题也会变成线性回归问题。

原本中有一个使用 pytorch 库中 nn.Linear 进行代码实操的代码片段,这里就不多说了。

2.2、逻辑回归(Logistic Regression)

如果说线性回归的结果是没有限制范围的,那么逻辑回归就会将计算结果限制在一个特定范围之内。

在线性回归的公式为: y = w x + b y = wx + b y=wx+b

那么在逻辑回归中: y = σ ( w x + b ) y = \sigma (wx + b) y=σ(wx+b)

激活函数会将线性回归 w x + b wx+b wx+b 的计算结果,再限制在一个确定的范围了。

在这里插入图片描述

上面这张图展示了逻辑回归的流程,已经有点神经网络的神经元的雏形了。

2.3、Sigmoid 回归

sigmoid 函数是我们在神经网络中常见到的激活函数,简单来说,当逻辑回归中的 σ ( z ) \sigma(z) σ(z) 是 sigmoid 函数的时候,这个逻辑回归也叫做 sigmoid 回归。
y = Sigmoid ( w x + b ) = 1 1 + e − ( w x + b ) y = \text{Sigmoid} (wx + b) = \frac{1}{1+e^{-(wx+b)}} y=Sigmoid(wx+b)=1+e(wx+b)1 其中 Sigmoid ( z ) = 1 1 + e − z \text{Sigmoid}(z) = \frac{1}{1+e^{-z}} Sigmoid(z)=1+ez1,这个 sigmoid 函数会将结果值限制在 [ 0 , 1 ] [0, 1] [0,1] 之间。

一般是用在二分类问题中预测概率。

2.4、Softmax 回归

在这里插入图片描述
上面说到 sigmoid 回归主要是针对二分类的问题,现在要介绍的 softmax 回归主要就是针对多分类的问题

如上图所示,一个输入 x x x,如果要进行 softmax 回归,进行类别为 K K K 的 多元分类。首先和 sigmoid 一样,需要经过各自类别的权重 w K w_K wK 和偏置 b K b_K bK 处理之后,得到每个类别的原始得分 z K z_K zK。然后一起送入到 softmax 函数内计算对应类别的概率。

这个公式就是计算输入在类别 i i i 的概率:
y i = σ ( z ) i = e z i ∑ j = 1 K e z j = e z i e z 1 + e z 2 + ⋯ + e z K y_i = \sigma (\bold{z})_i = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}} = \frac{e^{z_i}}{ e^{z_1} + e^{z_2} + \dots + e^{z_K} } yi=σ(z)i=j=1Kezjezi=ez1+ez2++ezKezi其中有 z K = w K x + b K z_K = w_K x + b_K zK=wKx+bK

一般来说,输入 x x x 其实也是一个维度为 K K K 的向量,如果不足的可以进行补零,超出的话就进行保留最主要的 K K K 个特征。这里我假设这个输入向量 x \bold{x} x 的所有维度的值都是 x x x

2.6、多层感知器(Multi-Layer Perceptron)

MLP 是一种全连接的前馈神经网络,每一层的每个神经元都与上一层的所有神经元相连,有点全连接层的意思。

而且,MLP 中的激活函数必须得是非线性激活函数,如果是线性,不管是多少层,其实都只是一个简单的线性模型,只能解决简单的线性问题,没有非线性的学习能力。

因为全连接的关系,所以一个比较大的缺点就是:计算量非常大。

MLP 主要有输入层,隐藏层和输出层三个部分组成。

其中最重要的是隐藏层,加权求和,还有激活函数的操作都是在隐藏层进行的。

在这里插入图片描述
为了加深对 MLP 的理解,我自己画了一下 MLP 的一个简单的网络结构图。输入层和输出层没有像大多数图那样画成节点的形式,也将权重偏置显式地标注了出来。

图中的 w 0 , 00 w_{0, 00} w0,00 的下标逗号之前的 0 0 0 表示这个参数属于第 0 0 0 层隐藏层的。下标逗号后面的 00 00 00 表示这是输入参数 x 0 x_0 x0 与隐藏单元 h 0 , 0 h_{0, 0} h0,0 之间的参数。

如果将这个网络结构用向量公式表现出来就是下面的式子: A 0 = f ( W 0 ⋅ X + b 0 ) Y = f ( W 1 ⋅ A 0 + b 1 ) \begin{matrix} \mathbf{A_0} = f(\mathbf{ W_0 \cdot X + b_0})\\ \mathbf{Y} = f(\mathbf{W_1 \cdot A_0 + b_1} ) \end{matrix} A0=f(W0X+b0)Y=f(W1A0+b1)其中 W 0 = [ w 0 , 00 w 0 , 10 w 0 , 01 w 0 , 11 w 0 , 02 w 0 , 12 ] ,       X = [ x 0 x 1 ] ,     b 0 = [ b 0 , 00 + b 0 , 10 b 0 , 01 + b 0 , 11 b 0 , 02 + b 0 , 12 ] \mathbf{W_0} = \begin{bmatrix} w_{0,00} & w_{0, 10} \\ w_{0,01} & w_{0, 11}\\ w_{0,02} & w_{0, 12} \end{bmatrix}, \space \space \space \space \space \mathbf{ X} = \begin{bmatrix} x_0\\ x_1 \end{bmatrix}, \space \space \space \mathbf{b_0} =\begin{bmatrix} b_{0,00} + b_{0, 10}\\ b_{0,01} + b_{0, 11} \\ b_{0,02} + b_{0,12} \end{bmatrix} W0= w0,00w0,01w0,02w0,10w0,11w0,12 ,     X=[x0x1],   b0= b0,00+b0,10b0,01+b0,11b0,02+b0,12 可以得到: W 0 ⋅ X + b 0 = [ w 0 , 00 w 0 , 10 w 0 , 01 w 0 , 11 w 0 , 02 w 0 , 12 ] ⋅ [ x 0 x 1 ] + [ b 0 , 0 b 0 , 1 b 0 , 2 ] = ( w 0 , 00 ⋅ x 0 + w 0 , 10 ⋅ x 1 + b 0 , 0 )      + ( w 0 , 01 ⋅ x 0 + w 0 , 11 ⋅ x 1 + b 0 , 1 )      + ( w 0 , 02 ⋅ x 0 + w 0 , 12 ⋅ x 1 + b 0 , 2 ) \begin{align*} \mathbf{ W_0 \cdot X + b_0} &= \begin{bmatrix} w_{0,00} & w_{0, 10} \\ w_{0,01} & w_{0, 11}\\ w_{0,02} & w_{0, 12} \end{bmatrix} \cdot \begin{bmatrix} x_0\\x_1\end{bmatrix} + \begin{bmatrix} b_{0,0} \\ b_{0,1} \\ b_{0,2} \end{bmatrix}\\ &= (w_{0,00}\cdot x_0 + w_{0,10}\cdot x_1 + b_{0,0}) \\ & \space \space \space \space + (w_{0,01}\cdot x_0 + w_{0,11}\cdot x_1 + b_{0,1}) \\ & \space \space \space \space + (w_{0,02}\cdot x_0 + w_{0,12}\cdot x_1 + b_{0,2}) \end{align*} W0X+b0= w0,00w0,01w0,02w0,10w0,11w0,12 [x0x1]+ b0,0b0,1b0,2 =(w0,00x0+w0,10x1+b0,0)    +(w0,01x0+w0,11x1+b0,1)    +(w0,02x0+w0,12x1+b0,2) 因为偏置项 b b b 是常数,所以这里我将两个常数直接合并了。

最后得出来的结果也是我们非常熟悉的形式。然后和之前的逻辑回归类似,将这个加权求和得到的结果,送到激活函数中,进行非线性的变换,得到我们所需的下一个隐藏层的输入项 A 0 \mathbf{A_0} A0

在这里插入图片描述
合并偏置常数项之后,我们的 MLP 结构图也可以画成上图的形式。

第二隐藏层的具体式子在这里就不列出来了。

2.7、简述如何训练一个模型:正向传播与反向传播

这个原文中也没做过多的展开,我这里也留着

第 3 节 · 卷积神经网络(CNN)

MLP 里每一层的每个元素,都要乘以一个独立参数的权重 W,再加上一个偏置 b,这样的神经网络层常被我们叫做「全连接层(Fully Connected Layer)或稠密层(Dence Layer)。但是这样有个显著问题:如果输入内容的局部重要信息只是发生轻微移动并没有丢失,在全连接层处理后,整个输出结果都会发生很大变化 —— 这不合理

即全连接层可能在处理输入时过于强调整体特征,而不足够关注输入中的局部结构信息。

所以为了让全连接层也能关注局部信息,是否可以设置一个滑动窗口来对局部输入进行处理。这就会 n-gram 设置 N 值的大小思路一样。这就引出了我们熟悉的 CNN 卷积神经网络,使用卷积核在原图上的滑动来提取图像的局部特征。

  1. CNN 与 MLP 有什么区别?
  2. CNN 的共享权重是什么意思?
  3. CNN 的局部连接是什么意思?

上面我画的示意图中,MLP 的输入数据是一维的,所以所有输入 MLP 进行全连接处理的数据都得先展平成一维的数据,而 CNN 的输入数据则是二维的,也就是可以。

其实某种意义上,可以将 MLP 理解成一个 1 × 1 1\times1 1×1 的卷积,但是和真正的 1 × 1 1\times1 1×1 卷积又有一些微秒的区别,在 CNN 中我们也常使用 1 × 1 1\times1 1×1 卷积来实现全连接结构,但是 1 × 1 1\times1 1×1 卷积的输入可以是二维的数据,而 MLP 还是只能输入一维的数据。

让我们修改一下上面的图,将输入数据变成我们熟悉的二维图像数据。

第 4 节 · 循环神经网络(RNN)

4.1、经典结构的 RNN(N vs N RNN)

也就是输入和输出的维度是一样的。
在这里插入图片描述

N vs.1 的 RNN

在这里插入图片描述

1 vs. N 的 RNN

在这里插入图片描述

4.4、LSTM(Long Short-Term Memory)长短时记忆网络

LSTM 因为在图像处理中基本用不上,所以我比较陌生。是一种特殊的 RNN 网络。

我们通过 RNN 的结构就可以看出来,后向传播的时候,连续的乘法结构很容易造成梯度消失或者梯度爆炸的问题。在 CNN 的时候,我们会通过 dropout 对某些神经元进行舍弃,来进行正则化,缓解梯度消失和爆炸的问题。而 LSTM 中呢,我们也会设计一个模块对过往的信息进行舍弃,来缓解 RNN 中出现的梯度消失或者爆炸问题。

LSTM将长短期记忆文本管理问题分为两个子问题:

  1. 从上下文中删除不再需要的信息(舍弃部分过往信息)
  2. 添加可能在后续决策中需要的信息(添加当前输入信息)

LSTM 引入了 “门(gate)” 的概念来控制信息的流向,可以分成 3 个门:

  • 遗忘门(forget gate):用于去除上文中所不需要的信息。
  • 输入门(input gate):将当前的信息输入到上下文中。
  • 输出门(output gate):输出当前的上下文信息。

其实 LSTM 的结构和公式都不难理解,但是我希望在这里一步步从 RNN 推导到 LSTM,就有很多细节不清楚了,这里暂时也不过多的纠结了。

4.5、双向 RNN 和双向 LSTM

在经典的循环神经网络中,状态的传输是从前往后单向的。然而,在有些问题中,当前时刻的输出不仅和之前的状态有关系,也和之后的状态相关。这时就需要双向RNN(BiRNN)来解决这类问题。例如预测一个语句中缺失的单词不仅需要根据前文来判断,也需要根据后面的内容,这时双向RNN就可以发挥它的作用。
在这里插入图片描述
原文中给了一张简单的 bi-RNN 示意图,但是我感觉有点容易误解的地方。它只是对前向和反向的隐藏层权重 W W W W ′ W' W 进行了区分,但是没有区分 V V V V ′ V' V U U U U ′ U' U 的权重。

一般计算的步骤是从前向后算一次,然后再从后向前计算一次。

原文虽然小标题中提到了双向 LSTM,但是实际没有具体的提到双向 LSTM 的,所以我这里也暂时略过。

4.6、堆叠循环神经网络(Stacked RNN)、堆叠长短时记忆网络(Stacked LSTM)

就是一层的输出作为下一层的输入,多层堆叠

4.7、N vs. M 的 RNN (Encoder-Decoder)

在这里插入图片描述
上图是一个抽象化的 Encoder-Decoder 模型示意图,相当于一个 N vs 1 和一个 1 vs M 的 RNN 网络的串联。一般我们也称之为 Seq2Seq 模型。

Encoder-Decoder 的结构有多种,但是大体的原理都是一样的。

仅管 Encoder-Decoder 模型可以实现序列到序列的任务,对于语音识别,翻译任务,问答任务的效果很不错,但是也存在一些问题:

  • 长序列信息丢失问题:Encoder 将输入编码为固定大小的向量的过程实际上是一个“信息有损的压缩过程”,如果信息量越大,那么这个转化向量的过程对信息的损失就越大。
  • 梯度消失或者爆炸:因为传统 Encoder-Decoder 是采用 RNN 作为编码器和解码器的,所以自然,RNN 存在的梯度消失和梯度爆炸问题也是不可避免的。
  • 并行效果差:因为每一时刻都依赖于前一时刻的输出。

第 5 节 · 为什么说 RNN 模型没有体现「注意力」?

其实从 4.7 就可以看出来,传统的 Encoder-Decoder 对于长序列的处理能力是很差的,因为不管序列多长,在经过编码器之后,都会压缩成固定尺寸的上下文向量(context vector),在这个压缩编码的过程中,很多长序列的信息就会丢失,导致后续解码部分也没办法获得全部的长序列信息。

举个简单的例子,如果长序列信息类似于山洞里的宝库,这时候一个盗贼进入了山洞,他只有一个箱子可用于搬运且只能搬运一次的话,可能是没办法将山洞内的财宝全部取走。想要实现利益最大化的话,自然是聚焦于高价值的宝物,也就是尽可能的用高价值的宝物填满箱子。

这就引出我们久有耳闻的 attention 机制。将注意力放到有价值的信息上面。

在传统的 Encoder-Decoder 模型里引入 attention 模块。

第 6 节 · 基于 Attention 机制的 Encoder-Decoder 模型

从Encoder-Decoder(Seq2Seq)理解Attention的本质 :这篇文章挺不错的。

在这里插入图片描述
从上面的 Encoder-Decoder 示意图,我们可以知道上下文向量(context vector)可以通过下式: C = f ( x 1 , x 2 , … , x n ) C = f(x_1, x_2, \dots ,x_n) C=f(x1,x2,,xn) 计算得到,而想要对于最后的输出结果 y i y_i yi,我们可以通过: y k = g ( C , y 1 , y 2 , … , y k − 1 ) y_k = g(C, y_1, y_2, \dots, y_{k-1}) yk=g(C,y1,y2,,yk1)但是我们也可以看出来,不管是计算 y 1 y_1 y1 y 2 y_2 y2 还是 y 3 y_3 y3,我们都是通过 C C C 来计算的,也就是说 Encoder 中任意单词对于 Decoder 的输出的影响都是一样的,不存在注意力机制的。

在这里插入图片描述
如果加入了 attention 模块,我们就可以看出来,对于不同的输出 y i y_i yi,我们有着不同的 C i C_i Ci,则对应的输出: y k = g ( C k , y 1 , y 2 , … , y k − 1 ) y_k = g(C_k, y_1, y_2, \dots, y_{k-1}) yk=g(Ck,y1,y2,,yk1)

但是问题来了,这个 C k C_k Ck 是怎么计算出来的?
在这里插入图片描述

也就是说,对于不同的 C k C_k Ck,attention 模块会给出不同的注意力向量 a k \mathbf{a^k} ak 来进行计算,上面的式子中, n n n 为输入序列的长度,而 k k k 为输出序列的长度。

a i k a_{ik} aik 就是 attention 注意力权重,表示第 i i i 个输入在第 k k k 个输出上分配的注意力。数值越高表示第 j j j 个输出受到第 i i i 个输入的影响越大。

如果将他们看成一个矩阵运算的话,则可以写成下面的形式: [ h 1 h 2 ⋯ h i h 1 h 2 ⋯ h i ⋮ ⋮ ⋱ ⋮ h 1 h 2 ⋯ h i ] ⋅ [ a 1 , 1 a 1 , 2 ⋯ a 1 , k a 2 , 1 a 1 , 2 ⋯ a 2 , k ⋮ ⋮ ⋱ ⋮ a i , 1 a i , 2 ⋯ a i , k ] = [ C 1 , C 2 , ⋯   , C k ] \begin{bmatrix} h_1 & h_2 & \cdots & h_i \\ h_1 & h_2 & \cdots & h_i \\ \vdots & \vdots & \ddots & \vdots \\ h_1 & h_2 & \cdots & h_i \end{bmatrix} \cdot \begin{bmatrix} a_{1,1} & a_{1,2} & \cdots & a_{1,k}\\ a_{2,1} & a_{1,2} & \cdots & a_{2,k}\\ \vdots & \vdots & \ddots & \vdots\\ a_{i,1} & a_{i,2} & \cdots & a_{i,k} \end{bmatrix} = [C_1, C_2, \cdots , C_k] h1h1h1h2h2h2hihihi a1,1a2,1ai,1a1,2a1,2ai,2a1,ka2,kai,k =[C1,C2,,Ck]其中等式左边第一个向量的维度为 k × i k \times i k×i,第二个向量 attention 权重矩阵的维度为 i × k i \times k i×k,最后获得的上下文权重向量的维度为 1 × k 1 \times k 1×k

但是问题又来了, a i k a_{ik} aik 是怎么计算获得的?
在 attention 模块中,注意力评价值 e i k e_{ik} eik 是由两部分组成的:

  • i i i 个输入(当前时刻输入)的隐藏层输出 h i h_i hi
  • k − 1 k-1 k1 个输出(前一时刻输出)的隐藏层输出 s k − 1 s_{k-1} sk1

也就是说这个注意力的值其实既和当前输入有关,也和前一时刻的输出相关。

公式可以写成: e i k = α ( h i , s k − 1 ) e_{ik} = \alpha(h_i, s_{k-1}) eik=α(hi,sk1)我们这里的 attention 机制是 soft attention,所以和 softmax 类似,我们要对上面这个注意力评价值进行加权平均: a i k = exp ⁡ ( e i k ) ∑ i = 1 n exp ⁡ ( e i k ) a_{ik} = \frac{\exp(e_{ik})}{\sum_{i=1}^n \exp(e_{ik})} aik=i=1nexp(eik)exp(eik)其中:

  • ∑ i = 1 n exp ⁡ ( e i k ) \sum_{i=1}^n \exp(e_{ik}) i=1nexp(eik):计算了每个时刻输入和前一时刻的输出的评价值之和
  • exp ⁡ ( e i k ) \exp(e_{ik}) exp(eik):表示当前时刻输入和前一时刻输出的评价值

感觉有种当前时刻输入,在总输入中的贡献占比的感觉。

为什么要使用 exp 来计算 attention 权重呢?

最后我们列出计算输出 y i y_i yi 的完整流程:

  1. 已知所有的输入 h i h_i hi s k − 1 s_{k-1} sk1,计算 e i k = α ( h i , s k − 1 ) e_{ik} = \alpha(h_i, s_{k-1}) eik=α(hi,sk1)
  2. 已知 e i k e_{ik} eik,计算 a i k = exp ⁡ ( e i k ) / ∑ i = 1 n exp ⁡ ( e i k ) a_{ik} = \exp(e_{ik}) / \sum_{i=1}^n \exp(e_{ik}) aik=exp(eik)/i=1nexp(eik)
  3. 已知所有的输入 h i h_i hi a i k a_{ik} aik, 计算 C k = ∑ i = 1 n a i k h i C_k = \sum^n_{i=1} a_{ik}h_i Ck=i=1naikhi
  4. 已知 s k − 1 s_{k-1} sk1 y k − 1 y_{k-1} yk1 C k C_{k} Ck,计算当前时刻输出的隐藏状态 s k = f ( s k − 1 , y k − 1 , C k ) s_{k} = f(s_{k-1}, y_{k-1}, C_{k}) sk=f(sk1,yk1,Ck)
  5. 已知 s k s_k sk y k − 1 y_{k-1} yk1 C k C_{k} Ck,计算当前时刻输出 y k = g ( y k − 1 , s k , C k ) y_k = g(y_{k-1}, s_k, C_k) yk=g(yk1,sk,Ck)
  6. 有了 s k s_k sk y k y_k yk,又可以继续下一时刻的循环了

第 7 节 · 自注意力机制(Self-Attention)

下面的章节就正式的进入到 transformer 的邻域了。

参考文章:The Illustrated Transformer
在这里插入图片描述这是我参考文章内的图片自己做的一个示意图。通过这个示意图,我来大概地讲解一下 self attention 的计算流程:

  1. 首先一句话中的单词经过 embedding 之后,每个单词都会生成对应的输入向量 x i \mathbf{x_i} xi
  2. 然后 X \mathbf{X} X 通过和对应权重 W Q \mathbf{W^Q} WQ W K \mathbf{W^K} WK W V \mathbf{W^V} WV 进行矩阵乘法,获得 Q \mathbf{Q} Q K \mathbf{K} K V \mathbf{V} V
  3. 通过计算 A = Softmax ( Q ⋅ K T / d k ) \mathbf{A} = \text{Softmax}(\mathbf{Q \cdot K^T /\sqrt{d_k}}) A=Softmax(QKT/dk ) 来获得自注意力权重矩阵。
  4. 最后将自注意力权重矩阵 A \mathbf{A} A 与 value 矩阵 V \mathbf{V} V 进行矩阵乘法,就可以获得 Z \mathbf{Z} Z

为什么要除以 d k \sqrt{d_k} dk
d k d_k dk 表示的是 key 矩阵的中 k i k_i ki 的维度,除以 d k \sqrt{d_k} dk 是为了:

  1. 防止 Q ⋅ K T \mathbf{Q \cdot K^T} QKT 的值过大,导致 softmax 计算的时候出现上溢出(overflow)。
  2. 使得 Q ⋅ K T \mathbf{Q \cdot K^T} QKT 的结果满足期望为 0,方差为 1 的分布。

为什么要计算 Q ⋅ K T \mathbf{Q \cdot K^T} QKT
计算 Q ⋅ K T \mathbf{Q \cdot K^T} QKT 时,从几何的角度来说,相当于对内部的向量 q \mathbf{q} q k \mathbf{k} k 进行点积操作,来计算两个向量的相似度。
q ⋅ k = ∥ q ∥ ∥ k ∥ ⋅ cos ⁡ θ \mathbf{q \cdot k} =\left \| \mathbf{q} \right \| \left \| \mathbf{k} \right \| \cdot \cos \theta qk=qkcosθ

  • 当两个向量垂直的时候, θ = 9 0 ∘ \theta = 90^{\circ} θ=90,就是点积为 0,表示这两个向量没有相似的地方。
  • 当两个向量平行的时候,两个向量的点积即为 ∥ q ∥ ∥ k ∥ \left \| \mathbf{q} \right \| \left \| \mathbf{k} \right \| qk
  • 当两个向量存在夹角 θ \theta θ,两个向量的点积就如上面公式一样。点积就是 q \mathbf{q} q k \mathbf{k} k 上投影的模。

这里 self attention 的 Z \mathbf{Z} Z 和 soft attention 中的 C \mathbf{C} C 是等效的。

第 8 节 · 多头注意力(Multi-Head attention)

多头注意力,其实相当于多次求 self attention,上面的 self attention 的产物是一个 Z \mathbf{Z} Z 矩阵,在多头注意力里,我们通过多组的 W Q \mathbf{W^Q} WQ W K \mathbf{W^K} WK W V \mathbf{W^V} WV,来获得多组的 Z \mathbf{Z} Z

在这里插入图片描述我们将上面 self attention 中计算 Z \mathbf{Z} Z 的过程简化一下,直接得到对应的 Z 0 , Z 1 , ⋯   , Z n \mathbf{Z_0, Z_1, \cdots, Z_n} Z0,Z1,,Zn。然后将其组合起来,与一个新设置的权重矩阵 W o \mathbf{W^o} Wo 相乘,获得最终的 Z \mathbf{Z} Z

多头注意力中的每个头都能关注不同的信息。

第 9 节 · 退化现象、残差网络与 Short-Cut

ResNet 残差网络在 CV 中也经常用到,所及就不详细解说了。

第 10 节 · Transformer 的位置编码(Positional Embedding)

在计算 attention 的时候,我们只是关注词与词之间的相似关系,但是却忽略了位置关系

在 Transformer 中,为了解决这个问题,新增了位置编码(Positional Encoding)。

在这里插入图片描述
大致的流程如上图所示,就是在 embedding 和计算 Q \mathbf{Q} Q K \mathbf{K} K V \mathbf{V} V 之间加入一个位置编码的流程,来将每个词或者说 token 的位置信息加入到输入向量 x \mathbf{x} x 中。

矩阵 P E \mathbf{PE} PE 中的向量 p e \mathbf{pe} pe 内的元素具体是怎么计算的呢? p e t , i = { sin ⁡ ( 1 1000 0 2 i d x ⋅ t )  if  i = 2 k cos ⁡ ( 1 1000 0 2 i d x ⋅ t )  if  i = 2 k + 1         for   k = 0 , 1 , 2 , ⋯   , d x 2 − 1 pe_{t,i} = \begin{cases} \sin(\frac{1}{10000^{\frac{2i}{d_x} }} \cdot t) & \text{ if } i = 2k \\ \cos(\frac{1}{10000^{\frac{2i}{d_x} }} \cdot t) & \text{ if } i= 2k + 1 \end{cases} \space \space \space \space \space \space \space \space \text{for} \space \space k = 0, 1, 2, \cdots, \frac{d_x}{2}-1 pet,i= sin(10000dx2i1t)cos(10000dx2i1t) if i=2k if i=2k+1        for  k=0,1,2,,2dx1其中:

  • d x d_x dx 是向量 x \mathbf{x} x 的维度。
  • k k k 0 0 0 d x / 2 − 1 d_x/2-1 dx/21 的整数

如果 i i i 是偶数的话,就是计算 sin ⁡ \sin sin,如果 i i i 是奇数的话就是计算 cos ⁡ \cos cos。一个完整的 p e \mathbf{pe} pe 向量可以写成下面形式: p e t = [ p e t , 0 , p e t , 1 , ⋯   , p e t , d x ] \mathbf{pe}_t = [pe_{t,0}, pe_{t,1}, \cdots, pe_{t,d_x}] pet=[pet,0,pet,1,,pet,dx]而一个完整的位置编码矩阵可以写成下面形式: P E = [ p e 0 p e 1 ⋮ p e t ] = [ p e 0 , 0 p e 0 , 1 ⋯ p e 0 , d x p e 1 , 0 p e 1 , 1 ⋯ p e 1 , d x ⋮ ⋮ ⋱ ⋮ p e t , 0 p e t , 1 ⋯ p e t , d x ] \mathbf{PE}=\begin{bmatrix} \mathbf{pe}_0 \\ \mathbf{pe}_1 \\ \vdots \\ \mathbf{pe}_t \end{bmatrix}=\begin{bmatrix} pe_{0,0} & pe_{0,1} & \cdots & pe_{0,d_x}\\ pe_{1,0} & pe_{1,1} & \cdots & pe_{1,d_x}\\ \vdots & \vdots & \ddots & \vdots\\ pe_{t,0} & pe_{t,1} & \cdots & pe_{t,d_x} \end{bmatrix} PE= pe0pe1pet = pe0,0pe1,0pet,0pe0,1pe1,1pet,1pe0,dxpe1,dxpet,dx

上面介绍的这种,是绝对编码中的三角式位置编码(Sinusoidal Positional Encoding),除此之外还有相对位置编码。

10.2、绝对位置编码

除了上面提到的三角式位置编码,还有下面几种绝对位置编码:

  • 习得式位置编码:将位置编码矩阵作为可学习的超参数来进行训练,缺点是外推性比较差,推理时输入文本超出训练的最大长度,则无法处理。
  • 循环式位置编码:将向量 x \mathbf{x} x 一个一个送入 RNN 中,RNN 中的模块是 Transformer,因为 RNN 暗含位置信息,所以就不需要进行额外的编码了,但是缺点就是 RNN 的并行性比较差。
  • 相乘式位置编码:使用哈达玛德积(Hadamard product),也就是逐元素相乘来替代相加,也就是 x ⊙ p e x_ \odot pe xpe 代替 x + p e x + pe x+pe

10.3、相对位置编码与其他位置编码

感觉暂时也不需要详细展开了,后续有时间的话再写吧。

第 11 节 · Transformer 的编码器 Encoder 和解码器 Decoder

11.1、Encoder 和 Decoder 的图示结构

在这里插入图片描述
沿用之前的参数符号,上图是 Transformer 的 Encoder 示意图,可以看出来:

  • 输入是经过位置编码的 X p e \mathbf{X}_{pe} Xpe
  • 经过第一个多头注意力模块(其中 MHA \text{MHA} MHA 是 Multi-Head Attention 的缩写)之后,输出的 Z \mathbf{Z} Z
  • 然后经过 Add & Norm 层,将 X p e \mathbf{X}_{pe} Xpe Z \mathbf{Z} Z 相加之后进行层归一化(LayerNorm),输出 X out 1 \mathbf{X}_{\text{out}1} Xout1
  • 然后输入 Feed Forward 层,这是由两个全连接层组成的,第一个全连接层的激活函数是 ReLU,第二个全连接层没有激活函数。得到我们的 F \mathbf{F} F
  • 最后再经过一次 Add & Norm 层,进行层归一化操作,得到 Encoder 的最终输出 X out 2 \mathbf{X}_{\text{out}2} Xout2

其中可以看到 Encoder 中存在两条 short-cut。

在这里插入图片描述

第一个 masked multi-head attention

接下来看看 Decoder 的结构,除了一个新的 masked multi-head attention 模块,其他模块都和 Encoder 的类似,所以具体的计算公式就不标注出来了。

我们说一下 masked multi-head attention 模块,这个 masked 的对象是什么,具体有什么用?

我们这里以单个注意力模块,也就是 self attention 来举例子,其实 masked 的操作主要是加在注意力权值矩阵进行 softmax 操作之前。
在这里插入图片描述
这是我从 self attention 示意图中抽取的注意力权值矩阵计算部分,左边是普通的计算注意力权值矩阵,在求解 A ′ \mathbf{A'} A 之后,直接对其进行 softmax 操作就行了。

而右边则是包含 mask 操作的,在进行 softmax 操作之前,先进行一个 mask 操作,防止后续标签进行对前面的预测进行影响,因为我们知道 Transformer 中 Decoder 也会输入一次输入序列,但是和 Encoder 部分不同的是,会对输入数列进行一个右移(shifted right)的操作。类似 Encoder 如果输入 [i am a student],那么 Decoder 部分,则会输入 [ I am a student],多了一个起始符,这个起始符就是用于预测 “I” 的。

第二个 multi-head attention

这个注意力模块也可以叫做 cross attention 模块,或者是 encoder-decoder attention 模块

第二个多头注意力模块,其实我们注意到,有两条线是来自于 Encoder,我们知道在计算 self attention 的时候,首先我们要计算 Q \mathbf{Q} Q K \mathbf{K} K V \mathbf{V} V 三个矩阵,一般来说,这三个矩阵都是一个输入和对应的权重矩阵计算获得的。

但是在 Decoder 的第二个多头注意力模块中,其中 K \mathbf{K} K V \mathbf{V} V 是由 Encoder 的输出 X out 2 \mathbf{X}_{\text{out}2} Xout2 计算获得的,而 Q \mathbf{Q} Q 是由 Decoder 的第一个 masked multi-head attention 模块的输出计算获得的。

11.2、Decoder 的第一个输出结果

我理解为 Transformer 是由很多个 Decoder block 组成的,但是第一个 Decoder block 和后续的 Decoder block 有一点细微的差别

在这里插入图片描述
假设 Transformer 一共有 N N N 个 Decoder block,第一个 Decoder block 是不含 masked multi-head attention 模块的。后续的 N − 1 N-1 N1 个 Decoder block 才是我们上面分析的正常的 Decoder block,这是为什么?

为什么 transformer的第一个 decoder blcok 不需要经过 masked multi-head attention 模块?

在 Transformer 模型中,第一个 Decoder block 的出结果是基于 Encoder 的输出和 Decoder 的初始输入(通常是起始符号,如)生成的。这个过程不需要经过 Masked Multi-Head Attention Layer,因为即便是经过了多头注意力模块,

11.3、Decoder 后续的所有输出

没看懂

11.4、Decoder 之后的 Linear 和 Softmax

这个部分其实和 cv 中的分类最后是一样的,只是 transformer 中的类别是词汇表。

第 12 节 · Transformer 模型整体

在这里插入图片描述

  • 首先输入数据生成词的嵌入式向量表示(Embedding),生成位置编码(Positional Encoding,简称 PE)。进入
  • Encoders 部分。先进入多头注意力层(Multi-Head Attention),是自注意力处理,然后进入全连接层(又叫前馈神经网络层),每层都有 ResNet、Add & Norm。
  • 每一个Encoder 的输入,都来自前一个 Encoder 的输出,但是第一个 Encoder 的输入就是 Embedding + PE。
  • 进入 Decoders 部分。先进入第一个多头注意力层(是 Masked 自注意力层),再进入第二个多头注意力层(是 Encoder-Decoder 注意力层),每层都有 ResNet、Add & Norm。
  • 每一个 Decoder 都有两部分输入。
  • Decoder 的第一层(Maksed 多头自注意力层)的输入,都来自前一个 Decoder 的输出,但是第一个 Decoder 是不经过第一层的(因为经过算出来也是 0)
  • Decoder 的第二层(Encoder-Decoder 注意力层)的输入,Q 都来自该 Decoder 的第一层,且每个 Decoder 的这一层的 K、V 都是一样的,均来自最后一个 Encoder。* 最后经过 Linear、Softmax 归一化。

后面的部分基本都是实际训练部分了。

参考文章:举个例子讲下transformer的输入输出细节及其他

但是感觉 transformer decoder 的输入输出维度还是不是很清晰

  • 输入输出的维度是多少?
  • 上一个 decoder 的输出是怎么整合到下一个 decoder 的输入的
  • 训练的时候输入的是 ground truth,但是推理的时候 decoder 的输入维度是多少?
  • transformer 的并行训练体现在哪里?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/433628.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Xilinx高级调试方法--远程调试

Xilinx高级调试方法--远程调试 1 虚拟电缆调试2 FPGA设计2.1 扩展配置接口 3 PCIe-XVC驱动3.1 PCIe-XVC驱动3.2 XVC-Server 4 Vivado Design Suite4.1 同一台主机4.2 不同主机 本文主要介绍Xilinx的一些高级调试方法,以及如何使用Xilinx的相关IP。 1 虚拟电缆调试 …

CAN通信篇 - CanSM模块配置(五)

文章目录 CanSMConfigurationCanSMManagerNetworkCanSMGeneralCanSMGeneration总结Can State Manager (CanSM)模块,是CAN网络的状态管理模块,所有对CAN网络状态的请求都是通过CanSM实现。这里我们介绍一下在Davinci Configurator中CanSM模块的配置。 在CanSM模块的总线管理…

游泳耳机哪个牌子好?四大热卖游泳耳机汇总,年度首选

在当今日益注重健康生活方式的时代,游泳作为一项全身性的有氧运动备受青睐。然而,对于许多游泳爱好者来说,水下世界的孤独可能会让他们感到无聊。而游泳耳机的出现不仅为游泳者带来了音乐的陪伴,还让他们能够在水下畅享各种声音&a…

【译】WordPress Bricks主题安全漏洞曝光,25,000个安装受影响

WordPress的Bricks主题存在一个严重的安全漏洞,恶意威胁行为者正在积极利用该漏洞在易受攻击的安装上运行任意PHP代码。 该漏洞被跟踪为CVE-2024-25600(CVSS评分:9.8),使未经身份验证的攻击者能够实现远程代码执行。它…

【MySQL】事务?隔离级别?锁?详解MySQL并发控制机制

目录 1.先理清一下概念 2.锁 2.1.分类 2.2.表锁 2.3.行锁(MVCC) 2.4.间隙锁 2.5.行锁变表锁 2.6.强制锁行 1.先理清一下概念 所谓并发控制指的是在对数据库进行并发操作时如何保证数据的一致性和正确性。在数据库中与并发控制相关的概念有如下几…

【企业动态】欢迎法国客户来访东胜物联,深入探讨智能化合作

本周,来自法国的客户莅临我司工厂进行实地参观考察。客户是一家历史悠久的设备供应商,其产品涵盖冷链、餐饮、农业等多个行业应用领域,正致力于从传统设备向智能设备转型,希望将设备接入物联网。在此次访问中,他们参观…

geoserver+mapbox-gl 离线部署矢量切片地图服务学习笔记

geoserver安装 geoserver的安装包可以在官网下载Download - GeoServer,想要选择版本点击Archived找到指定版本进行下载http://geoserver.org/download/ (如果网络不稳定,也可以直接使用下面的下载地址) geoserver-2.15.0.rar资…

从新手到专家:一探究竟,最佳的Excel学习网站推荐!

介绍:Excel是一款由微软公司开发的电子表格软件,是Microsoft Office套件的一部分。它通过网格形式的工作表提供数据存储、分析和可视化等功能,适用于个人计算机数据处理。具体介绍如下: 数据存储:Excel能够存储大量数据…

大语言模型(LLM):每个专业人士的完美助手

「大语言模型(LLM)革命」:ChatGPT如何引领工作效率新篇章 在不断发展的技术领域,像 ChatGPT 这样的大型语言模型 (LLM) 已成为各行业专业人士不可或缺的工具。 这篇博文探讨了大语言模型(LLM)在专业环境中的…

Linux第69步_依据“旧字符设备的一般模板”编写LED驱动

在编写LED驱动之前,先要了解和硬件有关的一些知识。 1、了解“MMU内存管理单元”以及相关函数 MMU是Memory Manage Unit的缩写,意思是“内存管理单元”。 老版本的Linux内核要求处理器必须有“MMU内存管理单元”,而现在的Linux内核已经支持…

车牌定位识别企业版

车牌定位识别企业版,只需要OPENCV,采用YOLOV8NANO检测车牌区域,然后使用PADDLE OCR检测车牌,能识别各国车牌,支持C,PYTHON开发 车牌定位识别企业版,只需要OPENCV,支持C,python

什么是云游戏?云游戏平台可以运行3A游戏吗?

对于不熟悉游戏行业的人来说,面对云游戏可能会有一个疑问——除了单机游戏,现在所有游戏不都是联网玩吗?云游戏和网络游戏有什么区别? 实际上,云游戏和传统网络游戏有着本质的不同。 传统网络游戏需要玩家先下载并在本…

【HTML】HTML基础7.1(无序列表)

目录 标签 属性 效果 注意 标签 <ul> <li>列表里要装的东西</li> <li>列表里要装的东西</li> <li>列表里要装的东西</li> </ul> 属性 type&#xff1a; circle空心圆disc实心圆square方框 效果 circle空心圆效果…

Positional Encoding 位置编码

Positional Encoding 位置编码 flyfish Transformer模型没有使用循环神经网络&#xff0c;无法从序列中学习到位置信息&#xff0c;并且它是并行结构&#xff0c;不是按位置来处理序列的&#xff0c;所以为输入序列加入了位置编码&#xff0c;将每个词的位置加入到了词向量中…

【hugggingface】批量加速下载HuggingFace上的模型

镜像网站及说明&#xff1a;https://hf-mirror.com/ 其他教程&#xff1a;如何快速下载huggingface模型——全方法总结 一、huggingface-cli方法下载 1.1安装依赖 pip install -U huggingface_hub1.2 设置环境变量 linux export HF_ENDPOINThttps://hf-mirror.comwindows …

如何挑选好的游泳耳机?游泳耳机的六大避坑指南!

游泳耳机是现代科技与运动健康完美结合的产物&#xff0c;对于热爱水上运动的朋友来说&#xff0c;一款好的游泳耳机不仅能让你在水中畅游时享受到音乐带来的乐趣&#xff0c;还能保护你的听力。然而&#xff0c;市场上琳琅满目的游泳耳机品牌和型号让人眼花缭乱&#xff0c;如…

08、MongoDB -- MongoDB 的 集合关联($lookup 和 DBRef 实现集合关联)

目录 MongoDB 的 集合关联演示前提&#xff1a;登录单机模式的 mongodb 服务器命令登录【test】数据库的 mongodb 客户端命令登录【admin】数据库的 mongodb 客户端命令 SQL 术语 与 Mongodb 的对应关系使用 $lookup 实现集合关联语法格式添加测试数据1、查询出订单数量大于6&a…

混沌工程-经典案例分享

目录 前言 案例 1、强弱依赖不合理 2、预案不生效 3、异常数据不兼容 4、监控体系缺陷 5、系统缺整体架构设计 总结 前言 我们公司从启动混沌工程到现在已经几乎覆盖了线上的所有核心业务&#xff0c;先后进行过2000次演练共挖掘出120个漏洞。这些漏洞有些得了及时修复…

C if...else 语句

一个 if 语句 后可跟一个可选的 else 语句&#xff0c;else 语句在布尔表达式为 false 时执行。 语法 C 语言中 if…else 语句的语法&#xff1a; if(boolean_expression) {/* 如果布尔表达式为真将执行的语句 */ } else {/* 如果布尔表达式为假将执行的语句 */ }如果布尔表…

Java Day2 面向对象

这里写目录标题 1、static总结1.1 代码块1.1.1 静态代码块1.1.2 实例代码块1.1.3 小例子 2、继承2.1 权限修饰符2.2 方法重写2.3 子类访问成员特点2.4子类构造器的特点 3、多态4、final、常量4.1 final4.2 常量 5 抽象类5.1 概念5.2 模板设计方法 6、接口6.1 接口新方法6.2 接口…