Transformer模型解读

contextualized word vectors

RNN, LSTM

RNN(I study at Julyedu.) –> RNN(I)->h1, RNN(study, h1)->h2, RNN(at, h2)->h3.

Encoder. 我可以同时观看全局信息。

query, keys, values

q1, q2, .., q5

k1, k2, k3, k4, k5

score(q, k1), score(q, k2), …, score(q, k5)

v1, v2, v3, v4, v5

\sum_{i=1}^5 func(score_i) v_i

dot(a, b)

mean

var(dot(a, b))

dot(a, b) = a1b1 + a2b2. ….

E(dot(a, b)) = n * E(ai*bi)

var(dot(a, b)) = E(dot(a, b)^2) - E(dot(a, b))^2

affine transformation

WX+b

Attention(Q, K, V ) = softmax(QKT √ dk )V

Q : seq_len, hid_size

K^T: hid_size, seq_len

V: seq_len, hid_size

QK^T : seq_len, seq_len

QK^T V: seq_len, hid_size

[emb_w(x), emb_p(i)]W –>

近两年来,NLP领域的模型研究已经被transformer模型以及它的各种变种给占领了。Transformer模型的火爆有很多原因,例如:

  • 模型简单易懂,encoder和decoder模块高度相似且通用

  • (encoder)容易并行,模型训练速度快

  • 效果拔群,在NMT等领域都取得了state-of-the-art的效果

论文地址

下面的文章翻译自

高屋建瓴地说,Transformer模型拿到一个序列,用来生成另一个序列。

img

打开这个黑箱,我们会看到其中包含了两个部分,encoders和decoders。

img

其中encoders和decoders都是两个堆叠架构。一层一层同质的结构堆叠到一起,组成了编码器和解码器。

img

首先我们打开每个encoder来参观一下其中包含的内容:

img

每一个encoder都包含了一个自注意力(self-attention)层和一个Feed Forward Neural Network。

encoder的输入首先会经过一个self-attention层。self-attention的作用是让每个单词可以看到自己和其他单词的关系,并且将自己转换成一个与所有单词相关的,focus在自己身上的词向量(?)

self-attention之后的输出会再经过一层feed-forward神经网络。每个位置的输出被同样的feed-forward network处理。

decoder也有同样的self-attention和feed-forward结构,但是在这两层之间还有一层encoder-decoder attention层,帮助decoder关注到某一些特别需要关注的encoder位置。

Tensor的变化

img

编码器

下面我们来详细解读一下编码器的工作。

img

Self-Attention机制

我们考虑用Transformer模型翻译下面这一句话:

“The animal didn’t cross the street because it was too tired”。

当我们翻译到 it 的时候,我们知道 it 指代的是 animal 而不是 street。所以,如果有办法可以让 it 对应位置的 embedding 适当包含 animal 的信息,就会非常有用。self-attention的出现就是为了完成这一任务。

如下图所示,self attnetion会让单词 it 和 某些单词发生比较强的联系,得到比较搞的attention分数。

img

weight(The) = softmax(v(it) * v(The) / \sqrt(d))

weight(The) = softmx(Query(It) * Key(The) / \sqrt(d))

\sum_{word} weight(word) * Value(word)

Self-attention的细节

为了实现 self-attention,每个输入的位置需要产生三个向量,分别是 Query 向量,Key 向量和 Value 向量。这些向量都是由输入 embedding 通过三个 matrices (也就是线性变化)产生的。

注意到在Transformer架构中,这些新的向量比原来的输入向量要小,原来的向量是512维,转变后的三个向量都是64维。

img

第二步是计算分数。当我们在用self-attention encode某个位置上的某个单词的时候,我们希望知道这个单词对应的句子上其他单词的分数。其他单词所得到的分数表示了当我们encode当前单词的时候,应该放多少的关注度在其余的每个单词上。又或者说,其他单词和我当前的单词有多大的相关性或者相似性。

在transformer模型中,这个分数是由query vector和key vector做点积(dot product)所得的结果。所以说,当我们在对第一个单词做self-attention处理的时候,第一个单词的分数是q_1和k_1的点积,第二个分数是q_1和k_2的分数。

img

第三步和第四步是将这些分数除以8。8这个数字是64的开方,也就是key vector的维度的开方。据说这么做可以稳定模型的gradient。然后我们将这些分数传入softmax层产生一些符合概率分布的probability scores。

img

softmax = exp(x_i) / sum exp(x_i)

这些分数就表示了在处理当前单词的时候我们应该分配多少的关注度给其他单词。

第五步是将每个value vector乘以它们各自的attention score。第六步是把这些weighted value vectors相加,成为当前单词的vector表示。

img

得到了self-attention生成的词向量之后,我们就可以将它们传入feed-forward network了。

Self-Attention中的矩阵运算

首先,我们要对每一个词向量计算Query, Key和Value矩阵。我们把句子中的每个词向量拼接到一起变成一个矩阵X,然后乘以不同的矩阵做线性变换(WQ, WK, WV)。

img

然后我们就用矩阵乘法实现上面介绍过的Self-Attention机制了。

img

Multi-headed attention

在论文当中,每个embedding vector并不止产生一个key, value, query vectors,而是产生若干组这样的vectors,称之为”multi-headed” attention。这么做有几个好处:

  • k: key, q: query, v: value

  • 模型有更强的能力产生不同的attention机制,focus在不同的单词上。

  • attention layer有多个不同的”representation space”。

img

每个attention head最终都产生了一个matrix表示这个句子中的所有词向量。在transformer模型中,我们产生了八个matrices。我们知道self attention之后就是一个feed-forward network。那么我们是否需要做8次feed-forward network运算呢?事实上是不用的。我们只需要将这8个matrices拼接到一起,然后做一次前向神经网络的运算就可以了。

