Kode asli yang tidak saya temukan di situs web PyTorch lagi.
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
Masalah dengan kode di atas tidak ada fungsi berdasarkan apa yang menghitung gradien. Ini berarti kita tidak tahu berapa banyak parameter (argumen yang dibutuhkan fungsi) dan dimensi parameter.
Untuk sepenuhnya memahami ini, saya membuat contoh yang mirip dengan aslinya:
Contoh 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])
Saya berasumsi fungsi kami adalah y=3*a + 2*b*b + torch.log(c)
dan parameternya adalah tensor dengan tiga elemen di dalamnya.
Anda bisa menganggap yang gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
seperti ini adalah akumulator.
Seperti yang mungkin Anda dengar, perhitungan sistem autograd PyTorch setara dengan produk Jacobian.
Jika Anda memiliki fungsi, seperti yang kami lakukan:
y=3*a + 2*b*b + torch.log(c)
Jacobian akan menjadi [3, 4*b, 1/c]
. Namun, Jacobian ini bukanlah cara PyTorch melakukan sesuatu untuk menghitung gradien pada titik tertentu.
PyTorch menggunakan penerusan maju dan diferensiasi otomatis mode mundur (AD) secara bersamaan.
Tidak ada matematika simbolik yang terlibat dan tidak ada diferensiasi numerik.
Diferensiasi numerik adalah menghitung δy/δb
, untuk b=1
dan di b=1+ε
mana ε kecil.
Jika Anda tidak menggunakan gradien di y.backward()
:
Contoh 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.)
Anda akan mudah mendapatkan hasil pada suatu titik, didasarkan pada bagaimana Anda mengatur Anda a
, b
, c
tensor awalnya.
Hati-hati bagaimana Anda menginisialisasi Anda a
, b
, c
:
Contoh 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])
Jika Anda menggunakan torch.empty()
dan tidak menggunakan pin_memory=True
Anda mungkin memiliki hasil yang berbeda setiap saat.
Juga, gradien catatan seperti akumulator jadi nolkan mereka saat diperlukan.
Contoh 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.)
Beberapa tip terakhir tentang istilah yang digunakan PyTorch:
PyTorch membuat grafik komputasi dinamis saat menghitung gradien dalam lintasan maju. Ini terlihat seperti pohon.
Jadi anda akan sering mendengar daun pohon ini adalah input tensor dan root adalah output tensor .
Gradien dihitung dengan menelusuri grafik dari akar ke daun dan mengalikan setiap gradien dengan menggunakan aturan rantai . Pengalikan ini terjadi pada gerakan mundur.