练习题放在最前面:
关于Transformer描述正确的是:
在训练和预测过程中,解码器部分均只需进行一次前向传播。
Transformer 内部的注意力模块均为自注意力模块。
解码器部分在预测过程中需要使用 Attention Mask。
自注意力模块理论上可以捕捉任意距离的依赖关系。
答案解释
选项1:训练过程1次,预测过程要进行句子长度次
选项2:Decoder 部分的第二个注意力层不是自注意力,key-value来自编码器而query来自解码器
选项3:不需要
选项4:正确,因为自注意力会计算句子内任意两个位置的注意力权重
2.
在Transformer模型中,注意力头数为h,嵌入向量和隐藏状态维度均为d,那么一个多头注意力层所含的参数量是:
4hd24hd^24hd2
(3h+1)d2(3h + 1)d^2(3h+1)d2
4d24d^24d2
3hd23hd^23hd2
答案解释
参考MultiHeadAttention模块的定义。
hhh个注意力头中,每个的参数量为3d23d^23d2,最后的输出层形状为hd×dhd \times dhd×d,所以参数量共为4hd24hd^24hd2。
3.
下列对于层归一化叙述错误的是:
层归一化有利于加快收敛,减少训练时间成本
层归一化对一个中间层的所有神经元进行归一化
层归一化对每个神经元的输入数据以mini-batch为单位进行汇总
层归一化的效果不会受到batch大小的影响
答案解释
批归一化(Batch Normalization)才是对每个神经元的输入数据以mini-batch为单位进行汇总
选择题
1.
以下对于注意力机制叙述错误的是:
注意力机制借鉴了人类的注意力思维方式,以获得需要重点关注的目标区域。
在计算注意力权重时,key 和 query 对应的向量维度需相等。
点积注意力层不引入新的模型参数。
注意力掩码可以用来解决一组变长序列的编码问题。
答案解释
在Dot-product Attention中,key与query维度需要一致,在MLP Attention中则不需要。
2.
以下对于加入Attention机制的seq2seq模型的陈述正确的是:
seq2seq模型不可以生成无穷长的序列。
每个时间步,解码器输入的语境向量(context vector)相同
解码器RNN仍由编码器最后一个时间步的隐藏状态初始化。
引入注意力机制可以加速模型训练。
答案解释
选项1:seq2seq模型的预测需人为设定终止条件,设定最长序列长度或者输出[EOS]结束符号,若不加以限制则可能生成无穷长度序列
选项2:不同,每个位置都会计算各自的attention输出
选项3:正确
选项4:注意力机制本身有高效的并行性,但引入注意力并不能改变seq2seq内部RNN的迭代机制,因此无法加速。
3.
关于点积注意力机制描述错误的是:
高维张量的矩阵乘法可用于并行计算多个位置的注意力分数。
计算点积后除以d\sqrt{d}d
以减轻向量维度对注意力权重的影响。
可视化注意力权重的二维矩阵有助于分析序列内部的依赖关系。
对于两个有效长度不同的输入序列,若两组键值对完全相同,那么对于同一个query的输出一定相同。
答案解释
有效长度不同导致 Attention Mask 不同,屏蔽掉无效位置后进行attention,会导致不同的输出。参考代码Dot-Product Attention的测试部分。
注意力机制在“编码器—解码器(seq2seq)”⼀节⾥,解码器在各个时间步依赖相同的背景变量(context vector)来获取输⼊序列信息。当编码器为循环神经⽹络时,背景变量来⾃它最终时间步的隐藏状态。将源序列输入信息以循环单位状态编码,然后将其传递给解码器以生成目标序列。然而这种结构存在着问题,尤其是RNN机制实际中存在长程梯度消失的问题,对于较长的句子,我们很难寄希望于将输入的序列转化为定长的向量而保存所有的有效信息,所以随着所需翻译句子的长度的增加,这种结构的效果会显著下降。
与此同时,解码的目标词语可能只与原输入的部分词语有关,而并不是与所有的输入有关。例如,当把“Hello world”翻译成“Bonjour le monde”时,“Hello”映射成“Bonjour”,“world”映射成“monde”。在seq2seq模型中,解码器只能隐式地从编码器的最终状态中选择相应的信息。然而,注意力机制可以将这种选择过程显式地建模。
注意力机制框架Attention 是一种通用的带权池化方法,输入由两部分构成:询问(query)和键值对(key-value pairs)。ki∈Rdk,vi∈Rdv
. Query q∈Rdq , attention layer得到输出与value的维度一致 o∈Rdv. 对于一个query来说,attention layer 会与每一个key计算注意力分数并进行权重的归一化,输出的向量o
则是value的加权求和,而每个key计算的权重与value一一对应。
为了计算输出,我们首先假设有一个函数α
用于计算query和key的相似性,然后可以计算所有的 attention scores a1,…,an
by
ai=α(q,ki).
我们使用 softmax函数 获得注意力权重:
b1,…,bn=softmax(a1,…,an).
最终的输出就是value的加权求和:
o=∑i=1nbivi.
不同的attetion layer的区别在于score函数的选择,在本节的其余部分,我们将讨论两个常用的注意层 Dot-product Attention 和 Multilayer Perceptron Attention;随后我们将实现一个引入attention的seq2seq模型并在英法翻译语料上进行训练与测试。
import math
import torch
import torch.nn as nn
import os
def file_name_walk(file_dir):
for root, dirs, files in os.walk(file_dir):
# print("root", root) # 当前目录路径
print("dirs", dirs) # 当前路径下所有子目录
print("files", files) # 当前路径下所有非目录子文件
file_name_walk("/home/kesci/input/fraeng6506")
dirs []
files ['_about.txt', 'fra.txt']
Softmax屏蔽
在深入研究实现之前,我们首先介绍softmax操作符的一个屏蔽操作。
def SequenceMask(X, X_len,value=-1e6):
maxlen = X.size(1)
#print(X.size(),torch.arange((maxlen),dtype=torch.float)[None, :],'\n',X_len[:, None] )
mask = torch.arange((maxlen),dtype=torch.float)[None, :] >= X_len[:, None]
#print(mask)
X[mask]=value
return X
def masked_softmax(X, valid_length):
# X: 3-D tensor, valid_length: 1-D or 2-D tensor
softmax = nn.Softmax(dim=-1)
if valid_length is None:
return softmax(X)
else:
shape = X.shape
if valid_length.dim() == 1:
try:
valid_length = torch.FloatTensor(valid_length.numpy().repeat(shape[1], axis=0))#[2,2,3,3]
except:
valid_length = torch.FloatTensor(valid_length.cpu().numpy().repeat(shape[1], axis=0))#[2,2,3,3]
else:
valid_length = valid_length.reshape((-1,))
# fill masked elements with a large negative, whose exp is 0
X = SequenceMask(X.reshape((-1, shape[-1])), valid_length)
return softmax(X).reshape(shape)
masked_softmax(torch.rand((2,2,4),dtype=torch.float), torch.FloatTensor([2,3]))
tensor([[[0.5423, 0.4577, 0.0000, 0.0000],
[0.5290, 0.4710, 0.0000, 0.0000]],
[[0.2969, 0.2966, 0.4065, 0.0000],
[0.3607, 0.2203, 0.4190, 0.0000]]])
超出2维矩阵的乘法
X
和 Y 是维度分别为(b,n,m) 和(b,m,k)的张量,进行 b 次二维矩阵乘法后得到 Z, 维度为 (b,n,k)
。
Z[i,:,:]=dot(X[i,:,:],Y[i,:,:])for i=1,…,n .
torch.bmm(torch.ones((2,1,3), dtype = torch.float), torch.ones((2,3,2), dtype = torch.float))
tensor([[[3., 3.]],
[[3., 3.]]])
点积注意力
The dot product 假设query和keys有相同的维度, 即 ∀i,q,ki∈Rd
. 通过计算query和key转置的乘积来计算attention score,通常还会除去 d−−√
减少计算出来的score对维度