Attention is All You Need | 每周一起读

简介:

Attention Is All You Need


通常来说,主流序列传导模型大多基于 RNN 或 CNN。Google 此次推出的翻译框架—Transformer 则完全舍弃了 RNN/CNN 结构,从自然语言本身的特性出发,实现了完全基于注意力机制的 Transformer 机器翻译网络架构。


论文链接:https://arxiv.org/pdf/1706.03762.pdf



开源实现




#Chainer#

https://github.com/soskek/attention_is_all_you_need


#PyTorch#

https://github.com/jadore801120/attention-is-all-you-need-pytorch


#TensorFlow#

https://github.com/Kyubyong/transformer


阅读笔记精选




Robin_CityU


该 paper 可以算作是 Google 针对 Facebook 之前的 CNN seq2seq: 1705.03122 的回应。工程性较强,主要目的是在减少计算量和提高并行效率的同时不损害最终的实验结果。 


模型的框架如下: 

  • Encoder 部分 -- 6 个 block,每个 block 中有两层,他们分别是 Multi-head self attention 和 Position-wise feed forward。

    1. Multi-head self attention - 多组self attention的连接。首先 encoder 的初始输入为sentence embedding + position embedding,其中position embedding的三角函数表示挺有意思。

    Attention(Q,K,V)=softmax(QK^T/sqrt(d_k))V,其中 Q 与 K 均为输入,(V 为 learned value?此处存疑)。输入 size 为[sequence_length, d_model],输出 size 不变。然后是 residual connection,即 LayerNorm(x+Sublayer(x)),输出 size 不变。


    2. Position-wise feed forward network,其实就是一个 MLP 网络,1 的输出中,每个 d_model 维向量 x 在此先由 xW1+b1 变为 d_ff 维的 x',再经过 max(0, x')W2+b2 回归 d_model 维。之后再是一个 residual connection。输出 size 仍是 [sequence_length, d_model]。


  • Decoder 部分 -- 6 个 block,每个 block 中有 3 层,他们分别是 Multi-head self attention (with mask),Multi-head attention (with encoder),Position-wise feed forward。


    1. Multi-head self attention (with mask) 与 encoder 部分相同,只是采用 0-1mask 消除右侧单词对当前单词 attention 的影响。


    2. Multi-head attention(with encoder) 引入 encoder 部分的输出在此处作为 multi-head 的其中几个 head。


    3. Position-wise feed forward network 与encoder部分相同。


  • some tricks during training process:(1) residual dropout; (2) attention dropout; (3) label smoothing


几点思考:

该模型没有使用 RNN 与 CNN,但做法其实像 CNN 的简化版,包括 normalization,dropout 的使用,以及 future work 提出的 local,restricted attention。


文章的第四部分其实并没有清楚地解释为什么使用所谓 self-attention,但是可否由此引出大家对 RNN 系列模型更深入的思考?毕竟 long dependency 与 hard to parallel 等问题一直存在。


在 seq2seq 任务中,一般 RNN 模型,encoder 与 decoder 自身受语言模型的约束较大,因此往往 decode 时常常出现重复、缺失等语言模型常出现的问题,如果真的切断由 RNN 建立的单词与单词之间的联系(其实 CNN 已经这么做了),也值得一试。而 position embedding 的引入,是否可以补充顺序信息?


WarBean


尝试用自己的理解对比一下卷积、recurrent 和 self attention: 


卷积:只能看到领域,适合图像,因为在图像上抽象更高层信息仅仅需要下一层特征的局部区域。


recurrent:理论上能看到所有历史,适合文本,但是存在梯度消失问题。


self attention:相比 recurrent 不存在梯度消失问题,这点显然。对比 CNN 更加适合文本,因为能够看到更远距离的信息,这点展开说明——因为文本语义的抽象不同于图像语义的抽象,后者看下一层的局部就行,前者经常需要看很远的地方。比如现在“苹果”这个词我要对它做一个抽象,按“苹果公司”抽象还是按“水果”抽象呢?这个选择可能依赖于几十个 step 之外的词。诚然,CNN 叠高了之后可以看到很远的地方,但是 CNN 本来需要等到很高层的时候才能完成的抽象,self attention 在很底层的时候就可以做到,这无疑是非常巨大的优势。



