编码器和解码器
编码器
在编码器的接口中,我们只指定长度可变的序列作为编码器的输入X。任何继承自Encoder基类的模型将完成代码实现。
from torch import nn
#@save
class Encoder(nn.Module):
"""编码器-解码器架构的基本编码器接口"""
def __init__(self, **kwargs):
super(Encoder, self).__init__(**kwargs)
def forward(self, X):
raise NotImplementedError
解码器
在下面的解码器接口中,我们新增一个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
合并编码器和解码器
总而言之,编码器-解码器架构包含了一个编码器和一个解码器,并且还拥有可选的额外参数。在前向传播中,编码器的输出用于生成编码状态,这个状态又被解码器作为器输入的一部分。
#@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)
“编码器-解码器”体系架构中的术语状态 会启发人们使用具有状态的神经网络来实现该架构