.. _sec_encoder-decoder: Arquitetura Encoder-Decoder =========================== Como discutimos em :numref:`sec_machine_translation`, maquina de tradução é um domínio de problema principal para modelos de transdução de sequência, cuja entrada e saída são ambas as sequências de comprimento variável. Para lidar com este tipo de entradas e saídas, podemos projetar uma arquitetura com dois componentes principais. O primeiro componente é um *codificador*: ele pega uma sequência de comprimento variável como entrada e a transforma em um estado com uma forma fixa. O segundo componente é um *decodificador*: ele mapeia o estado codificado de uma forma fixa a uma sequência de comprimento variável. Isso é chamado de arquitetura *codificador-decodificador*, que é representado em :numref:`fig_encoder_decoder`. .. _fig_encoder_decoder: .. figure:: ../img/encoder-decoder.svg A arquitetura encoder-decoder. Vamos fazer uma tradução automática de inglês para francês como um exemplo. Dada uma sequência de entrada em inglês: “They”, “are”, “watching”, “.”, esta arquitetura de codificador-decodificador primeiro codifica a entrada de comprimento variável em um estado, então decodifica o estado para gerar o token de sequência traduzido por token como saída: “Ils”, “respectent”, “.”. Uma vez que a arquitetura codificador-decodificador forma a base de diferentes modelos de transdução de sequência nas seções subsequentes, esta seção irá converter esta arquitetura em uma interface que será implementada posteriormente. Encoder ------- Na interface do codificador, nós apenas especificamos isso o codificador recebe sequências de comprimento variável como ``X`` de entrada. A implementação será fornecida por qualquer modelo que herde esta classe ``Encoder`` base. .. raw:: html
mxnetpytorch
.. raw:: html
.. code:: python from mxnet.gluon import nn #@save class Encoder(nn.Block): """The base encoder interface for the encoder-decoder architecture.""" def __init__(self, **kwargs): super(Encoder, self).__init__(**kwargs) def forward(self, X, *args): raise NotImplementedError .. raw:: html
.. raw:: html
.. code:: python from torch import nn #@save class Encoder(nn.Module): """The base encoder interface for the encoder-decoder architecture.""" def __init__(self, **kwargs): super(Encoder, self).__init__(**kwargs) def forward(self, X, *args): raise NotImplementedError .. raw:: html
.. raw:: html
Decoder ------- Na seguinte interface do decodificador, adicionamos uma função adicional ``init_state`` para converter a saída do codificador (``enc_outputs``) no estado codificado. Observe que esta etapa pode precisar de entradas extras, como o comprimento válido da entrada, o que foi explicado in :numref:`subsec_mt_data_loading`. Para gerar um token de sequência de comprimento variável por token, toda vez que o decodificador pode mapear uma entrada (por exemplo, o token gerado na etapa de tempo anterior) e o estado codificado em um token de saída na etapa de tempo atual. .. raw:: html
mxnetpytorch
.. raw:: html
.. code:: python #@save class Decoder(nn.Block): """The base decoder interface for the encoder-decoder architecture.""" 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 .. raw:: html
.. raw:: html
.. code:: python #@save class Decoder(nn.Module): """The base decoder interface for the encoder-decoder architecture.""" 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 .. raw:: html
.. raw:: html
Somando o Encoder e o Decoder ----------------------------- No fim, a arquitetura codificador-decodificador contém um codificador e um decodificador, com argumentos opcionalmente extras. Na propagação direta, a saída do codificador é usado para produzir o estado codificado, e este estado será posteriormente usado pelo decodificador como uma de suas entradas. .. raw:: html
mxnetpytorch
.. raw:: html
.. code:: python #@save class EncoderDecoder(nn.Block): """The base class for the encoder-decoder architecture.""" 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) .. raw:: html
.. raw:: html
.. code:: python #@save class EncoderDecoder(nn.Module): """The base class for the encoder-decoder architecture.""" 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) .. raw:: html
.. raw:: html
O termo “estado” na arquitetura do codificador-decodificador provavelmente inspirou você a implementar este arquitetura usando redes neurais com estados. Na próxima seção, veremos como aplicar RNNs para projetar modelos de transdução de sequência baseados em esta arquitetura de codificador-decodificador. Sumário ------- - A arquitetura do codificador-decodificador pode lidar com entradas e saídas que são sequências de comprimento variável, portanto, é adequada para problemas de transdução de sequência, como tradução automática. - O codificador pega uma sequência de comprimento variável como entrada e a transforma em um estado com forma fixa. - O decodificador mapeia o estado codificado de uma forma fixa para uma sequência de comprimento variável. Exercícios ---------- 1. Suponha que usamos redes neurais para implementar a arquitetura codificador-decodificador. O codificador e o decodificador precisam ser do mesmo tipo de rede neural? 2. Além da tradução automática, você consegue pensar em outro aplicativo em que a arquitetura codificador-decodificador possa ser aplicada? .. raw:: html
mxnetpytorch
.. raw:: html
`Discussão `__ .. raw:: html
.. raw:: html
`Discussão `__ .. raw:: html
.. raw:: html
.. raw:: html