公众号关注 “ML_NLP
设为 “星标”,重磅干货,第一时间送达!
来自 | 知乎
地址 | https://zhuanlan.zhihu.com/p/267683158
作者 | 矢吹
编辑 | 机器学习算法与自然语言处理公众号
本文已获作者授权,未经许可禁止二次转载
Transformer 是 2017 年 Attention is All You Need 这篇文章为机器翻译任务所设计的一个模型结构,其中 Encoder 部分被 BERT、Vision Transformer 等 NLP/CV 领域的 SOTA 所沿用,不仅取代了 RNN 在 NLP 领域的地位,甚至在 CV 领域可以与 CNN 平起平坐谈笑风生,在外部数据 JFT-300M 的加持下可以将 ImageNet 刷到 88.36%。因此作为深度学习2020年的学习者,Transformer Encoder 是必须了解的一个模型。

1 Transformer Encoder 模型

一个基础的 Transformer Encoder block 由以下 2 个部分构成,同时每个部分加入 Layer Normalization & Residual Module:

  1. Attention & Multi-head Attention 注意力模块
  2. FeedForward 前馈网络模块
以上两个模块的输入输出维度(channel)相同都为 
 ,但在每个模块内部的 channel 通常会进行收缩或者扩张,取决于你的算力。
  • 同时由于不采用 RNN 机制来捕捉输入序列之间的相对关系,Transformer Encoder 为输入序列加入了额外的 Positional Encoding 以进行时序关系建模,这部分是 Transformer 捕捉序列关系的核心,所以接下来我们将首先介绍这个模块。

2 Positional Encoding

Postional encoding 作为输入序列的位置信息编码,其维度和 input embedding 相同也为 
 ,每个维度代表不同波长的三角函数。
  • 为什么采用三角函数来对输入 position 进行映射?
我的理解是首先三角函数是周期函数,可以将无限长度的 postion 值映射到固定区间 
 ;其次可以通过设置三角函数不同的波长来产生多个步长的位置信息。各个维度 
 代表的三角函数波长从 
 逐渐递增到 
 。
数学形式如下:

3 Attention & Multi-head Attention

3.1 Attention

纵览 CV/NLP,首先 attetion 机制就是对输入的各个维度进行自适应加权
Transformer 中所设计的 attetion 也是如此,我们所要了解的就是其自适应加权具体如何实现。
  • 首先如何根据输入 
     得到 
     三部分?
 三部分由输入 
 经过线性变换产生, 
 ,可以通过一个全连接层完成线性变换再维度切分进行实现。输入 
 的维度固定为 
 ,因为要对 
 进行点积运算所以二者有相同的维度记为 
 ,最后 
 的维度记为 
 ,不过一般会令 
 。
当然你也可以采用最简单粗暴的做法直接恒等映射将 
 作为 
 ,此时 
 。
  • Attention 计算方法
对 
 计算点积值后经过 scale 以及 softmax 归一化作为 
 的自适应权重。这里使用 
 作为 scale 因子的原因是防止 
 维度过高造成其点积值过大的情况出现,这时 softmax 函数映射值非0即1,梯度值过小不利于优化。(可以对比一下 
 与 
 两组向量由于尺度不同所造成 softmax 输出值的差异。)
数学形式如下:
可以通过下面这个 
 的简单的例子来了解其具体计算过程。
importmath
importnumpyasnp
importtorch
importtorch.nn.functionalasF

defattention
(q, k, v):

d_k
=
q
.
size(
-1
)

dot_scaled
=
torch
.
matmul(q, k
.
transpose(
-2
,
-1
))
/
math
.
sqrt(d_k)

proba
=
F
.
softmax(dot_scaled, dim
=-1
)

output
=
torch
.
matmul(proba, v)

return
output


x
=
torch
.
FloatTensor(np
.
arange(
0
,
1.2
,
0.1
)
.
reshape(
2
,
6
))

q, k, v
=
x, x, x

single
=
attention(q, k, v)

'''

proba:

tensor([[0.4092, 0.5908],

[0.2228, 0.7772]])

single:

tensor([[0.3545, 0.4545, 0.5545, 0.6545, 0.7545, 0.8545],

[0.4663, 0.5663, 0.6663, 0.7663, 0.8663, 0.9663]])

'''

