Artık PyTorch web sitesinde bulamadığım orijinal kod.
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
Yukarıdaki kodla ilgili problem, degradelerin hesaplanmasına dayalı bir işlev yoktur. Bu, kaç parametre (fonksiyonun aldığı argümanlar) ve parametrelerin boyutunu bilmediğimiz anlamına gelir.
Bunu tam olarak anlamak için orijinaline yakın bir örnek oluşturdum:
Örnek 1:
a = torch.tensor([1.0, 2.0, 3.0], requires_grad = True)
b = torch.tensor([3.0, 4.0, 5.0], requires_grad = True)
c = torch.tensor([6.0, 7.0, 8.0], requires_grad = True)
y=3*a + 2*b*b + torch.log(c)
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients,retain_graph=True)
print(a.grad) # tensor([3.0000e-01, 3.0000e+00, 3.0000e-04])
print(b.grad) # tensor([1.2000e+00, 1.6000e+01, 2.0000e-03])
print(c.grad) # tensor([1.6667e-02, 1.4286e-01, 1.2500e-05])
Fonksiyonumuzun y=3*a + 2*b*b + torch.log(c)
ve parametrelerin içinde üç element bulunan tensörler olduğunu varsaydım .
Bunun gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
akümülatör olduğunu düşünebilirsiniz .
PyTorch otomatik derecelendirme sistemi hesaplamasının Jacobian ürününe eşdeğer olduğunu duymuşsunuzdur.
Yaptığımız gibi bir işleviniz olması durumunda:
y=3*a + 2*b*b + torch.log(c)
Jacobian olurdu [3, 4*b, 1/c]
. Bununla birlikte, bu Jacobian , PyTorch'un belirli bir noktada gradyanları hesaplamak için yaptığı şeyler değildir.
PyTorch, ardışık olarak ileri geçiş ve geri mod otomatik farklılaşmasını (AD) kullanır .
Sembolik matematik söz konusu değildir ve sayısal farklılaşma yoktur.
Sayısal türev hesaplamak olacaktır δy/δb
için, b=1
ve b=1+ε
ε küçük olduğu.
Aşağıdakilerde degradeler kullanmıyorsanız y.backward()
:
Örnek 2
a = torch.tensor(0.1, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)
c = torch.tensor(0.1, requires_grad = True)
y=3*a + 2*b*b + torch.log(c)
y.backward()
print(a.grad) # tensor(3.)
print(b.grad) # tensor(4.)
print(c.grad) # tensor(10.)
Basit Eğer set şekline göre, bir noktada sonuç elde edecek a
, b
, c
başlangıçta tensörleri.
Eğer senin başlatmak kadar dikkatli olun a
, b
, c
:
Örnek 3:
a = torch.empty(1, requires_grad = True, pin_memory=True)
b = torch.empty(1, requires_grad = True, pin_memory=True)
c = torch.empty(1, requires_grad = True, pin_memory=True)
y=3*a + 2*b*b + torch.log(c)
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(a.grad) # tensor([3.3003])
print(b.grad) # tensor([0.])
print(c.grad) # tensor([inf])
Kullanır torch.empty()
ve kullanmazsanız pin_memory=True
, her seferinde farklı sonuçlar elde edebilirsiniz.
Ayrıca, gradyanlar akümülatörler gibidir, bu nedenle gerektiğinde onları sıfırlayın.
Örnek 4:
a = torch.tensor(1.0, requires_grad = True)
b = torch.tensor(1.0, requires_grad = True)
c = torch.tensor(1.0, requires_grad = True)
y=3*a + 2*b*b + torch.log(c)
y.backward(retain_graph=True)
y.backward()
print(a.grad) # tensor(6.)
print(b.grad) # tensor(8.)
print(c.grad) # tensor(2.)
Son olarak, PyTorch'un kullandığı terimlerle ilgili birkaç ipucu:
PyTorch, ileri geçişte degradeleri hesaplarken dinamik bir hesaplama grafiği oluşturur . Bu bir ağaca çok benziyor.
Bu nedenle , bu ağacın yapraklarının girdi tensörleri ve kökünün çıkış tensörü olduğunu sık sık duyacaksınız .
Gradyanlar, grafiğin kökten yaprağa izlenmesiyle ve zincir kuralını kullanarak her gradyanın çarpılmasıyla hesaplanır . Bu çarpma, geriye doğru geçişte meydana gelir.