Practical-pytorch: Tutorial de soporte por lotes en seq2seq

Creado en 23 may. 2017  ·  8Comentarios  ·  Fuente: spro/practical-pytorch

Comentario más útil

Puse una primera versión del modelo por lotes en https://github.com/spro/practical-pytorch/blob/master/seq2seq-translation/seq2seq-translation-batched.ipynb a través de 31fdb61387e62948f6a24dc9a2dadd6d3221a73c

Los mayores cambios son el uso pack_padded_sequence antes del codificador RNN y pad_packed_sequence después, y la pérdida de entropía cruzada enmascarada de @jihunchoi después de la decodificación. Para el decodificador en sí, los cambios son menores porque solo ejecuta un paso de tiempo a la vez.

Todos 8 comentarios

Hola,
¡Gracias por el gran trabajo! ¿Podría agregar el procesamiento por lotes al tutorial también?

Hola, @spro , he estado trabajando para extender con lote. Mi código está aquí https://github.com/vijendra-rana/Random/blob/master/translation_with_batch.py . He creado algunos datos falsos para esto. Pero el problema es que recibo un error en la pérdida que dice


RuntimeError: intentando retroceder en el gráfico por segunda vez, pero los búferes ya se han liberado. Especifique retain_variables=True cuando llame hacia atrás por primera vez.

Entiendo que no podemos permitir que la pérdida se retroceda dos veces, pero no veo en ninguna parte que lo esté haciendo dos veces.
También tengo una pregunta sobre el enmascaramiento, ¿cómo enmascararías la pérdida en el codificador? No estoy seguro de cómo implementarlo, siendo el tamaño del codificador o/p (seq_len, lote, tamaño oculto) y la máscara (tamaño del lote, seq_len)

Gracias de antemano por la ayuda :)

Puse una primera versión del modelo por lotes en https://github.com/spro/practical-pytorch/blob/master/seq2seq-translation/seq2seq-translation-batched.ipynb a través de 31fdb61387e62948f6a24dc9a2dadd6d3221a73c

Los mayores cambios son el uso pack_padded_sequence antes del codificador RNN y pad_packed_sequence después, y la pérdida de entropía cruzada enmascarada de @jihunchoi después de la decodificación. Para el decodificador en sí, los cambios son menores porque solo ejecuta un paso de tiempo a la vez.

Gracias, @spro por tu esfuerzo en armarlos. Tus tutoriales son muy buenos.

Hola chicos, implementé más funciones basadas en este tutorial (por ejemplo, cálculo por lotes para llamar la atención) y agregué algunas notas.
Consulte mi repositorio aquí: https://github.com/howardyclo/pytorch-seq2seq-example/blob/master/seq2seq.ipynb

Noté que algunas implementaciones de batch seq2seq con atención permiten un tamaño incrustado que es diferente al tamaño oculto. ¿Hay alguna razón para hacer coincidir los dos tamaños?

@spro Gracias por la buena muestra de código.
Tuve algunos problemas, buscando ayuda: traté de ejecutarlo de inmediato, encontré un error en este bloque:

max_target_length = max(target_lengths)


decoder_input = Variable(torch.LongTensor([SOS_token] * small_batch_size))
decoder_hidden = encoder_hidden[:decoder_test.n_layers] # Use last (forward) hidden state from encoder
all_decoder_outputs = Variable(torch.zeros(max_target_length, small_batch_size, decoder_test.output_size))

if USE_CUDA:
    all_decoder_outputs = all_decoder_outputs.cuda()
    decoder_input = decoder_input.cuda()

# Run through decoder one time step at a time
for t in range(max_target_length):
    decoder_output, decoder_hidden, decoder_attn = decoder_test(
        decoder_input, decoder_hidden, encoder_outputs
    )
    all_decoder_outputs[t] = decoder_output # Store this step's outputs
    decoder_input = target_batches[t] # Next input is current target

# Test masked cross entropy loss
loss = masked_cross_entropy(
    all_decoder_outputs.transpose(0, 1).contiguous(),
    target_batches.transpose(0, 1).contiguous(),
    target_lengths
)
print('loss', loss.data[0])

El error dice lo siguiente:

RuntimeError                              Traceback (most recent call last)
<ipython-input-28-babf231e41ef> in <module>()
     13 for t in range(max_target_length):
     14     decoder_output, decoder_hidden, decoder_attn = decoder_test(
---> 15         decoder_input, decoder_hidden, encoder_outputs
     16     )
     17     all_decoder_outputs[t] = decoder_output # Store this step's outputs

/usr/local/lib/python2.7/dist-packages/torch/nn/modules/module.pyc in __call__(self, *input, **kwargs)
    489             result = self._slow_forward(*input, **kwargs)
    490         else:
--> 491             result = self.forward(*input, **kwargs)
    492         for hook in self._forward_hooks.values():
    493             hook_result = hook(self, input, result)

<ipython-input-24-43d7954b3ba4> in forward(self, input_seq, last_hidden, encoder_outputs)
     35         # Calculate attention from current RNN state and all encoder outputs;
     36         # apply to encoder outputs to get weighted average
---> 37         attn_weights = self.attn(rnn_output, encoder_outputs)
     38         context = attn_weights.bmm(encoder_outputs.transpose(0, 1)) # B x S=1 x N
     39 

/usr/local/lib/python2.7/dist-packages/torch/nn/modules/module.pyc in __call__(self, *input, **kwargs)
    489             result = self._slow_forward(*input, **kwargs)
    490         else:
--> 491             result = self.forward(*input, **kwargs)
    492         for hook in self._forward_hooks.values():
    493             hook_result = hook(self, input, result)

<ipython-input-22-61485b548d0f> in forward(self, hidden, encoder_outputs)
     27             # Calculate energy for each encoder output
     28             for i in range(max_len):
---> 29                 attn_energies[b, i] = self.score(hidden[:, b], encoder_outputs[i, b].unsqueeze(0))
     30 
     31         # Normalize energies to weights in range 0 to 1, resize to 1 x B x S

<ipython-input-22-61485b548d0f> in score(self, hidden, encoder_output)
     40         elif self.method == 'general':
     41             energy = self.attn(encoder_output)
---> 42             energy = hidden.dot(energy)
     43             return energy
     44 

RuntimeError: Expected argument self to have 1 dimension, but has 2

@suwangcompling oculto = oculto.apretar(), codificador_salida = codificador_salida.apretar()
¡puedes probarlo!

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

EinAeffchen picture EinAeffchen  ·  5Comentarios

AuCson picture AuCson  ·  3Comentarios

sakinaljana picture sakinaljana  ·  6Comentarios

kdrivas picture kdrivas  ·  3Comentarios

caozhen-alex picture caozhen-alex  ·  6Comentarios