Machine Learning › Deep learning เบื้องต้น

Gradient descent และ learning rate

ประมาณ 35 นาที

เป้าหมายของบท

  • คำนวณ loss gradient และอัปเดตพารามิเตอร์ด้วย gradient descent เอง
  • อธิบายผลของ learning rate (ช้า / ลงตัว / diverge)
  • รู้จัก ReLU / tanh / sigmoid และอ่าน loss_curve_ ของ MLP

โมเดลเรียนรู้ได้อย่างไร: ลดค่า loss ทีละก้าว

การเทรนโมเดล = หาพารามิเตอร์ที่ทำให้ loss (ความคลาดเคลื่อน) ต่ำที่สุด Gradient descent ทำโดยวนซ้ำ:

  1. คำนวณ loss จากข้อมูล
  2. หา gradient = ทิศทางที่ loss เพิ่มขึ้นเร็วที่สุด (อนุพันธ์ของ loss ต่อแต่ละพารามิเตอร์)
  3. ขยับพารามิเตอร์ สวนทิศ gradient ด้วยก้าวขนาด learning_rate: w ← w − lr × grad

ตัวอย่างเล็กที่สุด: จุดข้อมูล 5 จุดที่ y = 2x + 1 ให้โมเดล ŷ = w·x + b เริ่มที่ w = b = 0 และใช้ MSE เป็น loss

import numpy as np

x = np.array([0.0, 1.0, 2.0, 3.0, 4.0])
y = 2 * x + 1

w, b = 0.0, 0.0
pred = w * x + b
loss = np.mean((pred - y) ** 2)          # 33.0
grad_w = 2 * np.mean((pred - y) * x)     # -28.0
grad_b = 2 * np.mean(pred - y)           # -10.0
w -= 0.05 * grad_w                       # 1.4
b -= 0.05 * grad_b                       # 0.5

Learning rate: ก้าวเล็กเกินไป ช้า; ใหญ่เกินไป ระเบิด

วนซ้ำ 100 ก้าวด้วย learning rate ต่างกัน (ค่าจริงคือ w = 2, b = 1):

lr w b ผล
0.01 2.0512 0.8540 ยังไม่ถึง (ก้าวเล็ก)
0.05 2.0045 0.9872 ใกล้มาก
0.1 2.0002 0.9994 ลงตัว
0.25 ≈ −2.8×10³⁷ ≈ −9.7×10³⁶ diverge (ก้าวใหญ่จนกระโดดข้ามจุดต่ำสุดและห่างออกไปเรื่อยๆ)

Activation function ที่พบบ่อย

ฟังก์ชัน สูตร ช่วงเอาต์พุต ใช้ที่
ReLU max(0, z) [0, ∞) hidden layer (ค่าเริ่มต้น)
tanh (eᶻ − e⁻ᶻ)/(eᶻ + e⁻ᶻ) (−1, 1) hidden (แบบเก่ากว่า)
sigmoid 1/(1+e⁻ᶻ) (0, 1) output ของ binary classification

ใน MLPClassifier

  • learning_rate_init (ค่าเริ่มต้น 0.001) และ solver adam (ปรับก้าวอัตโนมัติ) — สำหรับข้อมูล scale แล้ว hidden (16,): lr 0.001 ใช้ครบ 200 รอบ, lr 0.01 และ 0.1 หยุดที่ ~96 และ ~95 รอบ (loss ไม่ลดพอ)
  • loss_curve_ เก็บ loss ของทุก epoch: เริ่ม 0.7329 → 0.565 ที่ 200 รอบ ลดลงโดยรวมแต่ ไม่จำเป็นต้องลดทุกรอบ (มี mini-batch ที่สุ่มมา)
  • loss บน train ลดลงเรื่อยๆ ไม่ได้แปลว่าโมเดลดีบนข้อมูลใหม่ — ดูบทถัดไป

ตัวอย่างแก้โจทย์

กด "ขั้นต่อไป" ทีละขั้น ลองรันและแก้โค้ดในแต่ละขั้นได้

gradient descent หนึ่งก้าว

คำนวณ loss gradient และอัปเดตพารามิเตอร์ด้วยมือ

  1. loss ที่ w = b = 0 คือ 33.0 และ gradient คือ (−28, −10)

    Python

learning rate ที่ต่างกัน

รัน gradient descent 100 ก้าวด้วย learning rate ต่างกัน

  1. lr 0.05 และ 0.1 เข้าใกล้ค่าจริง (w=2, b=1)

    Python

เติมช่องว่าง

แทน ___ ด้วยโค้ดที่ถูกต้อง แล้วกดตรวจคำตอบ

ยังไม่ได้ทำ

เติมสูตรอัปเดต: หนึ่งก้าวของ gradient descent ที่ lr = 0.05 จาก w = 0 (b = 0) เก็บ w ใหม่ไว้ใน w_new เติม ___ ให้ครบ

แบบฝึกท้ายบท

บทนี้จะนับว่าเสร็จเมื่อผ่านข้อพื้นฐานและประยุกต์ครบ ข้อท้าทายได้ดาวเพิ่ม

