[PYTHON] Ich lernte auch + init, Klasse, die versuchte, den Minimalwert der quadratischen Funktion zu finden, indem sie die Optimierungsmethode (SGD, Momentum, AdaGrad) in Deep Learning selbst machte.

Einführung

Täglich werden neue Algorithmen für Optimierungsmethoden in neuronalen Netzen erstellt. Im vorherigen Artikel habe ich zusammengefasst, wie es von SGD zu ADAM entwickelt wurde.

https://qiita.com/Fumio-eisan/items/798351e4915e4ba396c2

In diesem Artikel möchte ich diese Optimierungstechnik implementieren und sehen, wie schnell sie in einem neuronalen Netzwerk konvergiert! .. Dieses Mal möchte ich diese Optimierungsmethode auf eine einfache quadratische Funktion anwenden. Nehmen Sie in Lehrbüchern usw. grundsätzlich ein handgeschriebenes numerisches Bild wie MNIST als Beispiel und bestätigen Sie, dass der Wert der Verlustfunktion abnimmt. Da jedoch die Verlustfunktion im neuronalen Netzwerk sehr kompliziert ist, ist es schwierig zu erkennen, ob der Minimalwert abgeleitet wird. Daher möchte ich dieses Mal eine quadratische Funktion als Beispiel nehmen und sehen, wie sie sich dem Minimalwert nähert.   Außerdem habe ich das Definieren und Laden der Klasse selbst implementiert, aber ich werde feststellen, was ich dort verstanden habe.

Dies ist eine Übersicht.

Zweck der Zielfunktion und Optimierungsmethode

Hier ist der Zweck der quadratischen Funktion und der Optimierungsmethode, die dieses Mal angestrebt werden.

image.png

Ich habe mich entschlossen, den Mindestwert einer sehr leicht verständlichen Funktion zu finden. Da $ y = x ^ 2 $, wird $ y $, das den Mindestwert annimmt, zu $ y = 0 $, wenn $ x = 0 $. Ich möchte diese Funktion verwenden, die sowohl sinnlich als auch visuell leicht zu verstehen ist, um $ x $ ständig zu aktualisieren und zu bestätigen, dass sie sich $ y = 0 $ nähert.

Implementierungsdetails

Dieses Mal wird das Programm, das die Funktion definiert, in optimizers.py gespeichert. Anschließend wird die Funktion in sample.ipynb gelesen, berechnet und dargestellt. Daher würden wir uns bei der Implementierung freuen, wenn Sie diese beiden Programme im selben Ordner speichern und ausführen könnten.

Implementieren Sie SGD (Probabilistic Gradient Descent Method)

Erstens ist die grundlegende SGD. Die Formel ist unten gezeigt.

\mathbf{x}_{t + 1} \gets \mathbf{x}_{t} - \eta g_t\\
g_t = 2 *\mathbf{x}_{t} 

$ \ eta $ ist die Lernrate und $ g_t $ ist der Gradient der Funktion. $ g_t $ ist diesmal $ 2 * \ mathbf {x} _ {t} $, also ist es praktisch.

Als nächstes werden wir diese Technik implementieren.

optimizers.py


class SGD:

    def __init__(self, lr = 0.01,x=100):
        self.lr = 0.01
        self.x =100.0

    def update(self,x):
        x+= -self.lr * 2*x 
        return x

Die Formel selbst ist einfach, daher denke ich, dass es leicht zu verstehen ist, wenn man sich das Programm ansieht. Diese Funktion berechnet im nächsten Schritt $ x $ und gibt $ x $ zurück. $ \ Eta $ wird hier als $ lr $ geschrieben.

Hier ist ein Programm, das wiederholt $ x $ berechnet, um tatsächlich den Mindestwert zu finden.

sample.ipynb


max_iterations = 100

y7=[]
y8=[]
y9=[]

v7=[]
v8=[]
v9=[]
optimizer = optimizers.SGD()

