[PYTHON] Implementierung der Gradientenmethode 1

Einführung

Es ist ungefähr einen Monat her, seit ich diesen Tag im Adventskalender gebucht habe, und es ist fast Weihnachten. Irgendwie habe ich das Gefühl, dass dieses Jahr schneller als gewöhnlich vergangen ist. Dieses Mal werde ich für diejenigen, die Python bis zu einem gewissen Grad schreiben können, aber nicht wissen, welche Art der Implementierung konkret durch maschinelles Lernen erfolgen wird, dies auf leicht verständliche Weise als Weihnachtsgeschenk von mir senden. Da der theoretische Teil und der praktische Teil gemischt sind, nehmen Sie bitte nur den Teil auf und essen Sie ihn, den Sie verstehen können. Vielleicht können Sie immer noch ein Gefühl dafür bekommen. Ein intuitives Bild des maschinellen Lernens im vorherigen Artikel finden Sie auch unter hier.

Was ist die Gradientenmethode?

Die Gradientenmethode ist eine der zur Optimierung verwendeten Methoden. Diese Gradientenmethode wird häufig verwendet, um das Gewicht $ W $ zu ermitteln, das die optimale Ausgabe liefert.

Insbesondere wird vorheriger quadratischer Summenfehler angezeigt

\frac{1}{N} \sum_{n=1}^{N}\|\|\boldsymbol{y}\_{n}(\boldsymbol{x}\_{n},W)-\boldsymbol{t}_{n} \|\|^{2} \tag{1}

Eine der zu minimierenden Methoden ist die Gradientenmethode, bei der mithilfe der Differenzierung der Mindestwert ermittelt wird.

Implementierung der Differenzierung

Beginnen wir mit der Implementierung einer eindimensionalen Differenzierung. Funktion von $ x $ Differenzierung von $ f (x) $ $ f ^ {\ prime} (x) $ $ f ^ {\ prime} (x) = \ lim_ {h → 0} \ frac {f (x + h) - f (x)} {h} \ tag {2} $. Differenzierung bedeutet die Steigung der Funktion $ f (x) $ am Punkt $ x $. Zum Beispiel, wenn die Funktion $ f (x) = x ^ 2 $ ist $ f ^ {\ prime} (x) = \ lim_ {h → 0} \ frac {(x + h) ^ 2- x ^ 2} {h} = 2x \ tag {3} $. Die Implementierung ist zum Beispiel: (Da nur der folgende Code für das Hauptimportziel geschrieben wurde, vergessen Sie ihn danach grundsätzlich nicht.)

numerical_differentiation.py


import numpy as np
import matplotlib.pylab as plt

def nu_dif(f, x):
	h = 1e-4
	return (f(x + h) - f(x))/(h)

def f(x):
	return x ** 2
	
x = np.arange(0.0, 20.0, 0.1)
y = nu_dif(f, x)

plt.xlabel("x")
plt.ylabel("y")
plt.plot(x,y)
plt.show() 

Der Graph unter $ y = f \ ^ {\ prime} (x) = 2x $ sollte nun gezeichnet werden. [3382ED86-34E1-4011-BE99-ADE6A8E1E530.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535913/d1b7deeb-6e5f-6070-6bb3-b234e3b27432 .jpeg)

$ h $ ist ungefähr $ 10 \ ^ {-4} $, um Rundungsfehler zu vermeiden.

Bonus

In der obigen numerischen Berechnung ist $$ f ^ {\ prime} (x) = \ lim_ {h → 0} \ frac {f (x + h) - f (x - h)} {2h} \ tag {4} $ Berechnungen wie $ verbessern die Genauigkeit.

def nu_dif(f, x):
	h = 1e-4
	return (f(x + h) - f(x-h))/(2 * h)

Teilweise Differenzierung

Nachdem wir die eindimensionale Differenzierung implementiert haben, implementieren wir die mehrdimensionale Differenzierung. Hier werden wir der Einfachheit halber in zwei Dimensionen unterscheiden. Für eine Funktion mit zwei Variablen $ f (x, y) $ ist die Differenzierung zwischen $ x und y $, dh die partielle Differenzierung $ f_x, f_y , wie folgt definiert. $ f_x \ equiv \ frac {\ partielles f} {\ partielles x} = \ lim_ {h → 0} \ frac {f (x + h, y) - f (x, y)} {h} \ tag { 5} $ $ f_y \ equiv \ frac {\ partielles f} {\ partielles y} = \ lim_ {h → 0} \ frac {f (x, y + h) - f (x, y)} {h } \ tag {6} $$ Angenommen, die Funktion hier ist $ f (x, y) = x ^ 2 + y ^ 2 $. 32CD418B-824A-49C2-A87B-A2271759D8DD.jpeg