img

综合起来,我们可以用下面一张图表示Self-Attention模块所做的事情。

img

Positional Encoding

thinking machine

w_1, w_2

p_1, p_2

positional_embedding = nn.Embedding(512, 300)

w_1 + p_1, w_2 + p_2, w_3 + p_3, …, w_n + p_n

到目前为止,我们的模型完全没有考虑单词的顺序。即使我们将句子中单词的顺序完全打乱,对于transformer这个模型来说,并没有什么区别。为了加入句子中单词的顺序信息,我们引入一个概念叫做positional encoding。

img

如果我们假设输入的embedding是4个维度的,那么他们的position encodings大概长下面这样。

img

下面这张图的每一行表示一个positional encoding vector。第一行表示第一个单词的positional encoding,以此类推。每一行都有512个-1到1之间的数字。我们用颜色标记了这些vectors。

img

Residuals

另外一个细节是,encoder中的每一层都包含了一个residual connection和layer-normalization。如下图所示。

img

下面这张图是更详细的vector表示。

img

decoder也是同样的架构。如果我们把encoder和decoder放到一起,他们就长这样。

img

解码器

encoder最后一层会输出attention vectors K和V。K和V会被decoder用作解码的原材料。

img

在解码的过程中,解码器每一步会输出一个token。一直循环往复,直到它输出了一个特殊的end of sequence token,表示解码结束了。

img

decoder的self attention机制与encoder稍有不同。在decoder当中,self attention层只能看到之前已经解码的文字。我们只需要把当前输出位置之后的单词全都mask掉(softmax层之前全都设置成-inf)即可。

softmax(Q matmul K^T / sqrt(d)) matmul V

weights = Q matmul K^T: [seq_len, seq_len]

Masked Self Attention

q, k (100, 24, 35 - inf, 88 - inf, -55 - inf) –> softmax –> (0.9, 0.1, 0, 0, 0)

attention_mask

0, -inf, -inf, -inf

0, 0, -inf, -inf

0, 0, 0, -inf

0, 0, 0, 0

softmax(weights - attention_mask, -1)

训练

QKV, 并行训练

预测

一个单词一个单词解码

Encoder-Decoder Attention层和普通的multiheaded self-attention一样,除了它的Queries完全来自下面的decoder层,然后Key和Value来自encoder的输出向量。

batch_size * seq_length * hidden_size

padding_mask

tgt_mask

最后的线性层和softmax层

解码器最后输出浮点向量,如何将它转成词?这是最后的线性层和softmax层的主要工作。

线性层是个简单的全连接层,将解码器的最后输出映射到一个非常大的logits向量上。假设模型已知有1万个单词(输出的词表)从训练集中学习得到。那么,logits向量就有1万维,每个值表示是某个词的可能倾向值。

softmax层将这些分数转换成概率值(都是正值,且加和为1),最高值对应的维上的词就是这一步的输出单词。

img

模型的训练

现在我们已经了解了一个训练完毕的Transformer的前向过程,顺道看下训练的概念也是非常有用的。在训练时,模型将经历上述的前向过程,当我们在标记训练集上训练时,可以对比预测输出与实际输出。为了可视化,假设输出一共只有6个单词(“a”, “am”, “i”, “thanks”, “student”, “”)

img

模型的词表是在训练之前的预处理中生成的

一旦定义了词表,我们就能够构造一个同维度的向量来表示每个单词,比如one-hot编码,下面举例编码“am”。

img

举例采用one-hot编码输出词表

下面让我们讨论下模型的loss损失,在训练过程中用来优化的指标,指导学习得到一个非常准确的模型。

损失函数

我们用一个简单的例子来示范训练,比如翻译“merci”为“thanks”。那意味着输出的概率分布指向单词“thanks”,但是由于模型未训练是随机初始化的,不太可能就是期望的输出。

img

由于模型参数是随机初始化的,未训练的模型输出随机值。我们可以对比真实输出,然后利用误差后传调整模型权重,使得输出更接近与真实输出。如何对比两个概率分布呢?简单采用 cross-entropy或者Kullback-Leibler divergence中的一种。鉴于这是个极其简单的例子,更真实的情况是,使用一个句子作为输入。比如,输入是“je suis étudiant”,期望输出是“i am a student”。在这个例子下,我们期望模型输出连续的概率分布满足如下条件:

  1. 每个概率分布都与词表同维度

  2. 第一个概率分布对“i”具有最高的预测概率值。

  3. 第二个概率分布对“am”具有最高的预测概率值。

  4. 一直到第五个输出指向””标记。

img

对一个句子而言,训练模型的目标概率分布

在足够大的训练集上训练足够时间之后,我们期望产生的概率分布如下所示:

img

训练好之后,模型的输出是我们期望的翻译。当然,这并不意味着这一过程是来自训练集。注意,每个位置都能有值,即便与输出近乎无关,这也是softmax对训练有帮助的地方。现在,因为模型每步只产生一组输出,假设模型选择最高概率,扔掉其他的部分,这是种产生预测结果的方法,叫做greedy 解码。另外一种方法是beam search,每一步仅保留最头部高概率的两个输出,根据这俩输出再预测下一步,再保留头部高概率的两个输出,重复直到预测结束

更多资料

文章目录
  1. 1. Tensor的变化
  2. 2. 编码器
    1. 2.1. Self-Attention机制
    2. 2.2. Self-attention的细节
    3. 2.3. Self-Attention中的矩阵运算
    4. 2.4. Multi-headed attention
    5. 2.5. Positional Encoding
    6. 2.6. Residuals
  3. 3. 解码器
    1. 3.1. 最后的线性层和softmax层
  4. 4. 模型的训练
    1. 4.1. 损失函数
  5. 5. 更多资料
|