x = 100
optimizer.lr =0.1
for i in range(max_iterations):
    x = optimizer.update(x)
    y7.append(x)
    v7.append(optimizer.lr)
    
x = 100
optimizer.lr =0.01
for i in range(max_iterations):
    x = optimizer.update(x)
    y8.append(x)
    v8.append(optimizer.lr)

x = 100
optimizer.lr =0.9
for i in range(max_iterations):
    x = optimizer.update(x)
    y9.append(x)
    v9.append(optimizer.lr)

Mal sehen, wie sich die Konvergenz der Funktion ändert, wenn wir $ \ eta $ auf 0.1,0.01,0.9 ändern.

sample.ipynb



x = np.arange(max_iterations)
plt.plot(x, y7, label='lr=0.1')
plt.plot(x, y8, label='lr=0.01')
plt.plot(x, y9, label='lr=0.9')
plt.xlabel("iterations")
plt.ylabel("y")
plt.ylim(-5, 120)
plt.legend()
plt.show()

005.png

Sie können sehen, dass je näher sich der Wert von $ y $ auf der vertikalen Achse 0 nähert, desto mehr konvergiert er.

Wenn $ \ eta $ 0,01 ist, dauert die Konvergenz einige Zeit. Im Gegenteil, wenn $ \ eta $ bis zu 0,9 zu groß ist, können Sie sehen, dass es während der Jagd zur Konvergenz kommt. Wenn dieser Wert in dieser Funktion 1 oder mehr beträgt, wird er abweichen. Daher ist ersichtlich, dass $ \ eta $ ein guter Wert um 0,1 ist, der schnell konvergiert und Divergenz unterdrückt.

Momentum implementieren

Als nächstes werden wir Momentum implementieren. Im Vergleich zum vorherigen SGD unterdrückt dieser Algorithmus Vibrationen, indem er die Bewegung von $ x $ selbst berücksichtigt.

\mathbf{x}_{t + 1} \gets \mathbf{x}_{t} + h_t\\
h_t=-\eta * g_t +\alpha * h_{t-1}

Definieren Sie eine Funktion.

optimizers.py



class Momentum:

    def __init__(self,lr=0.01,alpha=0.8,v=None):
        self.lr = 0.01
        self.v = 0.0
        self.alpha = 0.8

    def update(self,x):
        self.v = self.v*self.alpha  - (2.0)*x*self.lr 
        x += + self.v
        return x

Und Renn. Dieses Mal werden wir den Effekt bewerten, indem wir den Wert von $ \ alpha $ als Hyperparameter ändern. 006.png

Der Standard $ \ alpha $ soll 0,8 sein. Selbst in diesem Ergebnis können wir sehen, dass 0,8 ein Wert ist, der genau richtig zu sein scheint. Wenn der Wert größer als dieser Wert ist, werden Sie viel jagen.

Implementieren Sie AdaGrad

Nun, diesmal ist der letzte AdaGrad. Bisher war die Lernrate $ \ eta $ konstant. Das Merkmal ist jedoch, dass diese Lernrate selbst den Effekt hat, dass sie mit der Anzahl der Berechnungen allmählich abnimmt.

h_{0} = \epsilon\\
h_{t} = h_{t−1} + g_t^{2}\\
\eta_{t} = \frac{\eta_{0}}{\sqrt{h_{t}}}\\
\mathbf{x}_{t+1} = \mathbf{w}^{t} - \eta_{t}g_t

Definieren Sie eine Funktion.

optimizers.py


class AdaGrad:

    def __init__(self,h0=10.0):
        self.v = 0.0
        self.h = 0.0
        self.h0 = 10.0

    def update(self,x):
        self.h += + (2.0*x)**2
        self.v = -self.h0/(np.sqrt(self.h)+1e-7)
        x += + self.v*2*x
        return x

Übrigens habe ich diesmal berechnet, indem ich den Anfangswert der Lernrate $ \ eta_0 $ (h0 im Programm) geändert habe.

007.png