Q&A 精选



Hinse


We suspect this to be caused by the dot products growing too large in magnitude to result in useful gradients after applying the softmax function.


解释了引入 scale 是为了避免:当 dk 比较大时点乘结果太大导致有效梯度太大(或被 clipped)。


WarBean: 但是为什么是除以根号 d_k 而不是 d_k 呢,有没有人能解释一下为什么这么选?


soloice: 不是很懂为什么内积变大会导致梯度变小。如果内积变大,应该是每一个 k 和 q 的内积都变大,做 softmax 的话反正最后要归一化,应该不受影响啊。 


有一种可能的解释是,点积只是绝对值变大,但是数值有正有负,比如 [0.1, -0.1] 变成 [10, -10],softmax 算出来结果就很糟糕。而且即使是这样的话,也可以期待一半的梯度有效回传吧 = = 另外这个 scale 其实就是 softmax 里的 temperature 吧,但是为什么用根号 d_k 就不清楚了。


dalegebit: 回复一下楼上的,其实注释里写得很清楚,假设两个 d_k 维向量每个分量都是一个相互独立的服从标准正态分布的随机变量,那么他们的点乘的方差就是 d_k,每一个分量除以 sqrt(d_k) 可以让点乘的方差变成 1。


gujiuxiang


Since our model contains no recurrence and no convolution, in order for the model to make use of the order of the sequence


存疑,输入应该包含 previous word,怎么就不无 recurrence。他们的 claim 和之前 facebook cnn 那篇类似,idea 卖得都很炫。不过,我认为都包含recurrence。


wxuan: 编码器端的 recurrence,都通过这个 Positional Encoding 消除了。


rqyang: 确实是编码器不存在 recurrence,解码器存在广义上的 recurrence。这里论文的出发点应该是对输入的序列不存在 recurrence,输出序列的时候是把上一时刻的词当作“query”来看了。

Hinse: 感觉 dec 也不存在 recurrence。 因为 recurrence 是指不同 step 之间要顺序执行从影响速度的 recurrence。而这个 decoder 每一层对不同位置的计算是并行的。当前位置的计算不依赖前面位置的计算结果。 当然这也是因为他使用的是 ground truth 做输入。 为了并行, 模型的灵活性受到了限制。


WarBean: 同意楼上说 decode(在训练阶段)也不存在 recurrence。之前的 rnn decoder 在训练的时候即便给 ground truth(即 Teacher Forcing 训练法),由于 hidden state 之间存在的连接,所以仍然必须一个个 position 滚过去。本文则不需要,因为已经砍掉相邻两步之间 hidden state 这条连接了。不过,在测试阶段 decode下一个词依赖于上一个输出,所以仍然是 recurrence 的。


jordan: 整个都不存在依赖上一词的信息的, 只是依赖上一层,但词与词之间是可以并行的。

wxuan


In this work, we use sine and cosine functions of different frequencies.


不是很理解这里的出发点,对最终效果有多大影响?

Hinse: 文章里面提到了这样做,是因为 sin(a+b) = sin(a)cos(b) + cos(b)sin(a),其中 b 是一个固定的 offset 也就是常数了,所以 pos+k 的编码就可以通过 pos 的编码来线性表示了。但我感觉还有一个原因就是不容易重复:不同的维度使用不同的频率 (i=0,1,2... dim_size)。不同位置就是同一个频率的不同相位。感觉就像信号处理里面不同的频率承载不同的信息叠加(位置编码后有两个 fc 和 relu)后仍然容易分离,同一个频率用不同的相位区分信息。这个其实没太想清楚还是先忽略吧。


rqyang: 如果我运算符优先级没弄错的话,指数运算优先级更高,然后在最后一维,那不是意味着后面的维度和位置的改变几乎无关了?不太理解这么做的意义。参考文献 [9] 当中用了一个 positional embedding 和词向量相加,相对好理解得多。


WarBean: 你公式写错了,最后一维的 PE = sin(pos / 10000)。


rqyang: 才发现这里是应该是 PE 的第二个参数是维度,ii 的最大值是维度的一半,谢谢提醒。