Lassen Sie uns nun auch eine teilweise Differenzierung implementieren. $ f_x = 2x, f_y = 2y $.

numerical_differentiation_2d.py


def f(x, y):
	return x ** 2 + y ** 2

def nu_dif_x(f, x, y):
	h = 1e-4
	return (f(x + h, y) - f(x - h, y))/(2 * h)
	
def nu_dif_y(f, x, y):
	h = 1e-4
	return (f(x, y + h) - f(x, y - h))/(2 * h)

Gradient

Der Gradientenoperator (nabla) für die dreivariable Funktion $ f (x, y, z) $ in dreidimensionalen kartesischen Koordinaten ist $ \ nabla f = \ bigg (\ frac {\ partiell f} {\ partiell x}, \ Es wird definiert durch frac {\ partielles f} {\ partielles y}, \ frac {\ partielles f} {\ partielles z} \ bigg) \ tag {7} $. Das Anwenden von Nabla $ \ nabla $ auf die Skalarfunktion ergibt eine Vektorgröße. Wenn zum Beispiel $ f (x, y, z) = x ^ 2 + y ^ 2 + z ^ 2 $, dann ist $ \ nabla f = (2x, 2y, 2z) $. ** $ - \ nabla f $ zeigt auf den Mindestwert von $ f $ (genau der Mindestwert). ** Außerdem kann Nabla im Allgemeinen auf die Dimension $ n $ erweitert werden. Illustrieren Sie $ - \ nabla f = (-2x, -2y) $ für $ f (x, y) = x ^ 2 + y ^ 2 $ für ein intuitives Verständnis. ![4C8FF21E-D388-4D7B-BB47-C71C02B2052D.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535913/90ce4f1a-0c0f-fbe9-a389-a8c5f5d5 .jpeg) Sie können sehen, dass der planare Vektor $ xy $ $ - \ nabla f $ an jedem Punkt auf den Ursprung zeigt. Und der Wert am Ursprung ist $ f (0,0) = 0 $, was dem Mindestwert von $ f $ entspricht. Die Größe des Pfeils gibt die Größe der Neigung an diesem Punkt an.

Implementierung der Gradientenmethode

Danke für deine harte Arbeit. Dies deckt alle mathematischen Grundlagen ab, die zur Implementierung einer einfachen Gradientenmethode erforderlich sind. Lassen Sie uns nun ein Programm implementieren, das automatisch den Mindestwert der Funktion ermittelt. Beliebiger Punkt Ausgehend von $ \ boldsymbol {x} ^ {(0)} $ $$ \ boldsymbol {x} ^ {(k + 1)} = \ boldsymbol {x} ^ {(k)} - \ eta \ nabla Schieben Sie nach unten zu dem Punkt $ \ boldsymbol {x} ^ * , der den Mindestwert gemäß f \ tag {8} $ angibt. Hier ist $ \ eta $ ein Hyperparameter, den Menschen in einer Größe angeben müssen, die als Lernkoeffizient bezeichnet wird. $ \ eta $ muss entsprechend angepasst werden, damit es nicht zu groß oder zu klein sein kann. Dieses Mal werde ich die Erklärung zum Lernkoeffizienten weglassen.

Implementieren Sie nun die Gradientenmethode, um den Punkt $ \ boldsymbol {x} ^ * = (x ^ *, y ^ *) $ zu finden, der den Mindestwert von $ f (x, y) = x ^ 2 + y ^ 2 $ ergibt. Machen wir das. Wie Sie bereits wissen, sind Sie erfolgreich, wenn Sie $ \ boldsymbol {x} ^ * = (0,0) $ erhalten.

numerical_gradient.py


#Gibt den Gradienten von f zurück
def numerical_gradient(f, x):
	h = 1e-4
	grad = np.zeros_like(x)
	
	for i in range(x.size):
		tmp = x[i]
		x[i] = tmp + h
		f1 = f(x)
		x[i] = tmp - h
		f2 = f(x)
		grad[i] = (f1 - f2)/(2 * h)
		x[i] = tmp
		
	return grad	

#Gradientenmethode
def gradient_descent(f, x, lr = 0.02, step_num = 200):
	for i in range(step_num):
		grad = numerical_gradient(f, x)
		x -= lr * grad
		
	return x
	
#Definiere f
def f(x):
	return x[0] ** 2 + x[1] ** 2

#Ausgabe x
print(gradient_descent(f, np.array([10.0, 3.0])))

