目录
引言
Transformer在今天已经非常火了, 不管是NLP, 还是CV, 效果表现均很好. 那么这是Transformer到底是什么呢?
要把Transformer的来龙去脉讲清楚, 首先得从attention开始, attention刚出来时, 直接把Google翻译送上了人生巅峰.
在Transformer的出现之前的NLP相比CV来说并不那么活跃, 同时难度相对也比较大, 用得最多的也就是LSTM那一套, 不可能像CV那样模型可迁移性很强.
而Transformer的出现后, 简直把NLP推进几十年的节奏. 改变了上述情况, 不仅可迁移性强, 计算效率也比LSTM高了多少倍.
现在Transformer更是在CV领域如火如荼, 下面就先从attention开始慢慢讲一下整个来弄去脉, 以及算法思想, 内部逻辑.
Attention
Attention是什么呢?
举个例子: 把眼前的实物看成一副图像的话, 我们通常只会关注到里面的某个部分, 例如某个美女帅哥等, 很多别的信息就被过滤掉了.
其最早应该是用于图像里面的(Recurrent Models of Visual Attention), 参考Attention:Recurrent Models of Visual Attention阅读笔记
Neural Machine Translation by Jointly Learning to Align and Translate中,将attention机制首次应用在nlp领域,其采用Seq2Seq+Attention模型来进行机器翻译,并且得到了效果的提升, 参考Seq2Seq With Attention. 与早期的注意力比较, 又有了很多改进.
其实我最开始看到Attention这个次是在Google’s Neural Machine Translation System, 不过这里面关于注意力的部分几乎与14年那篇相同.
为什么需要Attention?
例如在翻译任务中, 当句子太长时, 很难让编码器记住所有的信息用于翻译每个部分.
Attention的具体原理是怎么回事呢?
举个例子: 在翻译任务中, 在翻译某个词时, 可能只需要部分临近的词语, 别的部分对该词语的翻译并不具有太大的作用, 那么此时, 应该对临近的词语关注度更大, 其余部分关注度降低.
说到这里, 有没有觉得跟CV里面的2017年的SENet很像?
其实2017年的另外一篇CV论文NetSlimming也基本上如出一辙.
估计这两篇的作者, 也是受到Attention的启发.
通过这个例子, 现在我们应该对Attention有一个大概的认知了:
> 输出不同的权重即可, 且需要保证
> 输入应该是哪些呢? 以最开始眼前实物为例, 从人的视角出发, 输入的信息首先得包含所有原始信息, 其次需要兴趣点, 不同的兴趣点, 关注到的内容也不同.
在翻译任务编解码模型Neural Machine Translation by Jointly Learning to Align and Translate翻译任务编解码模型中, 原始信息也就是Encode的全部输出, 兴趣点则是每个Decode的隐层.
上图中的Attention输出并不是权重, 而直接是结果. 也就是对一段原始信息进行兴趣点提问, 直接得出最终结果.
用数学语言来描述上图中的Attention模块输出的context就是, 公式(1.1):
经过上面一堆的描述, Attention的本质基本上就是要呼之欲出了: 计算原始信息与兴趣点的相关性. 相关性越强的, 权重越大, 相关性越小的, 权重越小.
Attention进化版本
先给出的公式(1.2):
如果将公式(1.1)写成公式(1.2)的形式, 则是公式(1.3):
为什么感觉的更流行, 没有怎么直接看到
呢?
> An attention function can be described as mapping a query and a set of key-value pairs to an output, where the query, keys, values, and output are all vectors.
> The output is computed as a weighted sum of the values, where the weight assigned to each value is computed by a compatibility function of the query with the corresponding key.
我的理解是
> 在神经网络中, 说提出的问题比较复杂, 不便于直接从原始信息中得到结论
> 假设原始数据为
> 将其变为, 对其进行提问
, 所得到的答案需要从
中提取
上面这么来说可能比较晦涩, 举个例子
> 原文: 13+7=20
> 提问: 如果是8进制, 上式还能成立吗?
> 解题过程中
> - 需要将13, 7, 20转成10进制 => 也就是
> - 再计算看是否相等 =>
讲到了这里, 再多说几句, CNN之前, 大家会手工设计卷积核, 例如SURF算法. 有了CNN后, 需要什么卷积核, 交给模型自己去学习.
那么在Attention的时代, 需要提什么问题? 需要对什么提问? 需要什么来回答? 全部都交给模型自己去学习. 很美妙是吧, 已经是成熟的模型了, 可以自己去解决问题.
那计算相关性嘛, 方法就很多了, 总结如下:
在Neural Machine Translation by Jointly Learning to Align and Translate中的加法, 公式(1.4):
在Attention Is All You Need中的乘法(Scaled Dot-Product Attention), 公式(1.5):
更加直观的描述公式(1.5), 也就是:
在Effective Approaches to Attention-based Neural Machine Translation中的各种, 公式(1.6):
公式(1.6)中的最后一个, 称呼为感知机(perceptron)可能更好一些.
可否采用类似余弦相似性的方式来计算呢? 我觉得理论上应该是可以的, 就连感知机都能用, 别的还有啥不能用呢? 需要什么样的相似性, 理论上都完全可以交给模型自己学习.
另外还有一种Attention值得注意: Self-Attention.
> In a self-attention layer all of the keys, values and queries come from the same place.
那么到这里之后, Attention变成了什么样子? 公式(1.7)
这不就是输入, 输出特征吗? 那跟卷积核有啥差别? 直接用来"随意"堆叠, 不就搞定了? 避免了RNN的串联计算量, 还能提取到更好的特征? 事实上也差不多大概接近这个意思了, 下面来看一个Multi-Head Attention的东西. 原文中是这样计算的, 公式(1.8):
其中的Attention使用Scaled Dot-Product Attention时, 直观的描述如下:
有没有感觉上述的muti-head attention就类似CNN里面的一层卷积, 包含了多个卷积核?
那么self-attention加上muti-head attention会是什么样子? 将会在后面的Transormer中有直观的介绍.
现在回过头来观察公式(1.5)中为什么需要除以呢?
- 对模型的精度有提升?
- 对模型的训练有提升?
- Next we apply the “scaled” factor to have more stable gradients
- 也就是说对模型的训练有帮助, 为什么呢?
import numpy as np
def softmax(data):
data_exp = np.exp(data)
total = sum(data_exp)
return data_exp/total
# 假设矩阵维度为8
softmax([114, 96]) # array([1.00000000e+00, 2.78946809e-10])
softmax([114/8, 96/8]) # array([0.90465054, 0.09534946])
- 从上述实验结果可以看出, 当数组中数值差异稍微大一点时, 要么趋近于1, 要么趋近于0
- 这将增加模型的训练难度
- 假设输入Muti-Head的Attention中的QKV相同, 也即是均为X, 即
- 且, 误差传递到Attention时为
- 则有(不考虑V, 重点分析QK)
- 其中(设)
- 当时,
- 因此容易产生梯度消失
- 因此为了更加稳定的训练, 除了这个系数, 那么可否换成别的系数呢? 我认为是可以的!
- 具体论文为什么得到这个系数, 除了公式的美观外[偷笑]
- 假设输入的的各个分量均相互独立, 且均值为0, 方差为1
- 设, 则
的均值方差分别为:
Transformer
先直接上论文原图:
上图中左边部分为Encoder, 右边部分为Decoder. Encoder中的muti-head attention, 注意到了吧, 输入的Q, K, V都是同一个, 也就是self-attention.
再来分析Transformer的组成:
- 加入了ResNet机制, 每个Multi-Head Attention & Feed Forward后面都接了残差层
- 如果把Multi-Head Attention & Feed Forward看做一个整体, 那么也就是很多CV论文里面提到的一个Block
- Feed Forward由两个线性全链接层组成, 其中第一个线性全链接激活函数为Relu, 第二个没有激活函数, 直接接残差层. 原文公式如下, 公式(2.1):
- Encoder中全都是self-attention
- Decoder中也包含self-attention, 与Encoder不同的地方是增加了Mask操作.
- Decoder中除了self-attention外, 包含额外的encoder-decoder attention, 其输入的KV来自Encoder的输出, Q则来自Decoder自身
讲到这里, 其实基本上已经清楚整个Transformer的工作逻辑了.
但是有没有注意到一个问题: 整体框架图中还有一个Positonal Encoding, 如果没有会怎么样?
- Transformer与RNN系相比, 是并行计算的, 没有RNN提取序列特征的能力
- 换句话说, 如果没有序列特征, 那么在翻译任务中很可能会出现: 不管输入我喜欢深度学习, 还是输入深度学习喜欢我, 都可能翻译为I like deep learning
- 显然是不合理的
那么Positonal Encoding是如何解决上述问题的呢?
作者自己设计位置编码特征, 并与输入词向量相加, 得到新的特征向量. 并没有采用传统的类似one-hot编码, 与词向量拼接; 或自动化训练位置编码. 公式(2.2)
表示位置,
表示维度.
可以理解为词向量的维度.
根据公式(2.2)则可以将每个位置上的词/字符都编码成一个维度与相同的向量. 而且可以看到, 这个编码向量的同一维度上, 不同的位置其实就是一个三角函数曲线.
选择三角函数, 原文也提到了是因为位置偏移后向量便于线性表示, 也就是公式(2.3):
原文也提到, 对比了自动训练位置向量和三角函数编码位置向量, 结果相近, 则跟愿意选择三角函数编码. 因为可以少训练很多参数.
假设句子长度为100, 词向量为512, 则得到的位置向量为: (100, 512), 且
为同一周期, 同一相位的三角函数曲线上的点.
按照公式(2.2)的理解: 应该是表达奇数维度使用, 偶数维度使用
, 但源码中似乎直接把
与
拼接, 并没有按照奇偶维度进行操作. 应该是为了简化吧, 只要向量中包含了位置信息即可. 最终进入模型的向量其实是PositonalEncoding + WordEmbedding.
到这里, Transformer中还剩下最后一个问题, Decoder中的Mask是如何使用的? 其目的是什么?
训练的过程中, 我们知道预测结果, 所以可以随便怎么编码传入到Decoder中.
但真正使用做预测时, 就不能这么玩了. 为了能够让训练跟预测一样, Mask的作用就有了, 训练时会把当前时刻之后的均屏蔽掉, 只保留当前时刻之间的.
有没有觉得上面的描述哪里怪怪的? 不是并行计算的吗? 怎么还分时间先后啊? 那相比LSTM之类的有什么差别?
训练时, 是可以完全并行计算的, 则训练速度相比LSTM系列快很多.
预测时, 编码器部分是完全可以并行计算的, 解码器部分确实只能挨个进行, 当时相比LSTM已经好了很多.
Transformer在CV中的应用
- A Survey on Vision Transformer
- Transformers in Vision: A Survey
- 源码: https://github.com/x1489/vision_transformer
- 思想还是很简单的
- Transformer的输入是很多个1维向量(位置向量+词向量)
- 因此将图像切成很多个小块
- 再把每个小块转成1维向量
- 要么直接拉直成1维向量
- 要么通过卷积转成1维向量
- 再加上每个小块的位置向量
- 直接送入到了Transformer中
- 文中只用到了Encoder部分
- 最后再加一个MLP或Liner进行分类
- 更多的细节参考原文
- 虽然是成功将Transformer应用在了CV, 但似乎并没有很NB的样子
- 其实可以想想到, CV任务中, 输入的图像可能很多部分其实没有用, 只需要关注其中部分即可, 因此切成小块(小块越小效果越好), 或者别的注意力机制应该就能够直接达到不错的效果
- 论文ConvMixer提到这个事情, 可能ViT中的很大功劳来自于Patch
- 源码: https://github.com/locuslab/convmixer
[1]: https://zhuanlan.zhihu.com/p/46990010
[2]: https://jalammar.github.io/illustrated-transformer/
[3]: https://www.zhihu.com/question/437495132