Оригінальний код я більше не знайшов на веб-сайті PyTorch.
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
Проблема з кодом вище не існує функції, заснованої на тому, що обчислювати градієнти. Це означає, що ми не знаємо, скільки параметрів (аргументів приймає функція) та розмірність параметрів.
Щоб повністю зрозуміти це, я створив приклад, близький до оригіналу:
Приклад 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])
Я припускав, що наша функція є, y=3*a + 2*b*b + torch.log(c)а параметри - це тензори з трьома елементами всередині.
Ви можете подумати, gradients = torch.FloatTensor([0.1, 1.0, 0.0001])як ось цей акумулятор.
Як ви можете почути, обчислення системи автоградів PyTorch еквівалентно продукту Jacobian.

Якщо у вас є функція, як у нас:
y=3*a + 2*b*b + torch.log(c)
Якобієць був би [3, 4*b, 1/c]. Однак, цей якобіан не як PyTorch роблять речі для обчислення градієнтів в певній точці.
PyTorch використовує автоматичну диференціацію в режимі прямого і зворотного режимів (AD) в тандемі.
Немає символічної математики і чисельної диференціації.
Числову диференціацію було б обчислити δy/δb, для b=1і b=1+εде ε невелика.
Якщо ви не використовуєте градієнти в y.backward():
Приклад 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.)
Ви просто отримати результат в точці, грунтуючись на тому , як ви встановите a, b, cтензори спочатку.
Будьте обережні , як ви ініціалізації a, b, c:
Приклад 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])
Якщо ви використовуєте torch.empty()та не використовуєте, pin_memory=Trueто кожен раз можуть бути різні результати.
Крім того, градієнти примітки схожі на акумулятори, тому нулю їх потрібно, коли це потрібно.
Приклад 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.)
Нарешті, кілька порад щодо умов, які PyTorch використовує:
PyTorch створює динамічний обчислювальний графік при обчисленні градієнтів в прямому проході. Це схоже на дерево.
Тому ви часто чуєте, як листя цього дерева є вхідними тензорами, а корінь - вихідним тензором .
Градієнти обчислюються шляхом відстеження графіка від кореня до листа і множення кожного градієнта способом за допомогою ланцюгового правила . Це множення відбувається в зворотному проході.