从今天开始,我会再看一遍Transformer(这是第3遍了吧……)。
这次是依据Transformer 模型的 PyTorch 实现进行学习,再梳理一下Transformer模型的重点,最后用Pytorch实现。
本来想用AllenNLP一步到位,但是前天敲了一天发现不行,我对Pytorch不懂,同时还是不了AllenNLP,干脆从头再来。
4. 残差连接Residual connection
残差连接对应的是每个block中的add
image.png
残差连接示意图如下。
假设网络中某个层对输入x作用(比如使用Relu作用)后的输出是 image.png
层归一(Layer Normalization)与批归一(Batch Normalization)的区别就在于:
- BN在每一层的每一批数据上进行归一化(计算均值和方差)
- LN在每一个样本上计算均值和方差
层归一公式
其中是x最后一个维度的均值(看实现的源码是这样解释,但是为什么是最后一个维度呢)
层归一示意图
LayerNormalization.png
6. Mask
mask掩码,在Transformer中就是对某些值进行掩盖,使其在参数更新时不产生效果。
Transformer模型涉及两种mask。
- padding mask
-
sequence mask,这个在之前decoder中已经见过,使用在multi-heads context-attention中。
其中,padding mask在所有的scaled dot-product attention里面都需要用到,而sequence mask只有在decoder的multi-heads context-attention里面用到。
两种mask使用的位置对比.png
所以,我们之前ScaledDotProductAttention的forward方法里面的参数attn_mask在不同的地方会有不同的含义。这一点我们会在后面说明。
padding mask
说白了就是对齐每一句话,每个批次输入序列长度是不一样的。就是说要以最长的那句话为标准,其他句子少一个词就填充一个0。因为这些填充的位置是没有意义的,attention机制不应该把注意力放在这些位置上,所以我们需要进行一些处理。
操作方法就是把这些位置的值加上一个非常大的负数(可以是负无穷),这样的话,经过softmax,这些位置的概率就会接近0。
padding mask是一个张量,每个值都是一个Boolen,值为False的地方就是我们要进行处理的地方。
sequence mask
sequence mask是为了使得decoder不能看见未来的信息。也就是对于一个序列,在time_step为t的时刻,我们的解码输出应该只能依赖于t时刻之前的输出,而不能依赖t之后的输出。因此我们需要想一个办法,把t之后的信息给隐藏起来。
这部分具体操作:产生一个上三角矩阵,上三角的值全为1,下三角的值全为0,对角线也是0。把这个矩阵作用在每一个序列上。
没看懂,好像第一次看这部分也是没看懂,等下实现的时候看看吧,不知道这句话的意思。
回到本小结开始的问题,attn_mask参数有几种情况?分别是什么意思?
- 对于decoder的self-attention,里面使用到的scaled dot-product attention,同时需要padding mask和sequence mask作为attn_mask,具体实现就是两个mask相加作为attn_mask。
- 其他情况,attn_mask一律等于padding mask。
网友评论