2017-06-16 30 views
7

Üç basit sorum var.Özel işlev kaybı PyTorch

  1. Özel kayıp işlevim farklılaşamazsa ne olur? Hata ile pytorch veya başka bir şey yapacak mı?
  2. Özel işlevimde, modelin son kaybını temsil edecek bir kayıp değişkeni bildirirsem, bu değişken için requires_grad = True koymalı mıyım? ya da önemi yok mu? Önemli değil ise neden?
  3. Bazen insanların ayrı bir katman yazdığını ve forward işlevindeki kaybı hesapladığını gördüm. Hangi yaklaşım tercih edilir, bir işlev mi, katman mı yazılır? Niye ya?

Şaşkınlıkları gidermek için bu soruların açık ve güzel bir açıklamasına ihtiyacım var. Lütfen yardım et.

cevap

7

Gitmeme izin verin.

  1. Bu, "ayırt edilemez" ile ne demek istediğinize bağlıdır. Burada anlamlı olan ilk tanım, PyTorch'un gradyanları nasıl hesaplayacağını bilmemesidir. Yine de gradyanları hesaplamaya çalışırsanız, bu bir hata oluşturur. İki olası senaryo:

    a) Degradelerin uygulanmadığı özel bir PyTorch işlemi kullanıyorsunuz, örn. torch.svd(). Kendi operasyon uygulamış)

    import torch 
    from torch.autograd import Function 
    from torch.autograd import Variable 
    
    A = Variable(torch.randn(10,10), requires_grad=True) 
    u, s, v = torch.svd(A) # raises TypeError 
    

    b, ama backward() tanımlamak vermedi: Bu durumda bir TypeError alacak. Bu durumda, alacak bir NotImplementedError:

    class my_function(Function): # forgot to define backward() 
    
        def forward(self, x): 
         return 2 * x 
    
    A = Variable(torch.randn(10,10)) 
    B = my_function()(A) 
    C = torch.sum(B) 
    C.backward() # will raise NotImplementedError 
    

    duygusu "matematiksel olmayan türevlenebilir" dir kılan ikinci tanım. Açıkçası, matematiksel olarak ayırt edilemeyen bir işlem, ya uygulanan bir backward() yöntemine ya da duyarlı bir alt-gradyana sahip olmamalıdır. kimin backward() yöntem 0'dan subgradient 0 döndürür örnek torch.abs() için düşünün: Böyle durumlarda

    A = Variable(torch.Tensor([-1,0,1]),requires_grad=True) 
    B = torch.abs(A) 
    B.backward(torch.Tensor([1,1,1])) 
    A.grad.data 
    

    doğrudan PyTorch belgelerine bakın ve doğrudan ilgili operasyonun backward() yöntemini kazmak gerekir.

  2. Önemli değil. requires_grad kullanımı, alt grafikler için degradelerin gereksiz hesaplamaları önlemek içindir. Degrade gerektiren bir işlem için tek bir giriş varsa, çıktısı de degrade gerektirir. Tersine, tüm girdiler degrade gerektirmiyorsa, çıktı da buna ihtiyaç duymaz. Tüm Değişkenlerin gradyan gerektirmediği durumlarda alt hesaplarda geriye dönük hesaplama yapılmaz.

    Büyük olasılıkla, bazı Variables (örneğin nn.Module() alt sınıfının parametreleri), loss Değişkeniniz de degradeleri otomatik olarak gerektirecektir. Ancak, tam olarak requires_grad'un nasıl çalıştığını (yine yukarıya bakın) fark edebilirsiniz, ancak grafiğinizin yaprak değişkenleri için yalnızca requires_grad'u değiştirebilirsiniz.

  3. Tüm özel PyTorch kaybı işlevleri, 'un bir alt sınıfı olan _Loss alt sınıflarıdır.See here. Bu sözleşmeye bağlı kalmak isterseniz, özel kayıp işlevinizi tanımlarken _Loss alt sınıfını kullanmalısınız. Tutarlılıktan başka bir avantaj da, hedef değişkenlerinizi volatile veya requires_grad = False olarak işaretlemediyseniz, alt sınıfınızın AssertionError değerini yükseltmesidir. Bir diğer avantajı ise,bu nedenlerden dolayı bu yaklaşımı önerdiğim için nn.Sequential()'da kayıp fonksiyonunuzu yerleştirebilirsiniz.

+0

Bağlantı maalesef açılamıyor. – mexmex

+0

Soruyu gerçekten çözdüm çünkü çözdüm. Ama bu konuda bana yardımcı olabilir misiniz - https://stackoverflow.com/questions/44580450/cuda-vs-dataparallel-why-the-difference? –