2017-08-23 1 views
3

Wir haben den folgenden Code aus der pytorch Dokumentation:Was ist der erste Parameter (Gradienten) der Rückwärtsmethode, in Pytorch?

x = torch.randn(3) 
x = Variable(x, requires_grad=True) 

y = x * 2 
while y.data.norm() < 1000: 
    y = y * 2 

gradients = torch.FloatTensor([0.1, 1.0, 0.0001]) 
y.backward(gradients) 

Was genau den Gradienten-Parameter ist, die wir in der Rückwärts Methode übergeben und auf das, was wir tun es initialisieren?

+0

Mögliche Duplikat [Pytorch, was die Steigung Argumente] (https://stackoverflow.com/questions/43451125/ pytorch-was-sind-die-Gradienten-Argumente) – jdhao

Antwort

1

voll Um Ihre Frage zu beantworten, ist es eine etwas längere Erklärung erfordern würde, die im Grunde der chain rule Arbeiten rund um die Details, wie Backprop oder mehr entwickelt.

Die kurze programmatische Antwort ist, dass die Rückwärtsfunktion von Variable die Steigung aller Variablen in der Berechnungsgrafik berechnet, die an diese Variable angehängt ist. (Zur Verdeutlichung: Wenn Sie a = b + c haben, dann zeigt der Berechnungsgraph (rekursiv) zuerst auf b, dann auf c, dann auf, wie diese berechnet werden usw.) und kumuliert diese Gradienten in dem Attribut dieser Variablen kumulativ (summiert) . Wenn Sie dann opt.step() aufrufen, d. H. Einen Schritt Ihres Optimierers, fügt er dem Wert dieser Variablen einen Bruchteil dieses Gradienten hinzu.

Das heißt, es gibt zwei Antworten, wenn Sie es konzeptionell betrachten: Wenn Sie ein Machine Learning-Modell trainieren möchten, möchten Sie normalerweise den Gradienten in Bezug auf einige Verlustfunktion haben. In diesem Fall werden die berechneten Gradienten so sein, dass der Gesamtverlust (ein Skalarwert) abnimmt, wenn die Stufenfunktion angewendet wird. In diesem speziellen Fall wollen wir den Gradienten auf einen bestimmten Wert berechnen, nämlich den Einheitslängenschritt (so dass die Lernrate den Anteil der gewünschten Gradienten berechnet). Das bedeutet, dass Sie, wenn Sie eine Verlustfunktion haben und loss.backward() aufrufen, dasselbe wie loss.backward(torch.FloatTensor([1.])) berechnen.

Während dies der übliche Anwendungsfall für Backprop in DNNs ist, ist es nur ein Spezialfall der allgemeinen Differenzierung von Funktionen. Allgemeiner ausgedrückt, die symbolischen Differenzierungspakete (in diesem Fall Autograd, als Teil von pytorch) können verwendet werden, um Gradienten früherer Teile des Berechnungsgraphen bezüglich irgendeines Gradienten an einer Wurzel des von Ihnen gewählten Teilgraphen zu berechnen. Dies ist der Fall, wenn das Schlüsselwortargument gradient nützlich ist, da Sie diesen "root-level" -Gradienten dort auch für nicht-skalare Funktionen bereitstellen können!

Um hier ein kleines Beispiel zu verdeutlichen:

a = nn.Parameter(torch.FloatTensor([[1, 1], [2, 2]])) 
b = nn.Parameter(torch.FloatTensor([[1, 2], [1, 2]])) 
c = torch.sum(a - b) 
c.backward(None) # could be c.backward(torch.FloatTensor([1.])) for the same result 
print(a.grad, b.grad) 

druckt:

Variable containing: 
1 1 
1 1 
[torch.FloatTensor of size 2x2] 
Variable containing: 
-1 -1 
-1 -1 
[torch.FloatTensor of size 2x2] 

Während

a = nn.Parameter(torch.FloatTensor([[1, 1], [2, 2]])) 
b = nn.Parameter(torch.FloatTensor([[1, 2], [1, 2]])) 
c = torch.sum(a - b) 
c.backward(torch.FloatTensor([[1, 2], [3, 4]])) 
print(a.grad, b.grad) 

druckt:

Variable containing: 
1 2 
3 4 
[torch.FloatTensor of size 2x2] 
Variable containing: 
-1 -2 
-3 -4 
[torch.FloatTensor of size 2x2] 

und

a = nn.Parameter(torch.FloatTensor([[0, 0], [2, 2]])) 
b = nn.Parameter(torch.FloatTensor([[1, 2], [1, 2]])) 
c = torch.matmul(a, b) 
c.backward(torch.FloatTensor([[1, 1], [1, 1]])) # we compute w.r.t. a non-scalar variable, so the gradient supplied cannot be scalar, either! 
print(a.grad, b.grad) 

druckt

Variable containing: 
3 3 
3 3 
[torch.FloatTensor of size 2x2] 
Variable containing: 
2 2 
2 2 
[torch.FloatTensor of size 2x2] 

und

a = nn.Parameter(torch.FloatTensor([[0, 0], [2, 2]])) 
b = nn.Parameter(torch.FloatTensor([[1, 2], [1, 2]])) 
c = torch.matmul(a, b) 
c.backward(torch.FloatTensor([[1, 2], [3, 4]])) # we compute w.r.t. a non-scalar variable, so the gradient supplied cannot be scalar, either! 
print(a.grad, b.grad) 

druckt:

Variable containing: 
    5 5 
11 11 
[torch.FloatTensor of size 2x2] 
Variable containing: 
6 8 
6 8 
[torch.FloatTensor of size 2x2] 
Verwandte Themen