《动手学深度学习 Pytorch版》 9.6 编码器-解码器架构

发布时间 2023-10-20 11:54:53作者: AncilunKiang

为了处理这种长度可变的输入和输出, 可以设计一个包含两个主要组件的编码器-解码器(encoder-decoder)架构:

  • 编码器(encoder):它接受一个长度可变的序列作为输入,并将其转换为具有固定形状的编码状态。

  • 解码器(decoder):它将固定形状的编码状态映射到长度可变的序列。

image

9.6.1 编码器

编码器接口仅指定长度可变的序列作为编码器的输入 X。代码实现需要由继承这个Encoder基类的模型完成。

from torch import nn
#@save
class Encoder(nn.Module):
    """编码器-解码器架构的基本编码器接口"""
    def __init__(self, **kwargs):
        super(Encoder, self).__init__(**kwargs)

    def forward(self, X, *args):
        raise NotImplementedError

9.6.2 解码器

在下面的解码器接口中新增的 init_state 函数用于将编码器的输出(enc_outputs)转换为编码后的状态。

为了逐个地生成长度可变的词元序列,解码器在每个时间步都会将输入(例如:在前一时间步生成的词元)和编码后的状态映射成当前时间步的输出词元。

#@save
class Decoder(nn.Module):
    """编码器-解码器架构的基本解码器接口"""
    def __init__(self, **kwargs):
        super(Decoder, self).__init__(**kwargs)

    def init_state(self, enc_outputs, *args):
        raise NotImplementedError

    def forward(self, X, state):
        raise NotImplementedError

9.6.3 合并编码器和解码器

#@save
class EncoderDecoder(nn.Module):
    """编码器-解码器架构的基类"""
    def __init__(self, encoder, decoder, **kwargs):
        super(EncoderDecoder, self).__init__(**kwargs)
        self.encoder = encoder
        self.decoder = decoder

    def forward(self, enc_X, dec_X, *args):
        enc_outputs = self.encoder(enc_X, *args)
        dec_state = self.decoder.init_state(enc_outputs, *args)
        return self.decoder(dec_X, dec_state)

练习

(1)假设我们使用神经网络来实现“编码器-解码器”架构,那么编码器和解码器必须是同一类型的神经网络吗?

不需要吧,编码器解码器是抽象于神经网络的。


(2)除了机器翻译,还有其它可以适用于”编码器-解码器“架构的应用吗?

时序模型很多都需要的吧。