WarBean: 这个 position embedding 设置得很有意思,我尝试解释一下:每两个维度构成一个二维的单位向量,总共有 d_model / 2 组。每一组单位向量会随着 pos 的增大而旋转,但是旋转周期不同,按照论文里面的设置,最小的旋转周期是 2pi,最大的旋转周期是 10000 x 2pi。至于为什么说相邻 k 步的 position embedding 可以用一个线性变换对应上,是因为上述每组单位向量的旋转操作可以用表示为乘以一个 2 x 2 的旋转矩阵。 


隐约感觉论文像这样把 position 表示成多组不同旋转周期的单位向量,能有助于泛化到训练时没有见过的长度,但是说不出为什么,坐等大神分析。 看上去 10000(省略 2pi)的最大周期好像拉得有点大,似乎没啥必要,不过我在自己做的一个任务上用了这个 position embedding,我那个任务的 decode step 通常是 50 多,但是最大周期设置到 10、100、1000 效果都还不错,所以这里设置成 10000 应该也没太大问题,最多就是后面一些维度的周期太长变化率太慢,没啥用,冗余而已,也没什么坏处。如果担心冗余维度挤占有用维度的份额,那就把 d_model 设大一点就好了,论文用 512 维我感觉已经足够了。


yang: 一个是 sin 一个是 cos,这种位置信息能将相对位置表示的挺不错的,将时域和频域空间做了映射,将文本位置信息做成信号。


wxuan



一般的机器学习论文中,向量默认都是列向量,这里的公式是根据行向量写的。


rqyang: 这里应该都是矩阵,假设 query 的长度为 ,序列长度为 ,那么



来源:paperweekly


原文链接

相关文章
|
存储 消息中间件 网络协议
零拷贝技术在Java中为何这么牛?
零拷贝技术在Java中为何这么牛?
642 0
|
人工智能 监控 安全
什么是网络即服务 (NaaS)?
我们经常听到云计算领域中有IaaS(基础设施即服务)、PaaS(平台即服务)、SaaS(软件即服务),但是你知道吗?在网络领域也有一种术语叫做NaaS(网络即服务),本文瑞哥就带大家揭开NaaS的神秘面纱,让我们直接开始!
4549 0
什么是网络即服务 (NaaS)?
|
机器学习/深度学习 前端开发 JavaScript
前端技术探索:从基础到未来趋势的全方位解析
前端技术探索:从基础到未来趋势的全方位解析
298 1
|
存储 缓存 人工智能
解码 LangChain | LangChain + GPTCache =兼具低成本与高性能的 LLM
GPTCache 是一个用于存储 LLM 响应的语义缓存层。它可以为 LLM 相关应用构建相似语义缓存,当相似的问题请求多次出现时,可以直接从缓存中获取,在减少请求响应时间的同时也降低了 LLM 的使用成本。
828 0
|
存储 算法
m考虑时偏影响的根升余弦滤波器matlab仿真
MATLAB 2022a仿真实现了根升余弦滤波器(RRC)的效果,该滤波器常用于通信系统以消除码间干扰。RRC滤波器设计考虑了时偏影响,其脉冲响应由理想矩形脉冲卷积得到,滚降系数控制衰减速度。在有同步误差时,滤波器需保持良好ISI抑制能力。MATLAB代码展示了计算时偏量并应用RRC滤波于连续样本的过程,以降低误码率并优化系统性能。
336 2
|
机器学习/深度学习 自动驾驶 计算机视觉
YOLOv8改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)
YOLOv8改进 | Neck篇 | Slim-Neck替换特征融合层实现超级涨点 (又轻量又超级涨点)
1561 2
阿里云容器服务 ACK 产品技术动态(202312)
阿里云容器服务 ACK 产品技术动态(202312)
|
虚拟化 Docker 容器
Minikube - Kubernetes本地实验环境
为了方便大家本地开发和体验Kubernetes,社区提供了可以在本机部署的Minikube。本文介绍利用阿里云的镜像地址在Windows/Mac/Linux上来部署和配置Minikube
242057 77
Minikube - Kubernetes本地实验环境
|
C++
Halcon 学习笔记九:MFC+halcon联合
Halcon 学习笔记九:MFC+halcon联合
710 0
|
编译器 C语言
C语言练习题解析(3)
C语言练习题解析(3)
223 0