Das Ergebnis der Einstellung von $ \ boldsymbol {x} ^ {(0)} = (10,3), \ eta = 0,02, k = 0,1, \ ldots, 199 $ [ 0.00284608 0.00085382] Sollte ausgegeben werden. Da sowohl $ x als auch y $ ungefähr $ 10 ^ {-3} $ sind, kann man sagen, dass sie fast $ 0 $ sind.

Gradientenmethode beim maschinellen Lernen

Der Umriss und die Nützlichkeit der Gradientenmethode wurden oben erläutert. Beim maschinellen Lernen ist der Schlüssel, wie das optimale Gewicht $ \ boldsymbol {W} $ gefunden wird. Das optimale Gewicht ist die Verlustfunktion $ \ boldsymbol {W} $, die $ L $ minimiert. Die Gradientenmethode kann als eine der Methoden verwendet werden, um dies zu erhalten. Das Gewicht $ \ boldsymbol {W} $ ist beispielsweise eine $ 2 \ times2 $ -Matrix

\boldsymbol{W}=\left(\begin{array}{cc}
w_{11} & w_{12} \\
w_{21} & w_{22} 
\end{array}\right) \tag{9}

Für die Verlustfunktion $ L $ in

\nabla L \equiv \frac{\partial L}{\partial \boldsymbol {W}}\equiv\left(\begin{array}{cc}
\frac{\partial L}{\partial w_{11}} & \frac{\partial L}{\partial w_{12}} \\
\frac{\partial L}{\partial w_{21}} & \frac{\partial L}{\partial w_{22}} 
\end{array}\right) \tag{10}

Berechnen Sie $ \ boldsymbol {W} ^ {(k + 1)} = \ boldsymbol {W} ^ {(k)} - \ eta \ nabla L \ tag {11} $ Wenn Sie die Gradientenmethode gemäß anwenden, finden Sie $ \ boldsymbol {W} $, das den Mindestwert von $ L $ angibt. In den meisten Fällen ergibt das erhaltene $ \ boldsymbol {W} $ jedoch keinen Mindestwert von $ L $. Es ist, als würde man sich in eine Falle stürzen, bevor man an sein Ziel kommt. Die gekrümmte Oberfläche von $ L $ ist häufig für verschiedene $ \ boldsymbol {W} $ verbeult. Um dies zu vermeiden, gibt es einige andere Möglichkeiten, die etwas komplizierter sind. Ich werde ab dem nächsten Mal darüber schreiben.

Zusammenfassung

Vielen Dank, dass Sie so weit gelesen haben. Dieses Mal begann ich mit einer einfachen eindimensionalen Differentialimplementierung mit Python und erweiterte sie auf mehrere Dimensionen. Dann stellte ich den Gradientenoperator Nabla vor und lernte die Gradientenmethode, um den Minimalwert einer beliebigen Funktion damit zu ermitteln. Und schließlich habe ich Ihnen gesagt, dass die Verwendung der Gradientenmethode die Verlustfunktion reduzieren, dh die Genauigkeit des maschinellen Lernens verbessern kann. Obwohl die so erhaltenen Gewichte oft extrem sind, haben wir auch festgestellt, dass das Problem darin besteht, dass die Verlustfunktion nicht minimiert oder optimiert wird. Ab dem nächsten Mal werde ich einen anderen Ansatz für dieses Problem versuchen.

abschließend

Dieses Mal hatte ich die Gelegenheit, mich von einem Freund vorstellen zu lassen und in diesem Adventskalender 2019 der Chiba University zu posten. Es war ein wenig schwierig, weil ich es aus einem ziemlich rudimentären Teil zusammenfasste, aber ich konnte länger als gewöhnlich schreiben und fühlte ein Gefühl der Müdigkeit und Leistung. Zusätzlich zu meinen Posts veröffentlichen verschiedene Leute wundervolle Posts zu verschiedenen Themen auf verschiedenen Ebenen. Schauen Sie also bitte mal rein.

Recommended Posts

Implementierung der Gradientenmethode 1
Liste der Gradientenabstiegsmethoden (2020)
Zusammenfassung der Unity IAP-Implementierungsmethode
Einsum Implementierung der Wertiterationsmethode
Algorithmus für maschinelles Lernen (Gradientenabstiegsmethode)
Implementierung und Experiment der konvexen Clustering-Methode
Sattelpunktsuche mit der Gradientenmethode
Abschlussimplementierung
Binäre Methode
Denken Sie grob über die Gradientenabstiegsmethode nach
Implementierung von SVM durch probabilistische Gradientenabstiegsmethode
Spezielle Methode
Spezielle Methode
Zusammenfassende Anmerkung zu Deep Learning -4.3 Gradientenmethode-
Implementierung der logistischen Regression mit Partikelgruppenoptimierungsmethode