最近在学习transformer的知识,看了原论文,以及网上各式各样的材料,综合理解,之后写了这篇博客,这篇博客已经讲的非常非常细致了,因为我用了将近三天的时间,写完的,每一部分都尽可能的描述清楚。本博客只是论文中的模型框架展开分析,并没有对源码进行分析(这也是我下一步要做的),最后也会给出代码的实现。
Transformer和LSTM最大区别在于,LSTM的训练是迭代的,是一个接一个字的来,当前这个字过完LSTM单元后在可以进入下一个字,而transformer的训练是并行的,就是所有的字可以全部同时训练的,这样就大大加快了计算效率,transformer使用了位置嵌入positional embedding 来理解语言的顺序,使用自注意力机制和全连接层来进行计算。
本篇论文可以点击这里下载。这篇论文是Google于2017年在NIPS上发表的一篇文献,现在用Attention处理序列问题的论文层出不穷,本文的创新点在于抛弃了之前传统的Encoder-Decoder模型必须结合CNN或者RNN的固有模式,只用attention即可,正所谓大道至简。本文的主要目的是减少计算量和提高并行效率的同时,不损害模型效果。(之我见:其实就是摒弃了RNN(无法并行)和CNN(内存占用大,计算量大,参数多)各自的缺点,结合了RNN(保留长距离信息)和CNN(可以并行)各自的优点)。 本文提出了两个新的Attention机制,分别叫做Scaled Dot-Product Attention 和Multi-Head Attention。
目前主流的处理序列问题(如机器翻译、文档摘要,对话系统,QA等)大部分都是基于Encoder-Decoder框架(如seq2seq)。即:Encoder:from word sequence to sentence representation;Decoder: from sentence representation to word sequence distribution.传统的Encoder-Decoder一般使用RNN,大部分的神经机器翻译模型都选择使用RNN,但是正如我们所知道的,RNN难以处理长序列的句子,无法实现并行化(由于RNN处理序列的模式),并且面临对齐的问题。
之后这类模型的发展大多熊三个方面着手:
但是依旧存在一些潜在问题的制约,神经网络需要能够将源语句中所有必要信息压缩成固定长度的向量。这可能是的神经网路难以应付长时间(即长距离)的句子,特别是那些比训练语料库中的句子更长的句子;每个时间步的输出需要依赖于前面时间步的输出,这使得模型没有办法并行,效率低;仍然面临对齐问题。
后来CNN被引入到seq2seq模型中,CNN不能直接用于处理变长的序列样本但是可以实现并行化。完全基于CNN的Seq2seq模型虽然可以并行实现,但是非常占内存,很多的参数,大数据量上对参数进行调整也是不容易的。
Encoder-Decoder模型的主要缺点就是,无论输入如何变化,Encoder给出的都是一个固定维数的向量,存在信息损失;在生成文本的时候,每个词语所用到的语义向量都是一样的,这显然是过于简单的。为了解决上面提到的问题,一种可行的方案是引入attention mechanism。
深度学习里的Attention Model其实模拟的是人脑注意力模型,举个例子来说,
当我们观赏一幅画的时候,虽然我们可以看到整幅画的全貌,但是在我们深入仔细地观察时,
其实眼睛聚焦只有很小的一块,这个时候人的大脑主要关注在这一小块图案上,
也就是说这个时候人脑对整幅画的关注并不是均衡的,是有一定的权重区分的。
这就是深度学习里的Attention Model的核心思想。
所谓注意力就是说,在生成每个词的时候,对不同的输入词给予不同的关注权重。
将注意力加入到Encoder-Decoder中,Encoder不再生成一个固定大小的向量,
而是一个向量序列,并自适应地去选择这些向量的一个子集。
例如,where are you---->你在哪?我们正在翻译“你”的时候,
会给‘you’更多的权重,那么就可以有效解决对齐的问题。
这篇论文首先将注意力机制运用在NLP上,提出了Soft Attention Model,并将其应用到了机器翻译上面。其实,所谓的Soft Attention,是Softmax Attention,意思是在求注意力分配概率分布的时候使用的是softmax函数,对于输入句子中的每一个单词都给出一个概率,是个概率分布。加入注意力机制的模型表现确实更好,但是也存在一定的问题,比如,attention mechanism通常和RNN结合使用,我们都知道RNN依赖于t-1的历史信息来计算t时刻的信息,因此不能并行实现,计算效率比较低,特别是训练样本非常大的时候。
基于CNN的Seq2Seq+attention的优点:基于CNN的Seq2Seq模型具有基于RNN的Seq2seq模型捕捉 long distance dependency的能力,此外,最大的优点是可以并行化实现,效率比基于RNN的seq2seq模型高。缺点是:计算量大,与观测序列X和输出序列Y的长度成正比,参数比较多。
针对以上这两个问题,本文提出了Transformer模型,该模型也是一种Encoder-decoder的框架,只不过该模型完全不依赖于CNN和RNN;完全依赖于self-attention机制(一种堆叠式的self-attention)以及point-wise (逐点计算)的全连接层。
Encoder是由N=6个独立的层堆叠而成的,每个层有两个子层:
每个子层又引入了 residual connection,具体的做法为:每个子层的输出为这个子层的输入和输出相加: x + S u b l a y e r ( x ) x+Sublayer(x) x+Sublayer(x),这就要求每个子层的输入与输出的维度是完全相等的,然后再使用layer normalization,作为最终的输出:
L a y e r N o r m ( x + S u b l a y e r ( x ) ) Layer Norm(x+Sublayer(x)) LayerNorm(x+Sublayer(x))
论文中限定了Embedding层的输出和两个子层的输入输出的维度都是 d m o d e l = 512 d_{model}=512 dmodel=512,即上图中的 e m b e d d i n g d i m e n s i o n embedding\ dimension embedding dimension.
Normalization的作用是将数据归一化为均值位0,方差为1的数据。在把数据送入激活函数之前进行normalization(归一化),因为我们不希望输入数据落在激活函数的饱和区。
经过Attention之后的输出维度和输入的嵌入表示维度,即 X e m b e d d i n g X_{embedding} Xembedding,相同,也就是 [ b a t c h s i z e , s e q u e n c e l e n g t h , e m b e d d i n g d i m e n s i o n ] [batch\ size,\ sequence\ length,\ embedding\ dimension] [batch size, sequence length, embedding dimension],然后把它们加起来,做残差连接,直接进行元素相加,因为它们的维度是一致的。即,
X + S u b L a y e r ( X ) = X e m b e d d i n g + A t t e n t i o n ( Q , K , V ) ( 此 处 的 A t t e n t i o n 为 后 面 将 要 提 到 的 M u l t i − H e a d A t t e n t i o n ) X+SubLayer(X)=\\ X_{embedding}+Attention(Q,\ K,\ V)\\(此处的Attention为后面将要提到的Multi-Head Attention) X+SubLayer(X)=Xembedding+Attention(Q, K, V)(此处的Attention为后面将要提到的Multi−HeadAttention)
在之后的运算里,每经过一个模块的运算,都要把运算之前的值和运算之后的值相加(在此,运算即为Attention),从而得到残差连接,训练的时候可以使梯度直接走捷径反传到最初始层(这就是为啥要residual connection,也可以理解为residual connection的作用)residual connection。
L a y e r N o r m a l i z a t i o n Layer Normalization LayerNormalization的作用就是把神经网络中隐藏层归一为标准正太分布,也就是独立同分布,以起到加快训练速度,加速收敛的作用,同时也可以避免梯度消失和梯度爆炸的问题,相比Batch Normalization, Layer Normalization更适用于序列化模型比如RNN等,而Batch Normalization则更适用于CNN处理图像。
μ i = 1 m ∑ i = 1 m x i j \mu_{i}=\frac{1}{m} \sum^{m}_ {i=1}x_{ij} μi=m1i=1∑mxij
上式中以矩阵的行 ( r o w ) (row) (row)为单位求均值;
σ j 2 = 1 m ∑ i = 1 m ( x i j − μ j ) 2 \sigma^{2}_ {j} = \frac{1}{m} \sum^{m}_ {i=1}(x_{ij}-\mu_{j})^{2} σj2=m1i=1∑m(xij−μj)2
上式中以矩阵的行 ( r o w ) (row) (row)为单位求方差;
L a y e r N o r m ( x ) = α ⊙ x i j − μ i σ i 2 + ϵ + β LayerNorm(x) = \alpha \odot \frac{x_{ij}-\mu_{i}}{\sqrt{\sigma^{2}_ {i}+\epsilon}} + \beta LayerNorm(x)=α⊙σi2+ϵxij−μi+β
然后用每一行的每一个元素减去这行的均值, 再除以这行的标准差, 从而得到归一化后的数值, ϵ \epsilon ϵ 是为了防止除 0 0 0;
之后引入两个可训练参数 α , β \alpha,\beta α,β 来弥补归一化的过程中损失掉的信息, 注意 ⊙ \odot ⊙ 表示元素相乘而不是点积, 我们一般初始化 α \alpha α 为全 1 1 1, 而 β \beta β 为全 0 0 0.
其实,只要把Encoder每个子层都理解清楚了,Decoder的各个层就会很好理解。
Decoder也是由N=6个独立的层堆叠而成的,除了与Encoder层中的两个完全相同的子层外,在两层之间又加入了一个multi-head attention,这里是对Encoder的输出作attention处理。
与Encoder相同,每个子层之间也引入了residual connection,并且相加之后使用layer normalization得到每个子层的最后输出。
此外为了防止序列中元素的位置主导输出结果,对Decoder层的multi-head-attention层增加了mask操作,并且结合对output embedding结果进行右移一位的操作,保证了每个位置i的输出,只会依赖于i位之前(不包括i位,因为右移一位和mask)(加入了mask机制, masking 的作用就是防止在训练的时候 使用未来的输出的单词。 比如训练时,第一个单词是不能参考第二个单词的生成结果的。 Masking就会把这个信息变成0, 用来保证预测位置 i 的信息只能基于比 i 小的输出)。
论文中将常用的Attention结构从新的一种角度进行了描述,Attention作为一种函数,接受的输入为:一个query,一组key-value pairs,三者都是向量;输出就是对组中所有values的加权之和,其中的权值是使 compatibility function(如内积),对组内的每一个keys和query计算得到的。
例如,对于常见的self-attention来说,这里就是指对序列中的某一个元素对应的向量,求得经过self-attention之后的对应的向量。query指的是这个元素对应的向量(例如NLP任务中句子序列中某一个单词对应的embedding向量),key-value Paris就是这个序列的所有元素,其中的每个元素对应的key和value是完全相同的向量,对于要比较的那个元素,与query也是完全相同的。然后使用当前向量和所有向量做内积得到权值,最后的数据就是这个权值和对应向量的加权和。
将Source中的构成元素想象成是由一系列的
数据对构成,此时给定Target中的某个元素Query,通过计算Query和各个Key的相似性或者相关性,得到每个Key对应Value的权重系数,然后对Value进行加权求和,即得到了最终的Attention数值。所以本质上Attention机制是对Source中元素的Value值进行加权求和,而Query和Key用来计算对应Value的权重系数。
Self Attention 指的不是Target和Source之间的Attention机制,而是Source内部元素之间或者Target内部元素之间发生的Attention机制,也可以理解为Target=Source这种特殊情况下的注意力计算机制。
在本文中使用了两种Attention方法,分别为Scaled Dot-Product Attention和Multi-Head Attention。
整个模型框架如下所示:
我们假设query和key这两个用来比较的向量,长度都为 d k d_{k} dk;value向量的长度为 d v d_{v} dv。对query和所有的key进行点积得到值,再对这个点积结果除以 d k \sqrt{d_{k}} dk,完成scale,最后应用一个softmax function获得每个value对应的权重(也就说这也是一种soft attention),加权求和求得最后的输出向量。
这是对于一个query的情况,实际中是直接对一个血猎对应的所有querys直接进行计算,将所有querys拼成一个大的Q矩阵,对应的keys和values也拼接成K和V矩阵,则Scaled Dot-Product Attention对应的计算公式为:
A t t e n t i o n ( Q , K , V ) = s o f t m a x ( Q K T d k ) V Attention(Q,K,V)=softmax(\frac{QK^{T}}{\sqrt{d_{k}}})V Attention(Q,K,V)=softmax(dkQKT)V
需要注意的是: d k d_{k} dk较大的时候,向量之间的点积结果可能就会非常大,这会造成softmax函数陷入到梯度很小的区域,不利于反向传播的进行,。为了适应这种情况,适应了缩放因子 d k \sqrt{d_{k}} dk,对点积结果进行尺度化,将点积结果尽量缩小到梯度敏感的区域内。
回顾一下sigmod函数的图像,当值大于4的时候,第一就开始变得比较小了。(softmax可以看作是sigmod多分类的一个扩展)
softmax函数的解释如下:
其他关于softmax的知识,可以参考这里或者这里或者直接百度一下。
为什么当 d k \sqrt{d_{k}} dk比较大的时候,会导致点积的结果比较大,原论文中是这样解释的:
之前的方法都是对 d m o d e l d_{model} dmodel维度的query,keys和value直接只用一个Attention函数。在Multi-Head Attention方法中,进行如此操作:
Transformer中三种multi-head Attention
至此,Attention部分已经完全讲完了,下面给出一个直观的解释,帮助理解。
至此, 我们已经基本了解到 t r a n s f o r m e r transformer transformer编码器的主要构成部分, 我们下面用公式把一个 t r a n s f o r m e r b l o c k transformer\ \ block transformer block的计算过程整理一下:
1). 字向量与位置编码:
X = E m b e d d i n g L o o k u p ( X ) + P o s i t i o n a l E n c o d i n g X i n R b a t c h s i z e ∗ s e q l e n ∗ e m b e d d i m . X = EmbeddingLookup(X) + Positional\ Encoding\\ X\ in\ \mathbb{R}^{ batch\ size* seq\ len* embed\ dim.} X=EmbeddingLookup(X)+Positional EncodingX in Rbatch size∗seq len∗embed dim.
2). 自注意力机制:
其实在Encoder中, Q = K = V = X Q=K=V=X Q=K=V=X那么对 Q , K , V Q,K,V Q,K,V进行线性映射后的 Q , K , V Q,K,V Q,K,V可以写成如下:
Q = L i n e a r ( X ) = X W Q K = L i n e a r ( X ) = X W K V = L i n e a r ( X ) = X W V Q = Linear(X) = XW^{Q}\\ K = Linear(X) = XW^{K}\\ V = Linear(X) = XW^{V} Q=Linear(X)=XWQK=Linear(X)=XWKV=Linear(X)=XWV
然后对线性映射后的 Q , K , V Q,K,V Q,K,V进行Attention:
X a t t e n t i o n = M u l t i . H e a d A t t e n t i o n ( Q , K , V ) X_{attention} = Multi.Head\ Attention(Q, K, V) Xattention=Multi.Head Attention(Q,K,V)
3). 残差连接与 L a y e r N o r m a l i z a t i o n Layer\ Normalization Layer Normalization
X a t t e n t i o n = X + X a t t e n t i o n X a t t e n t i o n = L a y e r N o r m ( X a t t e n t i o n ) X_{attention} = X + X_{attention}\\ X_{attention} = LayerNorm(X_{attention}) Xattention=X+XattentionXattention=LayerNorm(Xattention)
4). 下面进行 F e e d F o r w a r d Feed\ Forward Feed Forward, 其实就是两层线性映射并用激活函数激活, 比如说 R e L U ReLU ReLU:
X h i d d e n = A c t i v a t e ( L i n e a r ( L i n e a r ( X a t t e n t i o n ) ) ) 即 : F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 X_{hidden} = Activate(Linear(Linear(X_{attention}))) \\ 即:FFN(x)=max(0,xW_{1}+b_{1})W_{2}+b_{2} Xhidden=Activate(Linear(Linear(Xattention)))即:FFN(x)=max(0,xW1+b1)W2+b2
5). 重复 3)残差连接与 L a y e r N o r m a l i z a t i o n Layer Normalization LayerNormalization:
令:
X h i d d e n = X a t t e n t i o n + X h i d d e n X h i d d e n = L a y e r N o r m ( X h i d d e n ) X h i d d e n i n R b a t c h . s i z e ∗ s e q . l e n ∗ . e m b e d . d i m . X_{hidden} = X_{attention} + X_{hidden}\\ X_{hidden} = LayerNorm(X_{hidden})\\ X_{hidden}\ \ in\ \mathbb{R} ^ { batch.size* seq. len*. embed. dim.} Xhidden=Xattention+XhiddenXhidden=LayerNorm(Xhidden)Xhidden in Rbatch.size∗seq.len∗.embed.dim.
在完整的Encoder中,上述步骤的2)~5)要堆叠式的重复6次。
Encoder 和Decoder都包含了一个fully connected feed-forward network,特殊的是,这个网络分别对每个位置的attention层的输出向量单独地进行作用,整个过程包括了两次线性变换以及一次ReLU激活。
F F N ( x ) = m a x ( 0 , x W 1 + b 1 ) W 2 + b 2 FFN(x)=max(0,xW_{1}+b_{1})W_{2}+b_{2} FFN(x)=max(0,xW1+b1)W2+b2
对于不同位置的线性变换是完全一样的,即使使用相同的参数。这一层的输入输出都是 d m o d e l = 512 d_{model}=512 dmodel=512,中间隐层的维度为 d f f = 2048 d_{ff}=2048 dff=2048。
用了两层Dense层,第二层的activation用的是Relu。可以看成是两层的1*1的1d-convolution。hidden_size变化为: 512 − > 2048 − > 512 512->2048->512 512−>2048−>512。
Position-wise feed forward network,其实就是一个MLP 网络,子层的输出中每个 d m o d e l d_{model} dmodel 维向量 x 在此先由 x W 1 + b 1 xW_1+b_1 xW1+b1 变为 d f f d_{ff} dff维的 x ′ x' x′,再经过 m a x ( 0 , x ′ ) W 2 + b 2 max(0,x')W_2+b_2 max(0,x′)W2+b2 回归 d m o d e l d_{model} dmodel 维。之后再是一个residual connection。输出 size 仍是 [ s e q u e n c e l e n g t h , d m o d e l ] [sequence\ length, d_{model}] [sequence length,dmodel]
使用已经训练好的embeddings将input token和output token转换成 d m o d e l d_{model} dmodel维度的向量。在最后Decoder的输出时,将Decoder的输出通过一个线性变换层和一个softmax层,转换成预测下一个token的概率向量,这两个层中参数也是提前训练好的。
在transformer模型中,两个embedding layers以及最后的softmax之前的线性变换,这三者共享使用相同的矩阵权值。对于embedding层,里面的权值需要乘以 d m o d e l \sqrt{d_{model}} dmodel之后再使用。
因为模型完全没有使用RNN和CNN,而又想使用序列中的顺序信息,就必须加入一些关于token的相对位置和绝对位置的信息。因此我们加入了Positional Encoding,作为Encoder和Decoder的输入。需要注意的是Positional Encoding产生的每个向量维度为 d m o d e l d_{model} dmodel,与原本的embedding向量维度相同,从而两者可以被相加使用。
实际上,Position Encoding的大小为 [ m a x s e q u e n c e l e n g t h , e m b e d d i n g d i m e n s i o n ] [max\ sequence\ length, embedding\ dimension] [max sequence length,embedding dimension],嵌入的维度同词向量的维度,即等于 d m o d e l = 512 d_{model}=512 dmodel=512, m a x s e q u e n c e l e n g t h max\ sequence\ length max sequence length属于超参数,指的是限定的最大单个句长。
对位置进行embedding的方法有很多,有训练方法和指定方法。在本文中,采用频率不同的sin函数和cos函数。
P E ( p o s , 2 i ) = s i n ( p o s / 1000 0 2 i d m o d e l ) 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)}=sin(pos/10000^{\frac{2i}{d_{model}}})\\ PE_{(pos,2i+1)}=cos(pos/10000^{\frac{2i}{d_{model}}}) PE(pos,2i)=sin(pos/10000dmodel2i)PE(pos,2i+1)=cos(pos/10000dmodel2i)
上述表达式中,pos指的是句中字(或词)的位置,取值范围是 [ 0 , m a x s e q u e n c e l e n g t h ) [0, max\ sequence\ length) [0,max sequence length)(注意左闭右开),i指的是维度向量的第i维,取值范围是 [ 0 , e m b e d d i n g d i m e n s t i o n ) [0, embedding\ dimenstion) [0,embedding dimenstion),上面有 s i n sin sin和 c o s cos cos一组公式,对应着embedding dimension上的一组奇数和偶数的序号的维度。例如,当i=0的时候 2 i = 0 , 2 i + 1 = 1 2i=0,2i+1=1 2i=0,2i+1=1,那么久对应着 ( 0 , 1 ) (0,1) (0,1)这组维度,对于偶数维用 s i n sin sin函数,奇数维用 c o s cos cos函数,也就是说,第0维用 s i n sin sin函数,第1维用 c o s cos cos函数,从而产生不同的周期性变化。那么可知 i < = d m o d e l / 2 i<=d_{model}/2 i<=dmodel/2。如下图所示:
位置嵌入在 embedding dimension维度上随着维度序号的增大,周期会越来越大(从 2 π 2 \pi 2π到 2 π ∗ 10000 2\pi*10000 2π∗10000),从而产生一种包含位置信息的纹理。而每一个位置在embedding dimension维度上都会得到不同周期的 s i n sin sin和 c o s cos cos函数的取值组合,从而产生独一的纹理位置信息,模型从而学到位置之间的依赖关系(函数图像是连续的)和自然语言的时序特性(周期内不同时刻对应于函数图像上不同的位置)。
Position Embedding本身是一个绝对位置信息,由于sin函数和cos函数的特性: S i n ( α + β ) = s i n α c o s β + c o s α s i n β C o s ( α + β ) = c o s α c o s β − s i n α s i n β Sin(\alpha+\beta)=sin\alpha cos\beta +cos\alpha sin\beta\\ Cos(\alpha+\beta)=cos\alpha cos\beta -sin\alpha sin\beta Sin(α+β)=sinαcosβ+cosαsinβCos(α+β)=cosαcosβ−sinαsinβ
这表明 P E p o s + k PE_{pos+k} PEpos+k可以表示为 P E p o s PE_{pos} PEpos的线性函数。
自注意力机制在论文「A structured Self-Attentive Sentence Embedding」中被首次提出。之所以使用Self-Attention而没有使用循环或者卷积的结构,主要出于以下三点的考虑:
以上是关于Transformer整个框架的分析,为了后续代码的理解,我们再解释一下,训练模型的时候所采用的Optimizer和Regularization。
Transformer使用Adam optimizer with β 1 = 0.9 , β 2 = 0.98 , ϵ = 1 0 − 9 \beta_{1}=0.9,\ \beta_{2}=0.98,\ \epsilon=10^{-9} β1=0.9, β2=0.98, ϵ=10−9,学习率根据下面的计算公式进行变动,现有一个预热,学习率会呈线性增长,然后呈幂函数递减,类似于下图所示。。
l r a t e = d m o d e l − 0.5 ∗ m i n ( s t e p _ n u m − 0.5 , s t e p _ n u m ∗ w a r m u p s t e p s − 1.5 ) lrate=d_{model}^{-0.5}*min(step\_num^{-0.5},step\_num\ *warmup_steps^{-1.5}) lrate=dmodel−0.5∗min(step_num−0.5,step_num ∗warmupsteps−1.5)
论文中设置warmup_steps=4000,也就是说训练的前4000步线性增长,4000步后面成幂函数递减。这么做可以加速模型训练收敛,先以上升的较大的学习率让模型快速落入一个局部收敛较优的状态,然后以较小的学习率微调参数慢慢逼近更优的状态以避免震荡。
论文中主要使用了两种正则化手段来避免过拟合并加速训练过程。
在每一residual Multi-Head Attention之后, Add & Norm之前进行dropout,以及add(token embedding, positional encoding)之后进行dropout,FFN中没有dropout,base model的dropout rate统一设置为0.1,big model在wmt14 en-fr数据集上设置为0.1, 在en-de数据集上设置为0.3.
Label Smothing Regularization(LSR)是2015年发表在CoRR的paper:Rethinking the inception architecture for computer vision中的一个idea,这个idea简单又实用。假设数据样本x的针对label条件概率的真实分布为:
q ( k ∣ x ) = δ k , y = { 1 , k = y 0 , k ≠ y q(k|x)=\delta_{k,y}=\left\{ \begin{aligned} 1, k = y\\ 0, k \neq y \end{aligned} \right. q(k∣x)=δk,y={1,k=y0,k=y
这使得模型对自己给出的预测太过自信,容易导致过拟合并且自适应能力差(easy cause overfit and hard to adapt)。解决方案是:给label分布加入平滑分布 u ( k ) u(k) u(k),一般取平均分布 u ( k ) = 1 k u(k)=\frac{1}{k} u(k)=k1就可以,于是得到:
q ′ ( k ∣ x ) = ( 1 − ϵ ) δ k , y + ϵ u ( k ) q'(k|x)=(1-\epsilon)\delta_{k,y}+\epsilon u(k) q′(k∣x)=(1−ϵ)δk,y+ϵu(k)
映射到损失函数 cross entropy有:
H ( q ′ , p ) = − ∑ k = 1 K log p ( k ) q ′ ( k ) = ( 1 − ϵ ) H ( q , p ) + ϵ H ( u , p ) \begin{aligned} H(q',p)&=-\sum_{k=1}^{K}\log^{p(k)}q'(k)\\ &=(1-\epsilon)H(q,p)+\epsilon H(u,p) \end{aligned} H(q′,p)=−k=1∑Klogp(k)q′(k)=(1−ϵ)H(q,p)+ϵH(u,p)
由上式可以知道,LSR使得不仅要最小化原来的交叉熵 H ( q , p ) H(q,p) H(q,p),还要考虑预测分布p与 u ( k ) u(k) u(k)之间差异最小化,使得模型预测泛化能力更好。transformer的论文指定 ϵ l s = 0.1 \epsilon_{ls}=0.1 ϵls=0.1。
下表是使用LSR和未使用LSR在tensorflow datasets的ted_hrlr_translate/pt_to_en dataset上bleu score对比
bleu on validation dataset | bleu on test dataset | |
---|---|---|
beam_search | 41.5 | 42.0 |
beam_search + label_smooth_regualrization | 47.3 | 46.8 |
可以看到使用了LSR在验证集和测试集上都取得了比更好的bleu score.但是LSR对perplexity不利,因为模型的学习目标变得更不确切了。
Pytorch实现的代码
[阅读笔记]《Attention is All You Need》
本文相当一部分的内容来自于词。
-《Attention is All You Need》论文翻译
本文算是对原论文的一个翻译,帮助阅读论文。
-深度学习中的“注意力机制”
本文也算是对原论文一个翻译,用来辅助读原论文。
-Transformer 详解
本文有一部内容也参考此处。