赞
踩
Google研究菌曰: 在transformer模型之前,我们做机器翻译等事情(论文原话: 我们做转录模型(transduction model)) 都是用循环神经网络(RNN)或者卷积神经网络(CNN)作为基本单元,搭建一个包含encoder和decoder的模型. 虽然效果不错,但是显然还有很多进步空间. 既然拿那么多钱,上班又不是996,不如整点新的东西? 于是有了transformer模型.
回顾下整体流程, 为啥会想到要去创造transformer这个东西.
做机器翻译?
–>那咱们搭一个具有encoder-decoder结构的模型. 其中seq2seq是最常用的encoder-decoder模型–>模型里的小单元用基本结构的RNN或者基本结构的CNN.
训练完发现对长句记忆效果不理想,模型记不住之前的信息?发生梯度消失?
–>采用RNN的变体结构LSTM
翻译效果不太好?不同输入单词对后面的影响以及重要程度没有体现? (这种情况被称为分心模型)
–>加入注意力机制(attention),让每个单词都关注它最应该关心的信息,即从"分心模型"变成了"带注意力模型"(打比方: 听老师上课时,要有目的的开小差,而不是肆无忌惮的开小差或者从头认真听到尾)
比起seq2seq有什么改进?
–> 原始的seq2seq模型,decoder部分用的信息全来自encoder部分最后一个时间片产生的向量, 显然向量长度有限->导致记录的信息也有限. 加入attention后, encoder部分每个单词都会产生额外信息,decoder部分模型会加入这个额外信息.
那现在效果还可以,但是attention机制依旧无法并行运算, 所以训练速度仍然很慢, 咋滴办? (且attention忽略了输入句中文字间和目标句中文字间的关系)
–>Transformer模型!! Transformer模型里的self-attention机制可以实现并行计算,并且代替seq2seq结构.
论文原文: Attention is all you need
英文解读–> https://jalammar.github.io/illustrated-transformer/
解读的中文翻译–> https://blog.csdn.net/yujianmin1990/article/details/85221271
这是原论文里Transformer的结构图(该图我以后会重画, 里面标注有些不是很正确, 容易引起误解)
就是下面这个样子. 整个模型包含encoder部分和decoder部分,依旧是encoder输入,decoder输出.
稍微画仔细点,长这样
需要注意的是:
6个encoder结构互相相同,但是不共享参数.
6个decoder结构互相相同,但是也不共享参数.
看完了,那看看每个encoder编码器里的具体结构. 长这样↓
encoder里的第一个结构叫做 self-attention 层. 所有向量进入encoder后,都会进入self-attention层. self-attention层帮助encoder编码器在编码(处理)某个特定单词时,同时关注同一个输入句子里其他单词的信息.
然后self-attention层的输出流向一个前向网络层(Feed Forward Neural Network),每个输入位置对应的前向网络是独立互不干扰的.
decoder和encoder长得差不多,结构如下
OK,到这里,整个Transformer最粗略的结构讲完了.
下一节深入每个结构的细节
我们先来看一下, 送到Encoder之前, 模型对输入的X是怎么处理的.
一些先验知识:
在NLP里,拿到单词,比较常见的情况下,我们都会把它转成向量. 这个操作称为embedding. 这个向量的长度我们称为embedding size, 它是一个超参数.
我们假设每个单词已经转换成1*4的一个向量(或者叫Tensor), 比如下图 (当然实际场景里尺寸没有那么小,通常尺寸是1*512或者1*1024)
那么对于一个句子,就是由一系列向量组成的一个list. [x1,x2,x3…], list的长度就是句子长度(对于上图这个例子, 那么这个list的size就是3*4)
当然由于我们都是进行矩阵运算,需要每个list长度都相同. 此时我们会设定一个统一长度(即max_len), 这个长度是一个超参数, 通常有两种方法:
1.使用训练集(或者每个batch里)的最长句子的长度. 长度不足的句子会在后面补[PAD]. 这个就是我们通常说的padding操作.
2.设定为文本最长长度的80%~90%. 同样,长度不足的补上[PAD]. 超出长度的句子,超出部分裁减掉. 这个情况通常用在文本摘要之类句子长度非常长的情况下,或者模型对句子长度输入有限制.
先验知识完毕.
开始正式讲Positional Encoding.
由于本模型没有使用循环或者卷积神经网络,我们需要额外的信息来表达词的顺序.
Transformer模型对每个输入词向量(就是下图中深绿色格子的小x矩阵Embedding) 额外加入了一个向量,这些向量遵循模型学习的指定模式. 这样可以帮助词定位自己的位置,或者在句子中不同词之间的距离. 直觉上看,在词嵌入中加入这些向量,可以让他们之后各种处理过程中,提供有意义的词嵌入间的距离.
说人话就是, 在词向量送入encoder之前,再加上一个位置编码向量(positional encoding),使得词向量具有一定的位置信息.
这个位置编码大概长这样↓*(图里数字存在疑问, 按照公式算出来并不对,也可能我算错了)*
那么这个东西怎么产生?
在论文里, 用的是这样的公式:
P
E
(
p
o
s
,
2
i
)
=
s
i
n
(
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
)
PE_{(pos,2i)} = sin(\frac{pos}{10000^{2i/d_{model}}} )
PE(pos,2i)=sin(100002i/dmodelpos)
P
E
(
p
o
s
,
2
i
+
1
)
=
c
o
s
(
p
o
s
1000
0
2
i
/
d
m
o
d
e
l
)
PE_{(pos,2i+1)} = cos(\frac{pos}{10000^{2i/d_{model}}} )
PE(pos,2i+1)=cos(100002i/dmodelpos)
公式里, pos就是词在输入句子(或者说输入的sequence)里的位置, i是词向量位置,即 2i 表示偶数位置,2i+1 表示奇数位置. dmodel的值就是单词embedding的大小(在上图中,就是4)
这样PE是一个二维矩阵, 列数=词向量(embedding)大小, 行数=输入句子中词的个数(或者说输入sequence的长度). 比如我句子/sequence长度是748,单词embedding大小是128, 那我的PE就是一个748*128大小的二维矩阵. PE(0,3)就是句子里第一个单词的第4个向量位置.
这样, 上述公式表示在每个词语的词向量的偶数位置添加sin变量,奇数位置添加cos变量. 注意i是从0开始的.
再举个
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。