2020/1/27 Gepostet
Heutzutage liegt die Hauptforschung zum maschinellen Lernen in der Python-Sprache, da Python über viele Bibliotheken (sogenannte Module) für die schnelle Datenanalyse und -berechnung verfügt. Unter anderem werden wir dieses Mal ein Modul namens ** pyTorch ** verwenden und erklären, wie Parameter mithilfe der darin enthaltenen probabilistischen Gradientenabstiegsmethode (SGD) aktualisiert werden ** Wie man sie im Programm handhabt **. Bitte haben Sie jedoch Verständnis dafür, dass dieser Artikel Ihrem eigenen Memo ähnelt und dass Sie möchten, dass er nur als Referenz verwendet wird, und dass Sie der Kürze halber möglicherweise falsche Ausdrücke oder Ausdrücke verwenden. Ich möchte, dass du es tust. Darüber hinaus werde ich keine wirklich detaillierte Erklärung zu SGD geben. Wenn Sie daran interessiert sind, lernen Sie dies bitte selbst.
Außerdem werden wir in diesem Artikel nicht lernen, wie man mit Netzwerk umgeht. Wenn Sie daran interessiert sind, klicken Sie bitte auf den unten stehenden Link.
Gründliche Erklärung von CNNs mit pyTorch
Wenn Sie pyTorch zum ersten Mal verwenden, müssen Sie es mit cmd installieren, da pyTorch noch nicht in Python installiert ist. Wechseln Sie zu dem unten stehenden Link, wählen Sie den in Ihrer Umgebung mit "QUICK START LOCALLY" am Ende der Seite aus und geben Sie den Befehl ein, der mit cmd usw. angezeigt wird (Sie sollten in der Lage sein, den Befehl zu kopieren und auszuführen).
offizielle Website von pytorch
So wie numpy einen Typ namens ndarray hat, hat pyTorch einen Typ namens "** Tensor type **". Wie der ndarray-Typ kann er Matrixberechnungen durchführen und ist einander ziemlich ähnlich, aber der Tensor-Typ ist beim maschinellen Lernen insofern überlegen, als er die GPU verwenden kann. Dies liegt daran, dass maschinelles Lernen einen erheblichen Rechenaufwand erfordert und eine GPU mit einer hohen Berechnungsgeschwindigkeit verwendet. Darüber hinaus ist der Tensortyp für die Aktualisierung von Parametern des maschinellen Lernens sehr einfach zu unterscheiden. Der Schlüssel zu diesem Artikel ist, wie einfach dies ist.
Informationen zu Operationen und Erklärungen vom Typ Tensor finden Sie unter dem folgenden Link.
Was ist der Tensor-Typ von pyTorch
Unter dem folgenden Link erfahren Sie, wie die Differenzierung realisiert wird.
Zusammenfassung von Beispielen, die nicht rückwärts pyTorch sein können
Dies wird als stochastische Gradientenabstiegsmethode bezeichnet, bei der es sich lediglich um eine Parameteraktualisierungsmethode handelt. Es gibt viele mathematische Erklärungen dazu, deshalb werde ich es hier nicht erklären.
Importieren Sie zunächst, damit Sie pyTorch verwenden können. Schreiben Sie von hier aus in die Python-Datei anstelle von cmd usw. Verwenden Sie das Modul, indem Sie den folgenden Code schreiben.
filename.rb
import torch
import torch.optim as optim
Die zweite Zeile "** import torch.optim as optim **" ist das Modul, das für die Verwendung von SGD vorbereitet ist.
5-2. optim.SGD Zunächst werden die Argumente von SGD erläutert. Die Verwendung ist wie folgt geschrieben.
filename.rb
op = optim.SGD(params, lr=l, momentum=m, dampening=d, weight_decay=w, nesterov=n)
Erläuterung der folgenden Argumente
--params: Übergeben Sie den Parameter, den Sie aktualisieren möchten. Dieser Parameter muss teilbar sein. --lr: Lernrate. Übergeben Sie einen Float-Typ. --momentum: Momentum. Übergeben Sie einen Float-Typ.
Dieses Mal werden der zusätzliche Informationsimpuls, die Dämpfung, weight_decay und nestrov als Anfangswerte verwendet (alle sind 0 oder False), um das Verhalten von SGD zu sehen.
Das Programm selbst ist sehr einfach und ein Beispiel für die Berechnung wird als vorläufige Vorbereitung gezeigt.
filename.rb
x = torch.tensor(5.0, requires_grad = True)
c = torch.tensor(3.0, requires_grad = True)
b = torch.tensor(2.0)
d = 4.0
y = c*3*torch.exp(x) + b*x + d
print(y)
------------Ausgabe unten---------------
tensor(1349.7185, grad_fn=<AddBackward0>)
Wenn Sie dieses Programm als Ausdruck schreiben
y = 3 c e^{x} + bx + d
In $ x = 5 $ ist $ c = 3 $, $ b = 2 $, $ d = 4 $. Außerdem wird "** require_grad = True **" gesetzt, damit nur die Variablen ** x ** und ** c ** differenziell berechnet werden können. Daraus übergeben wir SGD, um diese beiden Variablen zu aktualisieren. Das Folgende ist ein Beispiel.
filename.rb
op = optim.SGD([x,c], lr=1.0)
Beachten Sie, dass das Argument, das an den Teil ** params ** von SGD übergeben wird, "** [x, c] " ist, die auf diese Weise übergebenen Parameter jedoch die Liste " [] **" sind. Ich muss es groß machen. Dies ist natürlich ** dasselbe, wenn es nur eine Parametervariable ** gibt. Wenn Sie ein Netzwerk durch maschinelles Lernen usw. erstellen, können Sie auch die Parameter dieses Modells eingeben. In diesem Fall benötigen Sie diese Klammer jedoch nicht. Im Detail erwartet params, dass die Iteration als Argument kommt, und die Modellparameter haben die Form einer Iteration, sodass wir sie nicht benötigen. In der oben eingeführten Erläuterung von CNN finden Sie ein Beispiel für das Einfügen eines Modells.
Auch diese Variable ** op ** hat jetzt die Funktion von SGD, aber wenn Sie sie tatsächlich ausgeben, wird der Inhalt von SGD angezeigt.
filename.rb
print(op)
------------Ausgabe unten---------------
SGD (
Parameter Group 0
dampening: 0
lr: 1.0
momentum: 0
nesterov: False
weight_decay: 0
)
Die tatsächliche Parameterdifferenzierung ist wie folgt.
filename.rb
y.backward()
print(x.grad)
print(c.grad)
------------Ausgabe unten---------------
tensor(1337.7185)
tensor(445.2395)
Der Differenzwert jeder Variablen kann durch Eingabe von "** Variablenname.grad " angezeigt werden. Auf diese Weise unterscheidet " y.backward () **" automatisch die Variablen, die sich auf die endgültige Ausgabe beziehen ** y **. Aktualisieren Sie dann die Parameter wie folgt.
filename.rb
op.step()
print(x)
print(c)
------------Ausgabe unten---------------
tensor(-1332.7185, requires_grad=True)
tensor(-442.2395, requires_grad=True)
Auf diese Weise wird "** op.step () **" verwendet, um unter Verwendung der Differenzinformationen jeder Variablen zu aktualisieren. Mit anderen Worten, Sie können sehen, dass der Speicher der tatsächlichen Variablen ** x ** und ** c ** mit dem Speicher der Werte von SGD übereinstimmt. Die Aktualisierungsformel unter den aktuellen Bedingungen lautet wie folgt.
x \leftarrow x - \eta\frac{\partial y}{\partial x}
$ \ Eta $ ist die Lernrate, die jetzt 1,0 beträgt. Schreiben Sie die obige Formel mit dem tatsächlichen Variablenwert und dem Differenzwert um
-1332.7185 \leftarrow 5.0 - 1.0\times 1337.7185
Es passt sicherlich zusammen.
Die Variable ** op ** mit der SGD-Funktion wurde oben ausgegeben, aber detaillierte Informationen wie Parameter wurden nicht ausgegeben. Die detaillierte Ausgabe sollte wie folgt sein. Das folgende Programm wird jedoch mit den Daten vor der oben durchgeführten Differentialberechnung und Aktualisierung ausgeführt (Variablen x und c bleiben gleich).
filename.rb
print(op.param_groups)
------------Ausgabe unten---------------
[{'params': [tensor(5., requires_grad=True), tensor(3., requires_grad=True)],
'lr': 1.0,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
Auf diese Weise können Sie die detaillierten Parameter von SGD anzeigen und sehen, dass die Informationen im Listentyp "** [] **" enthalten sind. Mit anderen Worten, wenn Sie mit dem Inhalt herumspielen möchten, gehen Sie wie folgt vor.
filename.rb
op.param_groups[0]['lr'] = 0.1
print(op)
------------Ausgabe unten---------------
SGD (
Parameter Group 0
dampening: 0
lr: 0.1
momentum: 0
nesterov: False
weight_decay: 0
)
Jetzt wurde die Lernrate ** lr ** auf 0,1 umgeschrieben. Wenn Sie tatsächlich die normale Ausgabe ausprobieren, können Sie sehen, dass sie neu geschrieben wurde.
Wie oben schreiben wir die Informationen der Variablen ** x ** mit dem Parameter Umschreiben von SGD neu. Zuerst sind die Parameter
filename.rb
print(op.param_groups[0]['params'])
------------Ausgabe unten---------------
[tensor(5., requires_grad=True), tensor(3., requires_grad=True)]
Ist. Schreiben Sie nun das 0. Element auf der Seite der Variablen ** x ** neu.
filename.rb
op.param_groups[0]['params'][0] = torch.tensor(10., requires_grad=True)
print(op.param_groups)
------------Ausgabe unten---------------
[{'params': [tensor(10., requires_grad=True), tensor(3., requires_grad=True)],
'lr': 0.1,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
Sicher umgeschrieben. ** Aber schauen wir uns den tatsächlichen Wert der Variablen an. **
filename.rb
print(x)
------------Ausgabe unten---------------
tensor(5., requires_grad=True)
Der Körper wurde überhaupt nicht umgeschrieben. Wenn ich es tatsächlich mit backward () aktualisiere
filename.rb
y.backward()
op.step()
print(x)
print(x.grad)
print(op.param_groups)
------------Ausgabe unten---------------
tensor(5., requires_grad=True)
tensor(1337.7185)
[{'params': [tensor(10., requires_grad=True),
tensor(-41.5240, requires_grad=True)],
'lr': 0.1,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
Es ist zu beachten, dass sich der Wert der Variablen c vom obigen Beispiel unterscheidet, da die Lernrate lr 0,1 beträgt. Auf diese Weise wird weder der Wert der Variablen x noch der Wert von x, den SGD hat, aktualisiert. Außerdem wird ** x.grad ** berechnet, wenn die Variable ** x ** 5 ist. Dies wird dadurch verursacht, dass der Speicherort bei der Zuweisung von "** torch.tensor (10., require_grad = True) **" unterschiedlich ist. Seien Sie sehr vorsichtig, wenn Sie den Wert einer Variablen ändern.
Oben wurde festgestellt, dass beim Umschreiben der SGD-Variableninformationen die Variablen und SGD-Parameter nicht miteinander interagierten. Er sagte, der Grund sei ein Gedächtnisfehler. Schreiben wir nun die Variablen neu.
filename.rb
op = optim.SGD([x,c], lr=1.0)
print(op.param_groups)
------------Ausgabe unten---------------
[{'params': [tensor(5., requires_grad=True), tensor(3., requires_grad=True)],
'lr': 1.0,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
Für diese Variable ** x **
filename.rb
x = torch.tensor(10., requires_grad=True)
print(x)
------------Ausgabe unten---------------
tensor(10., requires_grad=True)
Und. Wenn Sie sich die Details der Variablen ** op ** hier noch einmal ansehen
filename.rb
print(op.param_groups)
------------Ausgabe unten---------------
[{'params': [tensor(5., requires_grad=True), tensor(3., requires_grad=True)],
'lr': 1.0,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
Die Parameter haben sich nicht geändert. Natürlich, wenn Sie mit backward () aktualisieren, wie es ist
filename.rb
y.backward()
op.step()
print(x)
print(x.grad)
print(op.param_groups)
------------Ausgabe unten---------------
tensor(10., requires_grad=True)
None
[{'params': [tensor(-1332.7185, requires_grad=True),
tensor(-442.2395, requires_grad=True)],
'lr': 1.0,
'momentum': 0,
'dampening': 0,
'weight_decay': 0,
'nesterov': False}]
Interessanterweise wurde nichts an den verschiedenen Speichervariablen ** x ** vorgenommen und die Parameter von SGD wurden aktualisiert. Abschließend ** sollten Sie vermeiden, die Variablen, die Sie unnötig aktualisieren möchten, neu zu schreiben **.
Dieses Mal habe ich die SGD des Optimierers mit pyTorch erklärt, obwohl es einfach ist. Überraschenderweise gab es kein Beispiel für die Anwendung von SGD auf etwas anderes als Network, daher werde ich es vorstellen. Ich denke, es gab viele Punkte, die schwer zu lesen waren, aber ich danke Ihnen für das Lesen.