目录
0.总览整个Decoder
decoder需要用到的参数是
1.dec_inputs(2,6)
2.enc_inputs(2,5)
3.enc_outputs(2,5,512)
decoder也有词编码和位置编码,这里的词编码和位置编码是复用的encoder的所以重点应该是放在decoder层的特有的东西。
1.词编码和位置编码
红色部分执行的就是对目标输入的词编码和位置编码,在这里采用的目标的数据的维度是(2,6),所以在进行词编码和位置编码后的维度是(2,6,512)
2.各种atten矩阵
在这一部分主要是得到了两个东西。
1.dec_self_attn_mask:是一个上三角的矩阵,也就是说在进行自回归的时候防止后面信息进行传递来使用的。
2.dec_enc_attn_mask:是由(dec_inputs, enc_inputs)做相乘得到的。
1.经过这一步dec_self_attn_pad_mask = get_attn_pad_mask(dec_inputs, dec_inputs).cuda(),得到的是如下的矩阵。
a | b | c | P | |
a | F | F | F | T |
b | F | F | F | T |
c | F | F | F | T |
P | F | F | F | T |
2.经过这一步得到的是掩盖的矩阵,也就是为了防止之后信息造成影响的矩阵。如下图所示dec_self_attn_subsequence_mask = get_attn_subsequence_mask(dec_inputs).cuda()
a | b | c | P | |
a | 0 | 1 | 1 | 1 |
b | 0 | 0 | 1 | 1 |
c | 0 | 0 | 0 | 1 |
P | 0 | 0 | 0 | 0 |
3.dec_self_attn_mask = torch.gt((dec_self_attn_pad_mask + dec_self_attn_subsequence_mask), 0).cuda()
先变成这样
a | b | c | P | |
a | 0 | 1 | 1 | 2 |
b | 0 | 0 | 1 | 2 |
c | 0 | 0 | 0 | 2 |
P | 0 | 0 | 0 | 2 |
再变成这样
a | b | c | P | |
a | 0 | 1 | 1 | 1 |
b | 0 | 0 | 1 | 1 |
c | 0 | 0 | 0 | 1 |
P | 0 | 0 | 0 | 1 |
这样既消除了pad的影响,又消除了某个单词之后的单词对预测这个单词的影响。
4.dec_enc_attn_mask = get_attn_pad_mask(dec_inputs, enc_inputs),这个矩阵dec_inputs是(2,5),enc_inputs是(2,6),最终的dec_enc_attn_mask是(2,6,5)
3.进入DecoderLayer层
dec_outputs, dec_self_attn, dec_enc_attn = layer(dec_outputs, enc_outputs, dec_self_attn_mask, dec_enc_attn_mask)
这一层用到了
1.dec_outputs:这是经过词编码和位置编码的输出,维度是(2,6,512)。
2.enc_outputs:这是经过层层encoder进行的输出是源数据的编码,维度是(2,5,512)
3.dec_self_attn_mask:是消除了后续影响的矩阵,维度是(2,6,6)
4.dec_enc_attn_mask:是两个inputs做的矩阵,维度是(2,6,5)也就是(2,6)和(2,5)的相乘。
将layer和里面的参数对一下
发现进入decoder层的输入就是
1.dec_inputs = decoder_outputs里面的经过词编码和位置编码的输出,是(2,6,512)维度的数据,
2.enc_outputs是(2,5,512)的数据,其他两个是:
3.dec_self_attn_mask:是消除了后续影响的矩阵,维度是(2,6,6)
4.dec_enc_attn_mask:是两个inputs做的矩阵,维度是(2,6,5)