โจทย์ทั้งหมด
ปานกลาง 0 ข้อที่แก้แล้ว อัตราผ่าน 0%

ตัวปรับค่า Adam

Implement Adam ตัวปรับค่ามาตรฐานของ deep learning ที่ใช้ค่าเฉลี่ยเคลื่อนที่และการแก้ความเอนเอียง

สิ่งที่คุณจะได้เรียนรู้

  • ติดตามค่าเฉลี่ยของโมเมนต์อันดับหนึ่งและสอง
  • แก้ความเอนเอียงในขั้นแรก ๆ
  • เขียนตัวปรับค่ามาตรฐานของ deep learning

โจทย์

Adam เก็บค่าเฉลี่ยเคลื่อนที่สองตัวต่อน้ำหนัก คือของ gradient (m) และของ gradient ยกกำลังสอง (v) แล้วใช้ค่าเหล่านี้กำหนดขนาดก้าวเฉพาะให้แต่ละน้ำหนัก

เริ่มด้วย m = 0 และ v = 0 สำหรับทุกน้ำหนัก สำหรับแต่ละก้าว t = 1, 2, 3, … ที่มี gradient g:

  1. m ← beta1 × m + (1 - beta1) × g
  2. v ← beta2 × v + (1 - beta2) × g²
  3. m̂ = m / (1 - beta1ᵗ) และ v̂ = v / (1 - beta2ᵗ) (การแก้ความเอนเอียง)
  4. w ← w - learning_rate × m̂ / (√v̂ + epsilon)

จง implement adam_steps(gradients, weights, learning_rate, beta1, beta2, epsilon) โดยอัปเดตหนึ่งครั้งต่อแถวของ gradients ตามลำดับ

อินพุต

gradients: หนึ่งแถวต่อก้าว แต่ละแถวมี gradient หนึ่งค่าต่อน้ำหนัก

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

ตัวอย่าง

ตัวอย่างที่ 1
อินพุต:
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 ไม่ว่า gradient จะใหญ่แค่ไหน

ตัวอย่างที่ 2
อินพุต:
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};

คำอธิบาย

Gradient ต่างกันถึง 10,000 เท่า แต่ทั้งสองน้ำหนักขยับประมาณ 0.01 ไปเป็น [-0.01, -0.01]: Adam ปรับสเกลแต่ละก้าวตามขนาดของ gradient ของตัวเอง

แหล่งอ้างอิง

โจทย์นี้ปรับให้เหมาะกับ CodeUtility กรุณาทำตามคำชี้แจงและข้อจำกัดด้านบน

เรียนรู้จากคนอื่น

แนวทางจากชุมชน

ยังไม่มีวิธีทำที่เผยแพร่ ลองแก้โจทย์นี้เพื่อแชร์วิธีแรก