Mittel 0 gelöst 0% Erfolgsquote

Adam-Optimierer

Implementiere Adam, den Standardoptimierer des Deep Learning, mit gleitenden Mittelwerten und Bias-Korrektur.

Das lernst du

  • Mittelwerte des ersten und zweiten Moments verfolgen
  • In frühen Schritten die Bias-Korrektur anwenden
  • Den Standardoptimierer des Deep Learning implementieren

Problem

Adam führt pro Gewicht zwei gleitende Mittelwerte, des Gradienten (m) und des quadrierten Gradienten (v), und gibt damit jedem Gewicht eine eigene Schrittweite.

Beginne mit m = 0 und v = 0 für jedes Gewicht. Für jeden Schritt t = 1, 2, 3, … mit Gradient g:

  1. m ← beta1 × m + (1 - beta1) × g
  2. v ← beta2 × v + (1 - beta2) × g²
  3. m̂ = m / (1 - beta1ᵗ) und v̂ = v / (1 - beta2ᵗ) (Bias-Korrektur)
  4. w ← w - learning_rate × m̂ / (√v̂ + epsilon)

Implementiere adam_steps(gradients, weights, learning_rate, beta1, beta2, epsilon) und wende pro Zeile von gradients ein Update an, in Reihenfolge.

Eingabe

gradients: Eine Zeile pro Schritt; jede Zeile hat einen Gradienten pro Gewicht.

weights: Die Startgewichte.

learning_rate, beta1, beta2, epsilon: Die Hyperparameter von Adam (üblich sind 0.001, 0.9, 0.999 und 0.00000001).

Ausgabe

Gib die Gewichte nach allen Schritten zurück.

Einschränkungen

0 ≤ Schritte ≤ 1.000, 1 ≤ Gewichte ≤ 100

0 < learning_rate ≤ 1, 0 ≤ beta1, beta2 < 1, 0 < epsilon ≤ 0.001

-100 ≤ jeder Wert ≤ 100

Beispiele

Beispiel 1
Eingabe:
beta1 = 0.9
beta2 = 0.999
epsilon = 1.0e-08
weights = [1.0]
gradients = [
    [2.0]
]
learning_rate = 0.1

Erwartete Ausgabe:
expected = [0.9]
Eingabe:
double beta1 = 0.9;
double beta2 = 0.999;
double epsilon = 1.0e-08;
std::vector<double> weights = {1.0};
std::vector<std::vector<double>> gradients = {
    {2.0}
};
double learning_rate = 0.1;

Erwartete Ausgabe:
std::vector<double> expected = {0.9};
Eingabe:
double beta1 = 0.9;
double beta2 = 0.999;
double epsilon = 1.0e-08;
double[] weights = new double[] {1.0};
double[][] gradients = new double[][] {
    new double[] {2.0}
};
double learning_rate = 0.1;

Erwartete Ausgabe:
double[] expected = new double[] {0.9};

Erläuterung

m = 0.1 × 2 = 0.2 und v = 0.001 × 4 = 0.004. Die Bias-Korrektur ergibt m̂ = 0.2 / 0.1 = 2 und v̂ = 0.004 / 0.001 = 4, also ist der Schritt 0.1 × 2 / √4 = 0.1: w = 0.9. Im ersten Schritt bewegt Adam jedes Gewicht ungefähr um die Lernrate, unabhängig von der Größe des Gradienten.

Beispiel 2
Eingabe:
beta1 = 0.9
beta2 = 0.999
epsilon = 1.0e-08
weights = [0.0, 0.0]
gradients = [
    [100.0, 0.01]
]
learning_rate = 0.01

Erwartete Ausgabe:
expected = [-0.01, -0.01]
Eingabe:
double beta1 = 0.9;
double beta2 = 0.999;
double epsilon = 1.0e-08;
std::vector<double> weights = {0.0, 0.0};
std::vector<std::vector<double>> gradients = {
    {100.0, 0.01}
};
double learning_rate = 0.01;

Erwartete Ausgabe:
std::vector<double> expected = {-0.01, -0.01};
Eingabe:
double beta1 = 0.9;
double beta2 = 0.999;
double epsilon = 1.0e-08;
double[] weights = new double[] {0.0, 0.0};
double[][] gradients = new double[][] {
    new double[] {100.0, 0.01}
};
double learning_rate = 0.01;

Erwartete Ausgabe:
double[] expected = new double[] {-0.01, -0.01};

Erläuterung

Die Gradienten unterscheiden sich um den Faktor 10.000, trotzdem bewegen sich beide Gewichte um etwa 0.01, auf [-0.01, -0.01]: Adam skaliert jeden Schritt mit der Größe des jeweiligen Gradienten.

So gehst du vor

Versuch es zuerst allein und öffne dann einen Hinweis nach dem anderen.

Hinweis 1

Verfolge pro Gewicht zwei gleitende Mittelwerte: einen für die Gradientenrichtung und einen für seine quadrierte Größe.

Hinweis 2

Wende die Bias-Korrektur mit der aktuellen Schrittzahl an, bevor du durch den Wurzelterm teilst.

Hinweis 3

Achte im Nenner auf epsilon, denn es verhindert eine Division durch null und verändert das finale Update leicht.

Erwartete Komplexität

Zeit O(s × w), zusätzlicher Speicher O(w)

Referenzen

Diese Aufgabe wurde für CodeUtility angepasst. Beachte die oben genannten Vorgaben und Einschränkungen.

Von anderen lernen

Community-Lösungen

Noch keine veröffentlichten Lösungen. Löse die Aufgabe und teile als Erster eine Lösung.