Den Originalcode habe ich auf der PyTorch-Website nicht mehr gefunden.
gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
y.backward(gradients)
print(x.grad)
Das Problem mit dem obigen Code gibt es keine Funktion basierend auf der Berechnung der Gradienten. Dies bedeutet, dass wir nicht wissen, wie viele Parameter (Argumente die Funktion akzeptiert) und welche Dimension von Parametern.
Um dies vollständig zu verstehen, habe ich ein Beispiel erstellt, das dem Original nahe kommt:
Beispiel 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])
Ich nahm an, dass unsere Funktion ist y=3*a + 2*b*b + torch.log(c)
und die Parameter Tensoren mit drei Elementen im Inneren sind.
Sie können sich vorstellen, gradients = torch.FloatTensor([0.1, 1.0, 0.0001])
dass dies der Akkumulator ist.
Wie Sie vielleicht hören, entspricht die Berechnung des PyTorch-Autograd-Systems dem Jacobian-Produkt.
Falls Sie eine Funktion haben, wie wir es getan haben:
y=3*a + 2*b*b + torch.log(c)
Jacobian wäre [3, 4*b, 1/c]
. Mit diesem Jacobi berechnet PyTorch jedoch nicht die Gradienten an einem bestimmten Punkt.
PyTorch verwendet die automatische Differenzierung im Vorwärts- und Rückwärtsmodus (AD) im .
Es gibt keine symbolische Mathematik und keine numerische Differenzierung.
Die numerische Differenzierung wäre zu berechnen δy/δb
, für b=1
und b=1+ε
wo ε klein ist.
Wenn Sie keine Farbverläufe verwenden in y.backward()
:
Beispiel 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.)
Sie werden das Ergebnis an einem Punkt einfach bekommen, je nachdem , wie Sie setzten Ihre a
, b
, c
Tensoren zunächst.
Seien Sie vorsichtig , wie Sie initialisieren Ihre a
, b
, c
:
Beispiel 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])
Wenn Sie verwenden torch.empty()
und nicht verwenden pin_memory=True
, können Sie jedes Mal andere Ergebnisse erzielen.
Notenverläufe sind auch wie Akkumulatoren, also setzen Sie sie bei Bedarf auf Null.
Beispiel 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.)
Zuletzt einige Tipps zu Begriffen, die PyTorch verwendet:
PyTorch erstellt bei der Berechnung der Gradienten im Vorwärtsdurchlauf ein dynamisches Berechnungsdiagramm . Das sieht einem Baum sehr ähnlich.
So werden Sie oft die hören Blätter dieses Baumes sind Eingangs Tensoren und die Wurzel ist Ausgangs Tensor .
Farbverläufe werden berechnet, indem das Diagramm von der Wurzel bis zum Blatt verfolgt und jeder Farbverlauf mithilfe der Kettenregel multipliziert wird . Diese Multiplikation erfolgt im Rückwärtsdurchlauf.