Dies ist die fünfte Ausgabe von PyTorch Official Tutorial nach Last time. Dieses Mal fahren wir mit [PyTorch anhand von Beispielen lernen] fort (https://pytorch.org/tutorials/beginner/pytorch_with_examples.html).
Learning PyTorch with Examples
In diesem Tutorial werden Sie anhand von Beispielcode in zwei Hauptfunktionen von PyTorch eingeführt.
Das vom Beispielcode behandelte Netzwerk (Modell) besteht aus 3 Schichten (Eingabeebene, verborgene Ebene x 1, Ausgabeschicht). Die Aktivierungsfunktion verwendet ReLU.
1.1. Warm-up: numpy
Implementieren Sie vor PyTorch zuerst das Netzwerk mit numpy. Numpy hat keine Funktionen für tiefes Lernen, Farbverläufe, Sie können ein einfaches neuronales Netzwerk erstellen, indem Sie es manuell implementieren.
import numpy as np
#N: Chargengröße
# D_in: Anzahl der Eingangsdimensionen
#H: Anzahl der Dimensionen der verborgenen Schicht
# D_out: Anzahl der Ausgangsabmessungen
N, D_in, H, D_out = 64, 1000, 100, 10
#Erstellen Sie zufällige Eingabe- und Lehrerdaten
x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)
#Initialisieren Sie das Gewicht mit einem zufälligen Wert
w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)
learning_rate = 1e-6
for t in range(500):
#Vorwärtsausbreitung:Berechnet den vorhergesagten Wert y mit dem aktuellen Gewichtswert
h = x.dot(w1)
h_relu = np.maximum(h, 0)
y_pred = h_relu.dot(w2)
#Berechnet den Verlust und gibt ihn aus
loss = np.square(y_pred - y).sum()
print(t, loss)
#Berechnen Sie unter Bezugnahme auf den Verlustwert den Gradienten der Gewichte w1 und w2 durch Rückausbreitung.
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.T.dot(grad_y_pred)
grad_h_relu = grad_y_pred.dot(w2.T)
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0
grad_w1 = x.T.dot(grad_h)
#Aktualisieren Sie das Gewicht.
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
Wenn Sie diesen Code ausführen, können Sie feststellen, dass der Verlustwert gesunken ist und das Lernen voranschreitet.
1.2. PyTorch: Tensors
Numpy kann nicht mit der GPU berechnet werden, aber PyTorchs Tensor kann die GPU verwenden, um numerische Berechnungen zu beschleunigen. Tensor kann auch Gradienten berechnen, aber jetzt implementieren wir es manuell, wie im obigen Numpy-Beispiel.
import torch
dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") #Kommentar hier, um auf der GPU zu laufen.
#N: Chargengröße
# D_in: Anzahl der Eingangsdimensionen
#H: Anzahl der Dimensionen der verborgenen Schicht
# D_out: Anzahl der Ausgangsabmessungen
N, D_in, H, D_out = 64, 1000, 100, 10
#Erstellen Sie zufällige Eingabe- und Lehrerdaten
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
#Initialisieren Sie das Gewicht mit einem zufälligen Wert
w1 = torch.randn(D_in, H, device=device, dtype=dtype)
w2 = torch.randn(H, D_out, device=device, dtype=dtype)
learning_rate = 1e-6
for t in range(500):
#Vorwärtsausbreitung:Berechnet den vorhergesagten Wert y mit dem aktuellen Gewichtswert
h = x.mm(w1)
h_relu = h.clamp(min=0)
y_pred = h_relu.mm(w2)
#Berechnet den Verlust und gibt ihn aus
loss = (y_pred - y).pow(2).sum().item()
if t % 100 == 99:
print(t, loss)
#Berechnen Sie unter Bezugnahme auf den Verlustwert den Gradienten der Gewichte w1 und w2 durch Rückausbreitung.
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.t().mm(grad_y_pred)
grad_h_relu = grad_y_pred.mm(w2.t())
grad_h = grad_h_relu.clone()
grad_h[h < 0] = 0
grad_w1 = x.t().mm(grad_h)
#Aktualisieren Sie die Gewichte mithilfe der Gradientenabstiegsmethode
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2
Selbst mit diesem Code können Sie sehen, dass der Verlustwert gesunken ist und das Lernen voranschreitet.
2.1. PyTorch: Tensors and autograd
Im obigen Beispiel haben wir die Vorwärts- und Rückwärtspropagation manuell implementiert. Sie können jedoch das Autograd-Paket von PyTorch verwenden, um die Rückpropagationsberechnung zu automatisieren.
-Set require_grad = True für die Variable (Tensor), für die Sie den Gradienten berechnen möchten. ・ Rückwärts ausführen () Diese beiden können die Backpropagation-Berechnung automatisieren.
import torch
dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") #Kommentar hier, um auf der GPU zu laufen.
#N: Chargengröße
# D_in: Anzahl der Eingangsdimensionen
#H: Anzahl der Dimensionen der verborgenen Schicht
# D_out: Anzahl der Ausgangsabmessungen
N, D_in, H, D_out = 64, 1000, 100, 10
#Erstellen Sie einen zufälligen Tensor, der die Eingabe- und Lehrerdaten enthält.
# require_grad =Auf False setzen, um anzuzeigen, dass der Gradient nicht berechnet werden muss.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
#Erstellen Sie einen zufälligen Tensor, der die Gewichte enthält.
# requires_grad =Die Einstellung auf True zeigt an, dass der Gradient berechnet wird.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)
learning_rate = 1e-6
for t in range(500):
#Vorwärtsausbreitung:Berechnen Sie den vorhergesagten Wert y mit der Tensor-Operation
#Zwischenwert h, da die Rückausbreitung nicht manuell berechnet wird_relu muss nicht aufbewahrt werden
y_pred = x.mm(w1).clamp(min=0).mm(w2)
#Berechnen und zeigen Sie Verluste mithilfe der Tensor-Operationen an
#Verlust ist Form (1,) Tensor
# loss.item()Ruft den im Verlust enthaltenen Skalarwert ab
loss = (y_pred - y).pow(2).sum()
if t % 100 == 99:
print(t, loss.item())
#Verwenden Sie Autograd, um die Backpropagation zu berechnen
# backward()Benötigt_grad =Berechnet die Verluststeigung für alle Tensoren, die True sind
#Nach diesem Anruf w1.grad und w2.grad ist jeweils w1,Wird ein Tensor, der den Gradienten von w2 hält
loss.backward()
#Aktualisieren Sie die Gewichte manuell mit der Methode des steilsten Abstiegs
#Benötigen Sie für Gewicht_grad =Weil es wahr ist, Fackel.no_grad()Verhindert, dass das Berechnungsdiagramm mit aktualisiert wird
# torch.optim.Sie können das gleiche mit SGD tun
with torch.no_grad():
w1 -= learning_rate * w1.grad
w2 -= learning_rate * w2.grad
#Setzen Sie den Farbverlauf nach dem Aktualisieren der Gewichte manuell auf Null
w1.grad.zero_()
w2.grad.zero_()
Obwohl nicht im Tutorial, veranschaulichen wir das Diagramm zur Berechnung der Backpropagation. Berechnungsdiagramme können mit torchviz dargestellt werden. Wenn Sie Colaboratory verwenden, müssen Sie es installieren.
!pip install torchviz
PyTorch: Eine kleine Änderung am Tensors-Beispielcode. Stoppen Sie die Schleife, damit der Gradient nur einmal berechnet wird.
#Erstellen Sie zufällige Eingabe- und Lehrerdaten
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
#Initialisieren Sie das Gewicht mit einem zufälligen Wert
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)
#Vorwärtsausbreitung:Berechnet den vorhergesagten Wert y mit dem aktuellen Gewichtswert
h = x.mm(w1)
h_relu = h.clamp(min=0)
y_pred = h_relu.mm(w2)
#Berechnet den Verlust und gibt ihn aus
loss = (y_pred - y).pow(2).sum().item()
#Berechnen Sie unter Bezugnahme auf den Verlustwert den Gradienten der Gewichte w1 und w2 durch Rückausbreitung.
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.t().mm(grad_y_pred)
grad_h_relu = grad_y_pred.mm(w2.t())
grad_h = grad_h_relu.clone()
grad_h[h < 0] = 0
grad_w1 = x.t().mm(grad_h)
Stellen Sie das Berechnungsdiagramm mit make_dot von torchviz grafisch dar. Veranschaulicht die Vorwärtsausbreitung und den Gradienten. param_dict ist nicht erforderlich, aber Sie können Variablennamen in das Diagramm schreiben.
#Das Berechnungsdiagramm der Vorwärtsausbreitung ist dargestellt.
from torchviz import make_dot
param_dict = {'w1': w1, 'w2': w2}
make_dot(loss, param_dict)
#Das Berechnungsdiagramm des Gradienten von w1 wird gezeigt.
make_dot(grad_w1, param_dict)
#Das Berechnungsdiagramm des Gradienten von w2 wird gezeigt.
make_dot(grad_w2, param_dict)
Das Berechnungsdiagramm ist unten.
Ändern Sie in ähnlicher Weise den Beispielcode in PyTorch: Tensors und Autograd, sodass der Gradient nur einmal berechnet wird. Wenn Sie create_graph = True zur Laufzeit () angeben, bleibt das abgeleitete Diagramm erhalten.
import torch
#Erstellen Sie einen zufälligen Tensor, der die Eingabe- und Lehrerdaten enthält.
# require_grad =Auf False setzen, um anzuzeigen, dass der Gradient nicht berechnet werden muss.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
#Erstellen Sie einen zufälligen Tensor, der die Gewichte enthält.
# requires_grad =Die Einstellung auf True zeigt an, dass der Gradient berechnet wird.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)
#Vorwärtsausbreitung:Berechnen Sie den vorhergesagten Wert y mit der Tensor-Operation
#Zwischenwert h, da die Rückausbreitung nicht manuell berechnet wird_relu muss nicht aufbewahrt werden
y_pred = x.mm(w1).clamp(min=0).mm(w2)
#Berechnen und zeigen Sie Verluste mithilfe der Tensor-Operationen an
#Verlust ist Form (1,) Tensor
# loss.item()Ruft den im Verlust enthaltenen Skalarwert ab
loss = (y_pred - y).pow(2).sum()
#Verwenden Sie Autograd, um die Backpropagation zu berechnen
# backward()Benötigt_grad =Berechnet die Verluststeigung für alle Tensoren, die True sind
#Nach diesem Anruf w1.grad und w2.grad ist jeweils w1,Wird ein Tensor, der den Gradienten von w2 hält
loss_backward = loss.backward(create_graph=True)
In ähnlicher Weise ist der durch Vorwärtsausbreitung und Autograd berechnete Gradient dargestellt.
#Das Berechnungsdiagramm der Vorwärtsausbreitung ist dargestellt.
param_dict = {'w1': w1, 'w2': w2}
make_dot(loss, param_dict)
#Das Berechnungsdiagramm des Gradienten von w1 wird gezeigt.
make_dot(w1.grad, param_dict)
#Das Berechnungsdiagramm des Gradienten von w2 wird gezeigt.
make_dot(w2.grad, param_dict)
Die Vorwärtsausbreitung ist dieselbe. Die Form der Backpropagation unterscheidet sich geringfügig, aber Sie können sehen, dass die Berechnung der Backpropagation automatisch von Autograd durchgeführt wird.
2.2. PyTorch: Defining new autograd functions
In PyTorch können Sie Ihre eigene Funktion (Operator) definieren, indem Sie eine Unterklasse von torch.autograd.Function definieren. Implementieren Sie die folgenden zwei Methoden in der Unterklasse.
In diesem Beispiel definieren wir ein zweistufiges Netzwerk mit unserer eigenen Funktion, dh der ReLU-Funktion.
import torch
class MyReLU(torch.autograd.Function):
"""
torch.autograd.Unterklassenfunktion und
Durch die Implementierung von Vorwärts- und Rückwärtspfaden, die mit Tensoren funktionieren
Sie können Ihre eigene benutzerdefinierte Autograd-Funktion implementieren.
"""
@staticmethod
def forward(ctx, input):
"""
Im Vorwärtsdurchlauf erhält es den Tensor, der die Eingabe und enthält
Gibt den Tensor zurück, der die Ausgabe enthält.
ctx ist ein Objekt für Backpropagation-Berechnungen.
ctx.save_for_Verwenden Sie die Rückwärtsmethode
Sie können Objekte zwischenspeichern.
"""
ctx.save_for_backward(input)
return input.clamp(min=0)
@staticmethod
def backward(ctx, grad_output):
"""
Rückwärts empfängt es einen Tensor, der den Verlustgradienten in Bezug auf die Ausgabe enthält.
Sie müssen den Verlustgradienten für die Eingabe berechnen.
"""
input, = ctx.saved_tensors
grad_input = grad_output.clone()
grad_input[input < 0] = 0
return grad_input
dtype = torch.float
device = torch.device("cpu")
# device = torch.device("cuda:0") #Kommentar hier, um auf der GPU zu laufen.
#N: Chargengröße
# D_in: Anzahl der Eingangsdimensionen
#H: Anzahl der Dimensionen der verborgenen Schicht
# D_out: Anzahl der Ausgangsabmessungen
N, D_in, H, D_out = 64, 1000, 100, 10
#Erstellen Sie einen zufälligen Tensor, der die Eingabe- und Lehrerdaten enthält.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
#Erstellen Sie einen zufälligen Tensor, der die Gewichte enthält.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)
learning_rate = 1e-6
for t in range(500):
#So wenden Sie eine Funktion an: Funktion.Verwenden Sie die Apply-Methode.
relu = MyReLU.apply
#Vorwärtsausbreitung:Berechnen Sie den vorhergesagten Wert y mit einer benutzerdefinierten Autograd-Funktion
y_pred = relu(x.mm(w1)).mm(w2)
#Verlust berechnen und anzeigen
loss = (y_pred - y).pow(2).sum()
if t % 100 == 99:
print(t, loss.item())
#Verwenden Sie Autograd, um die Backpropagation zu berechnen
loss.backward()
#Aktualisieren Sie die Gewichte mit der Methode des steilsten Abstiegs
with torch.no_grad():
w1 -= learning_rate * w1.grad
w2 -= learning_rate * w2.grad
#Setzen Sie den Farbverlauf nach dem Aktualisieren der Gewichte manuell auf Null
w1.grad.zero_()
w2.grad.zero_()
Lassen Sie uns auch die ursprüngliche Funktion visualisieren. Stellen Sie nach wie vor sicher, dass es nur einmal verarbeitet wird.
#Erstellen Sie einen zufälligen Tensor, der die Eingabe- und Lehrerdaten enthält.
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)
#Erstellen Sie einen zufälligen Tensor, der die Gewichte enthält.
w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)
#So wenden Sie eine Funktion an: Funktion.Verwenden Sie die Apply-Methode.
relu = MyReLU.apply
#Vorwärtsausbreitung:Berechnen Sie den vorhergesagten Wert y mit einer benutzerdefinierten Autograd-Funktion
y_pred = relu(x.mm(w1)).mm(w2)
#Verlust berechnen und anzeigen
loss = (y_pred - y).pow(2).sum()
#Verwenden Sie Autograd, um die Backpropagation zu berechnen
loss.backward(create_graph=True)
Hat es ein ähnliches Berechnungsdiagramm?
Es ist lange her, deshalb möchte ich PyTorch: nn in den zweiten Teil unterteilen.
2020/05/27 Erste Ausgabe veröffentlicht
Recommended Posts