tgt_mask = (tgt !=0).unsqueeze(1).unsqueeze(3) seq_length = tgt.size(1) nopeak_mask = (1- torch.triu(torch.ones(1, seq_length, seq_length), diagonal=1)).bool() tgt_mask = tgt_mask & nopeak_mask returnsrc_mask, tgt_mask # 前向传播 defforward(self, src, tgt): src_mask...
这里用了一个create_mask来生成需要的4个mask,分别为src_mask为保留所有、tgt_mask为下三角保留、src_padding_mask和tgt_padding_mask保留非PAD部分 defcreate_mask(src,tgt):src_seq_len=src.shape[0]tgt_seq_len=tgt.shape[0]tgt_mask=generate_square_subsequent_mask(tgt_seq_len)src_mask=torch.zeros((...
上面decoder代码中用到的src_mask和tgt_mask的来源如下: def make_std_mask(tgt, pad): "Create a mask to hide padding and future words." tgt_mask = (tgt != pad).unsqueeze(-2) tgt_mask = tgt_mask & Variable( subsequent_mask(tgt.size(-1)).type_as(tgt_mask.data)) return tgt_mask S...
tgt, tgt_mask)defencode(self, src, src_mask):# 先对输入进行embedding,然后再经过encoderreturnself.encoder(self.src_embed(src), src_mask)defdecode(self, memory, src_mask, tgt, tgt_mask):# 先对目标进行embedding,然后经过decoderreturnself.decoder(self.tgt_embed(tgt), memory, src_mask, tgt_...
(x, x, x, tgt_mask))# 这里使用的是 Self-Attention 机制,其实 m 是encoder的输出,x是decoder第一部分的输出,# 因为上面一部分的输出中, 未被预测的单词的 query 其实是 0(padding), 那么在这里可以直接使用 src_maskx = self.sublayer[1](x,lambdax: self.src_attn(x, m, m, src_mask))# ...
x = self.sublayer[0](x,lambdax: self.self_attn(x, x, x, tgt_mask)) #接着进入第二个子层,这个子层中常规的注意力机制,q是输入x;k,v是编码层输出memory,同样也传入source_mask,但是进行源数据遮掩的原因并非是抑制信息泄露,而是遮蔽掉对结果没有意义的padding。
self.tgt_embed=tgt_embed self.generator=generator defforward(self,src,tgt,src_mask,tgt_mask):"Take in and process masked src and target sequences."returnself.decode(self.encode(src,src_mask),src_mask,tgt,tgt_mask)defencode(self,src,src_mask):returnself.encoder(self.src_embed(src),src_...
这里面最大的区别就是*mask_和*_key_padding_mask,_至于*是src还是tgt,memory,这不重要,模块出现在encoder,就是src,出现在decoder,就是tgt,decoder每个block的第二层和encoder做cross attention的时候,就是memory。 *mask 对应的API是attn_mask,*_key_padding_mask对应的API是key_padding_mask ...
Padding Mask 对于输入序列一般要进行padding补齐,也就是说设定一个统一长度N,在较短的序列后面填充0到长度为N。对于那些补零的数据来说,attention机制不应该把注意力放在这些位置上,所以需要进行一些处理。具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样经过softmax后,这些位置的权重就会接近0。Tra...
x = self.sublayer[0](x, lambda x: self.self_attn(x, x, x, tgt_mask)) #接着进入第二个子层,这个子层中常规的注意力机制,q是输入x;k,v是编码层输出memory,同样也传入source_mask,但是进行源数据遮掩的原因并非是抑制信息泄露,而是遮蔽掉对结果没有意义的padding。