关于除了attention其他的transformer部分,结合看的transformer论文及自己的其他查询资料总结如下:
一、 MASK
mask操作在sequence类操作很常见,因为定长输入的序列很多时候存在填充情况,不利用mask参数告诉模型无意义填充值,会导致无效学习,甚至由于梯度传播的梯度消失问题,还会影响模型效果。而对于transform模型,除了类似sequence模型存在的需要padding mask的情况,还在decode部分,需要对于decode进行未来数据的遮蔽,进行sequence mask,具体如下,以下参考博客:Transformer 模型详解_XP-Code的博客-CSDN博客_get_attn_key_pad_mask
1 Padding mask
什么是padding mask呢?由于我们的每个批次输入序列长度是不一样的,也就是说,我们要对输入序列进行对齐。具体来说,就是给在较短的序列后面填充0。因为这些填充的位置,其实是没什么意义的,所以我们的attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。具体的做法是,把这些位置的值加上一个非常大的负数(可以是负无穷),这样的话,经过softmax,这些位置的概率就会接近0!而我们的padding mask实际上是一个张量,每个值都是一个Boolen,值为False的地方就是我们要进行处理的地方。
2 Sequence mask
sequence mask是为了使得decoder不能看见未来的信息。也就是对于一个序列,在time_step为t的时刻,我们的解码输出应该只能依赖于t时刻之前的输出,而不能依赖t之后的输出。因此我们需要想一个办法,把t之后的信息给隐藏起来。那么具体怎么做呢?也很简单:产生一个上三角矩阵,上三角的值全为0,下三角的值全为1,对角线也是0。把这个矩阵作用在每一个序列上,就可以达到我们的目的啦。
值得注意的是,本来mask只需要二维的矩阵即可,但是考虑到我们的输入序列都是批量的,所以我们要把原本二维的矩阵扩张成3维的张量(加入了一个batch_size维度)。上面的代码可以看出,我们已经进行了处理。
总的来说,attention中的mask 参数有几种情况:
对于decoder的第一个多头注意力子层,里面使用到的scaled dot-product attention,同时需要padding mask和sequence mask作为attn_mask,具体实现就是两个mask相加作为attn_mask。
其他情况,attn_mask一律等于padding mask。
二、 FFN
FFN的主要作用也就是简单的神经网络,可以起到空间变化的作用,具体来说,对于多头注意力得到特征对再进行FFN的非线性处理,可以挖掘特征的非线性关系,增强特征的表现能力。
三、 残差连接+层归一化(Layer Normalization)
这里需要先区别层归一化layer normalization 及 批量归一化 Batch Normalization,BN 方法。
Batch Normalization:是经常会应用于图像处理中的一种方法,即每层通过对于批量样本的净输入的标准化来减少样本带来的输入的过大偏移。
layer normalization:是和批量归一化非常类似的方法. 和批量归一化不同的是层归一化是对一个中间层的所有神经元进行归一化。LN主要是会用于NLP处理中,之所以利用LN而不是BN进行处理,原因在于:
NLP中 batch normalization与 layer normalization - 知乎 如果我们将一批文本组成一个batch,那么BN的操作方向是,对每句话的第一个词进行操作。但语言文本的复杂性是很高的,任何一个词都有可能放在初始位置,且词序可能并不影响我们对句子的理解。而BN是针对每个位置进行缩放,这不符合NLP的规律。而LN则是针对一句话进行缩放的,且LN一般用在第三维度,如[batchsize, seq_len, dims]中的dims,一般为词向量embedding的维度,或者是RNN的输出维度等等,这一维度各个特征的量纲应该相同。因此也不会遇到上面因为特征的量纲不同而导致的缩放问题。
在transformer中,比如对于encoder的multi-head attention进行layer normalization,可以理解为对于embedding通过multi-head attention得到的各组特征进行标准化。具体操作如下:
四、 Embedding
1 词Embedding
值得注意的应该只有encoder及decode部分的embedding是权重共享的,另外输出的结果也利用相同的embedding进行解码,得到预测的文本序列生成结果。
2 位置Embedding -- Positional Encoding
关于attention is all your need 中的 巧妙的位置编码这里就不说了,note下keras中的transformer位置参数并没有采用以上方法,而是直接建立了一个sequence_length*output_dim的新的embedding。