Es stellte sich heraus, dass $ \ eta_0 $ um 100 schneller konvergiert und nicht divergiert.

Verständnis von Klasse und Init

Da ich ein Anfänger in Python bin, habe ich init in meiner Klasse mit einem starken Eindruck verwendet. Dieses Mal fand ich Folgendes.

abschließend

Dieses Mal wurde die Funktion durch drei Arten von Optimierungsmethoden minimiert. Sie können sehen, dass es die Idee der schrittweisen Formel verwendet, die in der sogenannten High-School-Mathematik gelernt wurde. Obwohl ich alles außer Numpy gemacht habe, hat es mir geholfen, mein Verständnis der Programmierung selbst zu vertiefen. Wie ich in O'Reillys Deep-Learning-Buch erfahren habe, implementiere ich tatsächlich eine Optimierungsmethode in einem neuronalen Netzwerk. Sie können jeden Inhalt wie die Definition von Funktionen und kleinen Variablen, das Einfügen einer Aktivierungsfunktion, die Gradientenberechnung durch die Methode der inversen Fehlerausbreitung, die Bestimmung des Anfangswertes des Gewichtsparameters usw. verstehen. Wenn es jedoch um die Programmierung geht, wird es sehr kompliziert.

** Ich fragte mich erneut, ob die Programmierer eine Kombination dieser vielen Regeln und strukturellen Kenntnisse implementieren würden, was eine entmutigende Aufgabe wäre. Aufgrund dieser Schwierigkeit möchte ich Ihnen dafür danken, dass Sie es als Klasse oder Methode bezeichnet haben und die Funktion problemlos verwenden können. ** ** **

Das vollständige Programm ist hier gespeichert. https://github.com/Fumio-eisan/optimizers_20200326

Recommended Posts

Ich lernte auch + init, Klasse, die versuchte, den Minimalwert der quadratischen Funktion zu finden, indem sie die Optimierungsmethode (SGD, Momentum, AdaGrad) in Deep Learning selbst machte.
Ermitteln Sie den Mindestwert der Funktion mithilfe der Partikelgruppenoptimierungsmethode (PSO).
Ich habe versucht, den Höhenwert von DTM in einem Diagramm anzuzeigen
[Deep Learning von Grund auf neu] Ich habe versucht, die Gradientenbestätigung auf leicht verständliche Weise zu erklären.
Ich habe auch versucht, die Funktionsmonade und die Zustandsmonade mit dem Generator in Python nachzuahmen
Ich habe versucht, das lokale Minimum der Goldstein-Preis-Funktion zu bekämpfen
Ich möchte die Frage nach der Methode "__init__" und dem Argument "self" der Python-Klasse klären.
Ich habe versucht, die optimale Route des Traumlandes durch (Quanten-) Tempern zu finden
Ich habe die übliche Geschichte ausprobiert, Deep Learning zu verwenden, um den Nikkei-Durchschnitt vorherzusagen
Ich habe versucht, das Ergebnis des A / B-Tests mit dem Chi-Quadrat-Test zu überprüfen
[Python & SQLite] Ich habe den erwarteten Wert eines Rennens mit Pferden im 1x-Gewinnbereich ① analysiert
Ich habe versucht, die Anzahl der mit dem Coronavirus infizierten Menschen in Japan nach der Methode des neuesten Papiers in China vorherzusagen
Ich habe versucht, die Lernfunktion im neuronalen Netzwerk sorgfältig zu verstehen, ohne die Bibliothek für maschinelles Lernen zu verwenden (erste Hälfte).
Ich habe einen Appdo-Befehl erstellt, um Befehle im Kontext der App auszuführen
Ich habe versucht, die Strichzeichnung mit Deep Learning aus dem Bild zu extrahieren
Ich habe versucht, das Vorhandensein oder Nichtvorhandensein von Schnee durch maschinelles Lernen vorherzusagen.
Ich habe versucht, die Veränderung der Schneemenge für 2 Jahre durch maschinelles Lernen vorherzusagen