2017-09-24 53 views
6

PyTorch'un bu release numarası, yinelenen sinir ağı için değişken giriş uzunlukları için PackedSequence sağlar. Ancak, doğru kullanmak için biraz zor buldum. pack_padded_sequence tarafından beslendi bir RYSA tabakasının bir çıkış kurtarmak için pad_packed_sequence kullanmaPyTorch'ta toplu giriş LSTM ağı nasıl doğru uygulanır?

, biz B parti boyutu ve N gizli boyutudur, bir T x B x N tensörünü T maksimum zaman adım outputs aldık. Parti içindeki kısa diziler için, sonraki çıktının tüm sıfırlar olduğunu buldum.

İşte benim sorularım. Bu tensör kısa dizileri için sıfırların çok içerdiğinden bir bütün dizilerin son çıkışını gerekir tek çıkış görev için

  1. , basit outputs[-1] bir yanlış sonuç verecektir. Biri, tüm diziler için bireysel son çıkışı almak için dizi uzunluklarına göre indeksler oluşturmaya ihtiyaç duyacaktır. Bunu yapmanın daha basit bir yolu var mı? Birden fazla çıkış görev için
  2. (örneğin seq2seq), genellikle bir lineer tabaka N x O ekleyin ve toplu çıkışları TB x O içine T x B x O yeniden şekillendirme ve gerçek hedef TB (dil modeli genellikle tamsayı) ile çapraz entropi kaybı hesaplamak. Bu durumda, toplu çıktıda bu sıfırlar önemlidir?

cevap

3

Soru 1 - Son timestep

Bu ben geçen timestep çıktısını almak için kullandığınız koddur. Daha basit bir çözüm olup olmadığını bilmiyorum. Eğer öyleyse, bilmek isterim. Bu discussion'u izledim ve last_timestep yöntemimin göreceli kod snippet'ini yakaladım. Bu benim ilerlemem.

class BaselineRNN(nn.Module): 
    def __init__(self, **kwargs): 
     ... 

    def last_timestep(self, unpacked, lengths): 
     # Index of the last output for each sequence. 
     idx = (lengths - 1).view(-1, 1).expand(unpacked.size(0), 
               unpacked.size(2)).unsqueeze(1) 
     return unpacked.gather(1, idx).squeeze() 

    def forward(self, x, lengths): 
     embs = self.embedding(x) 

     # pack the batch 
     packed = pack_padded_sequence(embs, list(lengths.data), 
             batch_first=True) 

     out_packed, (h, c) = self.rnn(packed) 

     out_unpacked, _ = pad_packed_sequence(out_packed, batch_first=True) 

     # get the outputs from the last *non-masked* timestep for each sentence 
     last_outputs = self.last_timestep(out_unpacked, lengths) 

     # project to the classes using a linear layer 
     logits = self.linear(last_outputs) 

     return logits 

Soru 2 - varsayılan olarak Maskeli Çapraz Entropi Kaybı

Evet, sıfır yastıklı dilimler (hedefler) madde. Ancak, onları maskelemek çok kolaydır. Kullandığınız PyTorch sürümüne bağlı olarak iki seçeneğiniz vardır.

  1. PyTorch 0.2.0: ignore_index argümanı ile, CrossEntropyLoss doğrudan maskeleme Şimdi pytorch destekler. Örneğin, ben sıfır dolgu eklemek dil modelleme veya seq2seq, içinde, ben maske basitçe böyle sıfır yastıklı kelimeler (hedef):

    loss_function = nn.CrossEntropyLoss (ignore_index = 0)

  2. PyTorch 0.1.12 ve daha eski: PyTorch'un eski sürümlerinde, maskeleme desteklenmedi, bu nedenle kendi çözümünüzü uygulamak zorunda kaldınız. Kullandığım çözüm, masked_cross_entropy.py, jihunchoi tarafından yapıldı. Bu discussion da ilginizi çekebilir. (Last_timestep dönüş unpacked.gather içinde, Dosya "/root/PycharmProjects/skip-thoughts.torch/pytorch/tmpRNN.py", çizgi 13:

+0

Ben senin çözüm çalışıyorum ve ben hata var 1, idx) .squeeze() Dosya "/ usr/local/lib/python3.5/dist-packages/torch/autograd/variable.py ", satır 684, toplanır dönüş Gather.apply (öz, loş, dizin) RuntimeError: save_for_backward yalnızca giriş veya çıkış tensörlerini kaydedebilir, ancak argüman 0 yazmaz bu durumu tatmin et – chenfei