3.2 Multi-head Attention

Multi-head Attention 是对 
 进行分组后计算 attention 再将结果拼接,假设 head 数量即分组数为 
 ,则 multi-head attention 对比 single-head 其 
 是原来的 
 。Multi-head 和 single-head 的参数量是相同的,那么为什么需要 multi-head 即对输入进行分组处理?作者给的解释是可以让模型关注到来自不同表征子空间的关键信息。
将上面的例子扩展为 
 的 multi-head attention 可以参考下面的这段代码。
fromeinopsimport
rearrange

q_
=
rearrange(q,
'n (h d) -> h n d'
, h
=2
)

k_
=
rearrange(k,
'n (h d) -> h n d'
, h
=2
)

v_
=
rearrange(v,
'n (h d) -> h n d'
, h
=2
)

multi
=
attention(q_, k_, v_)

multi
=
rearrange(multi,
'h n d -> n (h d)'
, h
=2
)

'''

proba:

tensor([[[0.4740, 0.5260],

[0.3258, 0.6742]],

[[0.3975, 0.6025],

[0.2613, 0.7387]]])

multi:

tensor([[0.3156, 0.4156, 0.5156, 0.6615, 0.7615, 0.8615],

[0.4045, 0.5045, 0.6045, 0.7432, 0.8432, 0.9432]])

'''
  • 留个脑洞问题,multi-head attention 和 CV 中的分组卷积都是对输入进行分组处理,为什么分组卷积会造成参数以及计算量的减少,而 multi-head attention 不会?

4 FeedForward

前馈网络模块 FeedForward 就是一个普通的多层感知机 MLP,数学形式如下:
关于激活函数 
 ,Transformer 原始论文中所使用的是 ReLU,后续改进(BERT、ViT)所采用的都是高斯误差线性单元 GELU。
其中 
 为高斯分布的累积分布函数, 
 为 sigmoid 函数。题外话,EfficientNet 中所使用的 Swish 函数和 GELU 唯一的区别是去掉了常系数 1.702。

5 Layer Normalization & Residual Module

残差模块是常规操作不再赘述。
唯一需要注意的是归一化方法使用的是 layer normalization 而非 batch normalization。BN & LN 数学形式相同,都有两个可学习参数:再缩放参数 
 ,再平移参数 
 ,两者所不同的是均值方差 
 的计算方式不同。
BN 中的均值方差在每个 channel 上都有独立的一组,因为是将一个 batch 全部样本在此 channel 上的值作为总体求得。
LN 中的均值方差所有 channel 使用的是同一组,因为是将一个样本在全部 channel 上的值作为总体求得。
以上就是对 Transformer Encoder 的一个简单总结,更多细节请参考原论文,欢迎交流指正。

Reference

[1] Transformer arxiv.org/abs/1706.0376
[2] nlp.seas.harvard.edu/20
[3] looperxx.github.io/Atte
[4] BERT arxiv.org/abs/1810.0480
[5] Vision Transformer openreview.net/pdf?
下载1:四件套
在机器学习算法与自然语言处理公众号后台回复“四件套”
即可获取学习TensorFlow,Pytorch,机器学习,深度学习四件套!
下载2:仓库地址共享
在机器学习算法与自然语言处理公众号后台回复“代码”
即可获取195篇NAACL+295篇ACL2019有代码开源的论文。开源地址如下:https://github.com/yizhen20133868/NLP-Conferences-Code
重磅!机器学习算法与自然语言处理交流群已正式成立
群内有大量资源,欢迎大家进群学习!
额外赠送福利资源!邱锡鹏深度学习与神经网络,pytorch官方中文教程,利用Python进行数据分析,机器学习学习笔记,pandas官方文档中文版,effective java(中文版)等20项福利资源
获取方式:进入群后点开群公告即可领取下载链接
注意:请大家添加时修改备注为 [学校/公司 + 姓名 + 方向]
例如 —— 哈工大+张三+对话系统。
号主,微商请自觉绕道。谢谢!
继续阅读
阅读原文