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.
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!
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 ypad_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.