深度学习入门--Transformer中的Decoder详解

大家好,我是CuddleSabe,目前大四在读,深圳准入职算法工程师,研究主要方向为多模态(VQA、ImageCaptioning等),欢迎各位佬来讨论!
我最近在有序地计划整理CV入门实战系列及NLP入门实战系列。在这两个专栏中,我将会带领大家一步步进行经典网络算法的实现,欢迎各位读者(da lao)订阅

Transformer中的Decoder详解

  • Decoder
  • Decoder结构
  • Masked
  • 训练与推断
  • 实现代码

Decoder

在上一节中,我们学习了Encoder的结果及实现代码:
Transformer中的Encoder详解:Multi-Head-Attention及Feed-Forward
在这一节中,我们将学习Transformer剩余的部分:Decoder

Decoder结构

深度学习入门--Transformer中的Decoder详解_第1张图片
D e c o d e r Decoder Decoder的结构和 E n c o d e r Encoder Encoder类似,但是相较于 E n c o d e r Encoder Encoder,增加了一个 S u b l a y e r Sublayer Sublayer

值得注意的是,增加的这层 S u b l a y e r Sublayer Sublayer并不是 S e l f − A t t e n t i o n Self-Attention SelfAttention,因为这层 l a y e r layer layer的输入包含了 E n c o d e r Encoder Encoder的输出和上一步 D e c o d e r Decoder Decoder的输出。

Masked

可以观察到, D e c o d e r Decoder Decoder A t t e n t i o n Attention Attention叫做 M a s k e d − M u l t i − H e a d − A t t e n t i o n Masked-Multi-Head-Attention MaskedMultiHeadAttention,其原因在于加了 M a s k Mask Mask掩码。原因在于:
防止 D e c o d e r Decoder Decoder在训练时接触到未来信息,原因详见下一条。

训练与推断

因为 D e c o d e r Decoder Decoder的输入是上一层的 O u t p u t Output Output E n c o d e r Encoder Encoder的编码,所以在训练时如果采用训练时的输出,则有可能会造成预测越来越偏差 g r o u n d − T r u t h ground-Truth groundTruth的情况:因为偏差会慢慢累积。
所以,在训练时, D e c o d e r Decoder Decoder的输入是 g r o u n d − T r u t h ground-Truth groundTruth E n c o d e r Encoder Encoder的编码,这样所有的 g r o u n d − T r u t h ground-Truth groundTruth可以同时送进 D e c o d e r Decoder Decoder进行训练。
在推断时, D e c o d e r Decoder Decoder的输入是上一层 D e c o d e r Decoder Decoder的输出和 E n c o d e r Encoder Encoder的编码,需要一个个依次送入。
在训练时,注意要 M a s k Mask Mask掉未来的信息.

实现代码

class DecoderLayer(nn.Module):
    def __init__(self, size, self_attn, src_attn, feed_forward, dropout):
        super(DecoderLayer, self).__init__()
        self.size = size
        self.self_attn = self_attn
        self.src_attn = src_attn
        self.feed_forward = feed_forward
        self.sublayer = clones(SublayerConnection(size, dropout), 3)

    def forward(self, x, memory, src_mask, tgt_mask):
        m = memory
        a = MultiHeadedAttention(8, 1024)
        x = self.sublayer[0](x, lambda x: a(x, mask=tgt_mask))
        x = self.sublayer[1](x, lambda x: self.src_attn(x, m, m, mask=src_mask))
        return self.sublayer[2](x, self.feed_forward)


# Decoder
class Decoder(nn.Module):
    def __init__(self, layer, N):
        super(Decoder, self).__init__()
        self.layers = clones(layer, N)
        self.norm = LayerNorm(layer.size)

    def forward(self, x, memory, src_mask, tgt_mask):
        for layer in self.layers:
            x = layer(x, memory, src_mask, tgt_mask)
        return self.norm(x)

你可能感兴趣的:(深度学习入门系列,深度学习,算法,人工智能,神经网络)