🟢 พื้นฐาน

🟢 พื้นฐานยังไม่ได้ทำ

คำนวณ MSE loss ของโมเดลเริ่มต้น w = 0, b = 0 (ŷ = w·x + b เทียบกับ y ที่ให้ไว้) เก็บไว้ในตัวแปร initial_loss

🟢 พื้นฐานยังไม่ได้ทำ

gradient ของ MSE ที่ w = 0, b = 0: grad_w = 2·mean((ŷ − y)·x) และ grad_b = 2·mean(ŷ − y) เก็บไว้ในตัวแปร grad_w, grad_b

🟢 พื้นฐานยังไม่ได้ทำ

อัปเดตหนึ่งก้าวด้วย lr = 0.05 จาก w = b = 0 เก็บ w ใหม่ไว้ใน w1 และ b ใหม่ไว้ใน b1

🟢 พื้นฐานยังไม่ได้ทำ

ใช้ gradient_descent ที่ให้ไว้กับ lr = 0.1 (100 ก้าว) เก็บ w และ b ที่ได้ (ปัด 4 ตำแหน่ง) ไว้ในตัวแปร w_final, b_final

🟡 ประยุกต์

🟡 ประยุกต์ยังไม่ได้ทำ

MSE สุดท้าย (หลัง 100 ก้าว) เมื่อใช้ lr = 0.01 และ lr = 0.05 กับ gradient_descent ที่ให้ไว้ ปัด 6 ตำแหน่ง เก็บไว้ในตัวแปร loss_001, loss_005

🟡 ประยุกต์ยังไม่ได้ทำ

ที่ lr = 0.25 gradient descent (100 ก้าว) diverge หรือไม่ — เก็บ True/False (พิจารณาว่า |w| มากกว่า 1e6) ไว้ในตัวแปร diverged และ lr = 0.1 ไว้ใน diverged_01

🟡 ประยุกต์ยังไม่ได้ทำ

ค่าของ activation ที่ z = 2.0: sigmoid, tanh และ ReLU ที่ z = −2.0 ปัด 4 ตำแหน่ง เก็บไว้ในตัวแปร sigmoid_2, tanh_2, relu_neg2

🔴 ท้าทาย

🔴 ท้าทายยังไม่ได้ทำ

fit MLP (16,) (max_iter=200, random_state=42) บน Z_train: loss_curve_ มีกี่ค่า (n_epochs), loss แรกและสุดท้าย (ปัด 4 ตำแหน่ง) เก็บไว้ใน first_loss, final_loss และจำนวนครั้งที่ loss เพิ่มขึ้นจากรอบก่อนหน้าไว้ใน n_increases

🔴 ท้าทายยังไม่ได้ทำ

fit MLP (16,) (max_iter=200, random_state=42) บน Z_train ด้วย learning_rate_init = 0.001, 0.01 และ 0.1 เก็บจำนวน iteration ที่ใช้จริง (n_iter_) ไว้ใน it_0001, it_001, it_01 ตามลำดับ

Quiz

1. gradient descent ขยับพารามิเตอร์ไปทางไหน
2. ในตัวอย่างบทนี้ lr = 0.25 ทำให้ w พุ่งไป ≈ −2.8×10³⁷ เกิดอะไรขึ้น
3. sigmoid เหมาะกับส่วนไหนของ MLP สำหรับ binary classification
4. loss_curve_ ลดลงเรื่อยๆ ตลอด 200 รอบ หมายความว่าอย่างไร

สรุป

  • gradient descent: w ← w − lr × gradient ทำซ้ำเพื่อลด loss
  • lr เล็กช้า, พอดีลงตัว, ใหญ่เกิน diverge (ตัวอย่าง lr 0.25 ระเบิดเป็น ~10³⁷)
  • ReLU สำหรับ hidden, sigmoid สำหรับ output ของ binary; loss_curve_ ลดลงบน train ไม่ได้การันตีผลบนข้อมูลใหม่

คำถามสัมภาษณ์

อธิบาย gradient descent และบทบาทของ learning rate

ทำซ้ำ: คำนวณ gradient ของ loss ต่อพารามิเตอร์ แล้วขยับพารามิเตอร์สวนทิศ gradient ด้วยก้าว learning rate ถ้า lr เล็กเกินจะช้า ถ้าใหญ่เกินจะข้ามจุดต่ำสุดหรือ diverge จึงมักใช้ lr ที่ปรับด้วย optimizer (เช่น Adam) และตรวจ loss curve

ถ้า loss ของโมเดลเพิ่มขึ้นหรือเป็น nan ระหว่างเทรน ควรตรวจอะไร

สงสัย learning rate สูงเกินไปก่อน (ลดลง), ตรวจว่า scale input แล้ว, ค่าที่มีปัญหา (NaN/inf ในข้อมูล), และ gradient ระเบิด จากนั้นลองเทรนบนข้อมูลเล็กมากๆ ให้ loss ลดจนเกือบ 0 เพื่อตรวจว่าโค้ดถูก