In der Differentialrechnung sagt uns die Ableitung einer Funktion, wie stark sich der Ausgang bei einem kleinen Schubs in der Eingangsvariablen ändert. Diese Idee kann auch auf multivariable Funktionen erweitert werden. Dieser Artikel zeigt die Implementierung des Gradient Descent-Algorithmus mit NumPy. Die Idee ist sehr einfach - beginnen Sie mit einem beliebigen Startpunkt und bewegen Sie sich in Richtung des Minimums (dh -ve des Gradientenwerts) und geben Sie einen Punkt zurück, der so nahe am Minimum liegt.

GD() ist eine benutzerdefinierte Funktion, die für diesen Zweck verwendet wird. Es nimmt die folgenden Parameter:

  • Gradient ist eine Funktion, die ein aufrufbares Python-Objekt sein kann, das einen Vektor nimmt und den Gradienten einer Funktion zurückgibt, die wir zu minimieren versuchen.
  • start ist der willkürliche Startpunkt, den wir der Funktion geben, es ist eine einzelne unabhängige Variable. Es kann auch eine Liste oder ein Numpy-Array für mehrere Variablen sein.
  • learn_rate steuert die Größenordnung, um die die Vektoren aktualisiert werden.
  • n_iter ist die Anzahl der Iterationen, die die Operation ausführen soll.
  • tol ist das Toleranzniveau, das die minimale Bewegung in jeder Iteration angibt.

Unten ist die Implementierung angegeben, um die erforderliche Funktionalität zu erzeugen.

Beispiel:

Python3

import numpy as np
  
  
def GD(f, start, lr, n_iter=50, tol=1e-05):
    res = start
      
    for _ in range(n_iter):
        
        # graident is calculated using the np.gradient 
        # function.
        new_val = -lr * np.gradient(f)
        if np.all(np.abs(new_val) <= tol):
            break
        res += new_val
          
    # we return a vector as the gradient can be
    # multivariable function. if the function has 1
    # dependent variable then it returns a scalar value.
    return res
  
  
# Example 1
f = np.array([1, 2, 4, 7, 11, 16], dtype=float)
print(f"The vector notation of global minima:{GD(f,10,0.01)}")
  
# Example 2
f = np.array([2, 4], dtype=float)
print(f'The vector notation of global minima: {GD(f,10,0.1)}')

Ausgabe: 

Die Vektornotation globaler Minima:[9,5 9,25 8,75 8,25 7,75 7,5 ]

Die Vektornotation globaler Minima: [2.0539126e-15 2.0539126e-15]

Sehen wir uns relevante Konzepte, die in dieser Funktion verwendet werden, im Detail an.

Anwendung der Toleranzebene

Die folgende Codezeile ermöglicht es GD(), vorzeitig zu beenden und zurückzukehren, bevor n_iter abgeschlossen ist, wenn die Aktualisierung kleiner oder gleich dem Toleranzniveau ist. Dies beschleunigt den Prozess besonders, wenn wir ein lokales Minimum oder einen Sattelpunkt erreichen, an dem sich die Inkrementbewegung befindet sehr langsam aufgrund des sehr geringen Gradienten, wodurch die Konvergenzrate beschleunigt wird.

Python3

if np.all(np.abs(new_val) <= tol):
   break

Lernratennutzung (Hyperparameter)

  • Die Lernrate ist ein sehr entscheidender Hyperparameter, da sie das Verhalten des Gradientenabstiegsalgorithmus beeinflusst. Wenn wir beispielsweise die Lernrate von 0,2 auf 0,7 ändern, erhalten wir eine andere Lösung, die sehr nahe bei 0 liegt, aber aufgrund der hohen Lernrate gibt es eine große Änderung von x und das heißt, es überschreitet den Minimalwert mehrmals, daher oszilliert es bevor es auf null einpendelt. Diese Oszillation erhöht die Konvergenzzeit des gesamten Algorithmus.
  • Eine kleine Lernrate kann zu einer langsamen Konvergenz führen und die Sache noch schlimmer machen, wenn die Anzahl der Iterationen klein ist, dann könnte der Algorithmus sogar zurückkehren, bevor er das Minimum findet.

Unten ist ein Beispiel, um zu zeigen, wie sich die Lernrate auf unser Ergebnis auswirkt.

Beispiel:

Python3

import numpy as np
  
  
def GD(f, start, lr, n_iter=50, tol=1e-05):
    res = start
    for _ in range(n_iter):
        # gradient is calculated using the np.gradient function.
        new_val = -lr * np.gradient(f)
        if np.all(np.abs(new_val) <= tol):
            break
        res += new_val
  
    # we return a vector as the gradient can be multivariable function.
    # if the function has 1 dependent variable then it returns a scalar value.
    return res
  
  
f = np.array([2, 4], dtype=float)
# low learing rate doesn't allow to converge at global minima
print(f'The vector notation of global minima: {GD(f,10,0.001)}')

Ausgang

[9.9 9.9]

Der vom Algorithmus zurückgegebene Wert ist nicht einmal annähernd 0. Dies zeigt an, dass unser Algorithmus zurückkehrt, bevor er zu globalen Minima konvergiert.