在2017年,《Attention is all you need》 一篇文章拉开了Transformer的世界
之后两三年,在NLP等很多任务上大放异彩
在2020 年拓展到CV领域,并且在CV的很多下游任务上表现优异
看到的每一篇工作,基本都离不开卷积网络
正如作者所说 Attention is all my need
transformer可以并行训练,也是用来实现attention注意力机制
之前RNN的困境
(1)特征的有效性不够,某一时刻拿到了前一时刻的所有特征,特征没有聚焦点,难以处理长时期依赖
(2)训练效率不够,必须得等前一时刻训练出来之后才能进行这一时刻的训练,而我们的transformer通过转换为矩阵运算实现并行
注意力模型其实有很多
transformer是做的比较好的一类
Encoder编码器和Decoder解码器构架
Encoder部分把原语言特征抽取出来 ,送到Decoder
如下图所示
左边蓝色部分是编码器,右边红色部分是解码器
下边紫色部分是嵌入层部分
观察我们会发现,编码器和解码器旁边都有一个N,表明是N层的堆叠
原论文中
左边编码器堆叠六层 N=6
右边解码器堆叠六层 N=6
我们不禁要问
堆叠多层Encoder和Decoder为什么?
特征提取能力可以更强,就好吧卷积网络增加卷积层一样的道理
transformer
Encoder 抽取特征 多层累加形式(所以输入输出维度不变)例子中都是[L.512]维度
比如有十个单词,那么经过Encoder以后就会输出十个特征,输入序列长度等于输出序列长度
Decoder 根据特征翻译出来找到对应的层
我们的讲解从输入开始
我们的核心任务是把一串话
I like playing badminton, swimming. I love everything about life.
翻译为
J’aime jouer au badminton, nager. J’aime tout dans la vie.
嵌入层我们先将字符进行编码,就是将字符变为向量形式(方便后续网络计算)
假设我们输入一句话是L个单词,词库大小是1000个单词
用独热码编码的话
我们的输入就是一个[L×1000]维度的向量
input Embeding 嵌入处理
通过一个变换将单词的one-hot独热码表示映射到连续空间上(降维)可以使用nn.Embedding实现
把每一个单词的维度降维成512维 所以输入L个单词 512维 则输入为[L×512]维度的向量
为什么用sin,cos位置编码
主要是可以记住相对位置,也可以记住绝对位置
我们想要把上下文信息编码进去,就是通过自注意力实现的
比如吃苹果,苹果手机
多头自注意力层的主要内容无非就两块内容
第一个核心是 自注意力
注意力本质就是权重,也就是我给我需要的部分足够多的关注,所以生成权重的方法是关键
自注意力采用如下方式产生权重
(1)经过三个线性变换
每个单词经过3个线性变换生成3个对应的向量q,k,v
具体实践的时候,是通过三个矩阵Q1,K1,V1 这三个矩阵是可学习的,x1×Q1得到q1 ,x1×K1得到k2 ……其他同理,进而决定了我们的每一个x对应的q,k,v是多少
(2)得到权重
用每个单词自己的q和其他单词的k做点乘,得到ai ,然后除以根号下的维度,然后再softmax 操作转换为权重大小
(3)依据权重输出最终值
则最后的翻译参考的x等于权值v乘对应的v再累加
输出 翻译得到单词的概率
以上所有操作都可以矩阵并行运算
注意这里的每一个xi都有一个输出,而且都利用了上下文的信息
第二个核心 多头
刚刚我们讲到用Q,K,V矩阵生成每一个句子的q,k,v
实际中我们往往用多组Q,K,V矩阵
原论文中是八组
那这样的话我们不就会得到八组结果了吗?
很简单,我们将八组结果送入contact连接层,再经过一个线性变换层得到最后的结果
这一层实际有两个操作
一个是Add,就是一种经典残差结构
一个是Norm,是LayerNorm,归一化操作
和之前的BatchNorm有一定的差异
在实际操作中往往送入的不是一个样本而是一批次样本,比如十个句子
那么两者区别的区别就在于
batch Norm是十个句子之间的输出做归一化,一批次的所有样本做归一化
而layerNorm是单个句子的某一层的输出做归一化
加入前馈神经网络
加强非线性操作,提高特征提取能力
解码器的核心部分很多都和编码器相同
如 多头注意力,残差归一化层,这里不做讲解
不同的是有一个Masked多头注意力层
为什么要加一个Masked呢
原因很简单
因为我们要实现并行训练,一次给模型好多句子对
我们不希望解码器的推测的时候能看到目标句子中还未完成翻译的部分,这样的话可能就不用费劲思考了,直接就可以输出答案了,
所以我们加入掩码,遮住每个句子还没有翻译完成的部分!!!
所以我们给解码器输入的是
目标句子已经翻译完成的部分特征,并且中途会插入原句子的特征(来自编码器)
一句话总结 利用原语言提取的特征,加上已经翻译过的特征进行预测未翻译的语言的特征
实际操作中操作中源语言的K,V传入Decoder
后来在CV引入了Transformer
有了VIT,SwinTransformer等一系列经典工作