समस्या
Adam हर वज़न के लिए दो मूविंग एवरेज रखता है, ग्रेडिएंट (m) का और ग्रेडिएंट के वर्ग (v) का, और इनसे हर वज़न को उसका अपना कदम आकार देता है।
हर वज़न के लिए m = 0 और v = 0 से शुरू करें। ग्रेडिएंट g वाले हर कदम t = 1, 2, 3, … के लिए:
- m ← beta1 × m + (1 - beta1) × g
- v ← beta2 × v + (1 - beta2) × g²
- m̂ = m / (1 - beta1ᵗ) और v̂ = v / (1 - beta2ᵗ) (बायस करेक्शन)
- w ← w - learning_rate × m̂ / (√v̂ + epsilon)
adam_steps(gradients, weights, learning_rate, beta1, beta2, epsilon) लागू करें, gradients की हर पंक्ति के लिए क्रम से एक अपडेट करते हुए।
इनपुट
gradients: हर कदम के लिए एक पंक्ति; हर पंक्ति में हर वज़न के लिए एक ग्रेडिएंट।
weights: शुरुआती वज़न।
learning_rate, beta1, beta2, epsilon: Adam के हाइपरपैरामीटर (आम मान 0.001, 0.9, 0.999 और 0.00000001 हैं)।
आउटपुट
सभी कदमों के बाद वज़न लौटाएँ।
सीमाएँ
0 ≤ कदम ≤ 1,000, 1 ≤ वज़न ≤ 100
0 < learning_rate ≤ 1, 0 ≤ beta1, beta2 < 1, 0 < epsilon ≤ 0.001
-100 ≤ हर मान ≤ 100
उदाहरण
इनपुट:
beta1 = 0.9
beta2 = 0.999
epsilon = 1.0e-08
weights = [1.0]
gradients = [
[2.0]
]
learning_rate = 0.1
अपेक्षित आउटपुट:
expected = [0.9]
इनपुट:
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;
अपेक्षित आउटपुट:
std::vector<double> expected = {0.9};
इनपुट:
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;
अपेक्षित आउटपुट:
double[] expected = new double[] {0.9};
व्याख्या
m = 0.1 × 2 = 0.2 और v = 0.001 × 4 = 0.004। बायस करेक्शन से m̂ = 0.2 / 0.1 = 2 और v̂ = 0.004 / 0.001 = 4 मिलता है, इसलिए कदम 0.1 × 2 / √4 = 0.1 है: w = 0.9। पहले कदम पर Adam हर वज़न को लगभग learning rate जितना खिसकाता है, ग्रेडिएंट का आकार कुछ भी हो।
इनपुट:
beta1 = 0.9
beta2 = 0.999
epsilon = 1.0e-08
weights = [0.0, 0.0]
gradients = [
[100.0, 0.01]
]
learning_rate = 0.01
अपेक्षित आउटपुट:
expected = [-0.01, -0.01]
इनपुट:
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;
अपेक्षित आउटपुट:
std::vector<double> expected = {-0.01, -0.01};
इनपुट:
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;
अपेक्षित आउटपुट:
double[] expected = new double[] {-0.01, -0.01};
व्याख्या
ग्रेडिएंट में 10,000 गुना का अंतर है, फिर भी दोनों वज़न लगभग 0.01 खिसककर [-0.01, -0.01] हो जाते हैं: Adam हर कदम को उसके अपने ग्रेडिएंट के आकार से स्केल करता है।
संदर्भ
यह चुनौती CodeUtility के लिए अनुकूलित की गई है। ऊपर दिए गए स्टेटमेंट और सीमाओं का पालन करें।