相关论文介绍
- Transformer原始文章:
- Google Brain, NIPS 2017: Attention Is All You Need
- 文章中介绍了一种应用Attention机制的新型特征提取器,命名为Transformer, 实验证明Transformer优于RNN(LSTM),CNN等常规的特征提取器
- Transformer的使用:
- GPT: Improving Language Understanding by Generative Pre-Training
- BERT: BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding
- 以上两个工作都使用了Transformer作为特征提取器, 使用两阶段训练的方式实现迁移学习(Pre-Training and Fine-Training)
相关博客介绍
- 强烈推荐看看jalammar的博客: illustrated-transformer
- 另一篇不错的Attention和Transformer讲解自然语言处理中的自注意力机制(Self-Attention Mechanism)
- 一篇很多个人理解的博客 《Attention is All You Need》浅读
Transformer讲解
- 最直观的动态图理解
- 本文讲解主要按照Google Brain, NIPS 2017: Attention Is All You Need的思路走,该论文的亮点在于:
- 不同于以往主流机器翻译使用基于 RNN 的 Seq2Seq 模型框架,该论文用 Attention 机制代替了 RNN 搭建了整个模型框架, 这是一个从换自行车零件到把自行车换成汽车的突破
- 提出了多头注意力(Multi-Head Attention)机制方法,在编码器和解码器中大量的使用了多头自注意力机制(Multi-Head self-attention)
- 在WMT2014语料库的英德和英法语言翻译任务上取得了先进结果
Transformer是什么?
- 本质上是个序列转换器
- 进一步讲,是个 Encoder-Decoder 模型的序列转换器
- 更进一步的讲,是个 6层Encoder + 6层Decoder 结构的序列转换器
- 上面的图中,每个 Encoder 是
- 详细的讲, 每个Encoder是
- 展开看里面 Encoder 中的数据流向
- 更进一步的展开看 Encoder 中的数据流向
- 两层 Encoder + 两层Decoder (其中一个Decoder没有完全画出来) 的数据流向
- 带细节动图查看数据流向
- 最后,我们给出Transformer的结构图(来自原文中)
Transformer中的Attention
Transformer中使用了 Multi-Head Attention, 同时也是一种 Self Attention
- 由于Transformer的Multi_Head Attention中 Query == Key == Query, 所以也是一种 Self Attention
- 即$$\boldsymbol{Y_{AttentionOutput}} = Self Attention(\boldsymbol{Q},\boldsymbol{K},\boldsymbol{V}) = Attention(\boldsymbol{X},\boldsymbol{X},\boldsymbol{X})$$
- 更多关于广义Attention的理解请参考: DL——Attention
Multi-Head Attention
- Muti-Head Attention 由 \(h\) 个 Scaled Dot-Product Attention和其他线性层和Concat操作等组成
- Scaled Dot Product Attention中Mask操作是可选的
- Scaled Dot Product Attention数学定义为(没有Mask操作)
$$
\begin{align}
Attention(\boldsymbol{Q},\boldsymbol{K},\boldsymbol{V}) = softmax\left(\frac{\boldsymbol{Q}\boldsymbol{K}^{\top}}{\sqrt{d_k}}\right)\boldsymbol{V}
\end{align}
$$ - Multi-Head Attention的某个输出的数学定义为
$$
\begin{align}
MultiHead(\boldsymbol{Q}, \boldsymbol{K}, \boldsymbol{V}) &= Concat(head_1,\dots,head_h)\boldsymbol{W}^{O} \\
where \quad head_i &= Attention(\boldsymbol{Q}\boldsymbol{W}_i^Q,\boldsymbol{K}\boldsymbol{W}_i^K,\boldsymbol{V}\boldsymbol{W}_i^V)
\end{align}
$$
有关Multi-Head Attention的理解
- 原论文的描述:
Multi-head attention allows the model to jointly attend to information from different representation subspaces at different positions,
- 理解:
- 所谓多头,就是多做几次(\(h\)次)同样的事情(参数\((W_i^Q, W_i^K, W_i^V)\)不共享, 即当 \(i \neq j \) 时, \((W_i^Q, W_i^K, W_i^V) \neq (W_j^Q, W_j^K, W_j^V)\)),然后把结果拼接
- Multi-Head Attention中, 每个头(Scaled Dot-Product Attention)负责不同的子空间(subspaces at differect positions)
- 每个头权重不同, 所以他们的关注点也会不同,注意, 初始化时他们的参数不能相同, 否则会造成他们的参数永远相同, 因为他们是同构的
- 个人理解: 多头的作用可以类比于CNN中的卷积层, 负责从不同的角度提取原始数据的特征
Self Attention
- Self Attention是只 Key和Query相同的 Attention, 这里因为 Key 和 Value 也相同,所以有 Query == Key == Query
- 即$$ \boldsymbol{Y_{AttentionOutput}} = Self Attention(\boldsymbol{Q},\boldsymbol{K},\boldsymbol{V}) = Attention(\boldsymbol{X},\boldsymbol{X},\boldsymbol{X})$$
Transformer中的Attention
- 既是Multi-Head Attention, 也是 Self Attention
- 所以有$$\boldsymbol{Y_{AttentionOutput}} = MultiHead(\boldsymbol{X},\boldsymbol{X},\boldsymbol{X})$$
Transformer 输入层
- Transformer的输入层使用了 Word Embedding + Position Embedding
- 由于Transformer去除RNN的Attention机制完全不考虑词的顺序, 也就是说, 随机打乱句子中词的顺序 (也就是将键值对\((\boldsymbol{K}, \boldsymbol{V})\)对随机打乱), Transformer中Attention的结果不变
- 实际上, 目前为止, Transformer中的Attention模型顶多是个非常精妙的”词袋模型” (这句话来自博客:https://kexue.fm/archives/4765)
Word Embedding
- 和之前的词嵌入一样, 将One-Hot值映射成词向量嵌入模型中
Position Embedding
FaceBook的《Convolutional Sequence to Sequence Learning》中曾经用过Position Embedding
- 在不使用RNN的情况下建模词的顺序, 弥补”词袋模型”的不足
- 用 Position Embedding来为每个位置一个向量化表示
- 将每个位置编号,然后每个编号对应一个向量
- 通过结合位置向量和词向量,就给每个词都引入了一定的位置信息,这样Attention就可以分辨出不同位置的词了
- 原始论文中, 作者提出了一种周期性位置编码的表示, 数学公式如下:
$$
\begin{align}
PE(pos,2i) &= sin(pos/10000^{2i/d_{\text{model}}}) \\
PE(pos, 2i+1) &= cos(pos/10000^{2i/d_{\text{model}}})
\end{align}
$$ - 我觉得上述公式太丑了,转换一下写法可能更容易理解
$$
\begin{align}
PE(pos,2i) &= sin\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) \\
PE(pos, 2i+1) &= cos\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right)
\end{align}
$$- \(pos\) 是位置编号
- \(i\) 表示位置向量的第 \(i\) 维
- 为什么选择\(10000^{\frac{2i}{d_{\text{model}}}}\)? [待更新]
- 每个维度的位置编码对应着一个正弦函数, 周期为 \(2\pi\)到 \(10000\cdot 2\pi\)
- 选择正弦函数的原因是假设这将允许模型学到相对位置信息
- 因为对于固定的 \(k\), \(PE_{pos+k} = LinearFuction(PE_{pos})\), 所以这给模型提供了表达相对位置的可能性
与之前的Position Embedding的区别
- Position Embedding对模型的意义不同:
- 以前在RNN、CNN模型中Position Embedding是锦上添花的辅助手段,也就是“有它会更好、没它也就差一点点”的情况,因为RNN、CNN本身就能捕捉到位置信息
- 在Transformer这个纯Attention模型中,Position Embedding是位置信息的唯一来源,因此它是模型的核心成分之一,并非仅仅是简单的辅助手段
- Position Embedding的向量构造方式不同
- 在以往的Position Embedding中,基本都是根据任务训练出来的向量
- 而Google直接给出了一个构造Position Embedding的公式:
$$
\begin{align}
PE(pos,2i) &= sin\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right) \\
PE(pos, 2i+1) &= cos\left (\frac{pos}{10000^{\frac{2i}{d_{\text{model}}}}}\right)
\end{align}
$$ - Google经过实验, 学到的位置嵌入和这种计算得到的位置嵌入结果很相近
- Google选用这种嵌入方式的原因是这种方式允许模型以后可以扩展到比训练时遇到的序列长度更长的句子
输入层的输出(Attention的输入)
- 综合词嵌入和位置嵌入信息,我们可以得到下面的公式
$$
\begin{align}
\boldsymbol{x} = \boldsymbol{x}_{WE} + \boldsymbol{x}_{PE}
\end{align}
$$- \(\boldsymbol{x}\) 为输入层经过词嵌入和位置嵌入后的 输出, 也就是Attention的输入
- \(\boldsymbol{x}_{WE}\) 指词嵌入的结果
- \(\boldsymbol{x}_{PE}\) 指位置嵌入的结果
Transformer总结
- Transformer是一个特征提取能力非常强(超越LSTM)的特征提取器
- 一些讨论
- Transformer与CNN没关系,但是Transformer中使用多个 Scaled Dot-Product Attention 来最后拼接的方法(Multi-Head Attention), 就是CNN的多个卷积核的思想
- Transformer论文原文中提到的残差结构也来源于CNN
- 无法对位置信息进行很好地建模,这是硬伤。尽管可以引入Position Embedding,但我认为这只是一个缓解方案,并没有根本解决问题。举个例子,用这种纯Attention机制训练一个文本分类模型或者是机器翻译模型,效果应该都还不错,但是用来训练一个序列标注模型(分词、实体识别等),效果就不怎么好了。那为什么在机器翻译任务上好?我觉得原因是机器翻译这个任务并不特别强调语序,因此Position Embedding 所带来的位置信息已经足够了,此外翻译任务的评测指标BLEU也并不特别强调语序
- Attention如果作为一个和CNN,RNN平级的组件来使用,可能会集成到各自的优点, 而不是”口气”很大的 “Attention is All You Need”