影片狀態:錄影需登入或課程授權。 本文依公開投影片與作業整理,數值例子為本站補充,不是課堂逐字稿。
知道反向傳播用鏈式法則,還不等於能寫出正確的訓練迴圈。這篇用一個能手算到底的小模型,讓你核對 tensor、loss、梯度與更新各自扮演的角色。它是本站自擬的先修練習,不是官方 HW0 的題目或解答。官方課表連到 Colab handout;本文不假裝取得其所有題目與評分標準。
先讀 RNN 篇的梯度路徑。實作需要 Python 與 PyTorch;以下只用 CPU,沒有 GPU、下載資料或大型模型的需求。你應該在自己的環境確認套件可匯入,再把程式存成 autodiff_toy.py 執行。
先把目標寫清楚
自擬資料是 x=2、目標 y=5,模型預測 ŷ=wx+b。初始 w=1、b=0,因此 ŷ=2。使用 L=(ŷ−y)²/2,得到 L=4.5。除以二隻是讓導數簡單,並不改變最小值所在位置。
令 r=ŷ−y=−3。鏈式法則給 ∂L/∂w=r×x=−6,∂L/∂b=r=−3。學習率 0.1 的梯度下降更新為 w'=1−0.1×(−6)=1.6,b'=0−0.1×(−3)=0.3。新預測為 3.5,新 loss 為 1.125。數值下降支援這次更新方向正確,但一筆資料不能決定對其他輸入是否泛化。
用 autograd 核對同一件事
import torch
w = torch.tensor(1.0, requires_grad=True)
b = torch.tensor(0.0, requires_grad=True)
x = torch.tensor(2.0)
y = torch.tensor(5.0)
pred = w * x + b
loss = 0.5 * (pred - y).square()
loss.backward()
print(loss.item(), w.grad.item(), b.grad.item())
with torch.no_grad():
w -= 0.1 * w.grad
b -= 0.1 * b.grad
w.grad = None
b.grad = None
new_loss = 0.5 * (w * x + b - y).square()
print(w.item(), b.item(), new_loss.item())
預期第一行近似 4.5 -6.0 -3.0,第二行近似 1.6 0.3 1.125;浮點數最後幾位可有誤差。requires_grad 告訴框架要追蹤參數的導數;backward 沿著 loss 的運算圖計算它們。no_grad 讓參數更新不成為下一輪要微分的運算,清除 grad 則避免上一輪殘留。
這裡清除梯度放在更新後;慣用 optimizer 迴圈通常把 zero_grad 放在下一輪 forward 前。兩者都必須確保每輪要用的梯度範圍明確。刻意做 gradient accumulation 是另一種設計,不能跟忘記清梯度混為一談。
batch 改變的是哪些維度
把資料改成 x=[1,2]、y=[3,5],初始參數仍是 1 與 0。預測為 [1,2],殘差為 [−2,−3]。若 L 是每筆半平方誤差的平均,L=(4+9)/4=3.25,∂L/∂w=(−2×1−3×2)/2=−4,∂L/∂b=(−2−3)/2=−2.5。
使用向量時,模型參數仍是共用的一個 w 與 b,並不是兩筆資料各訓練一套。若把 mean 改成 sum,loss 與梯度都變成兩倍;同一學習率因此有不同更新幅度。報告 loss 時必須說清楚 reduction,否則跨 batch 大小比較可能是在比較不同尺度。
另一種危險是預測形狀 [B,1]、目標形狀 [B]。兩者相減可能 broadcast 成 [B,B],每個預測跟每個目標都配對。程式能跑不是資料流正確的證據;在計算 loss 前檢查形狀,是這種錯誤最便宜的防線。
從一輪變成訓練迴圈
每輪的順序是清梯度、forward、計算 scalar loss、backward、更新參數。重新 forward 很重要:上一輪的圖代表舊參數下的運算,不能在更新後反覆把同一張圖當成新一輪訓練。通常也不需要用 retain_graph=True 掩蓋圖重用問題。
模型有 dropout 或 batch normalization 時,train/eval 狀態會改變 forward 行為;eval() 並不等同 no_grad()。前者切換層的模式,後者控制是否記錄梯度。在這個只有 scalar 參數的例子裡看不出差別,換到作業 1 就會有影響。
變式練習與答案
若單筆例子把 loss 改成沒有除以二的平方誤差,梯度是甚麼?答案是 w 的 −12 與 b 的 −6。若仍用學習率 0.1,更新後 w=2.2、b=0.6,預測恰好為 5、loss 為零。這只是本例的數值巧合,不代表放大 loss 總能一步收斂。
若同一張圖在沒有清 grad 的情況下反向傳播兩次,梯度會怎樣?在允許保留圖的前提下會相加成 −12 與 −6;一般直接第二次 backward 會因圖已釋放而報錯。能分清「梯度累加」與「圖是否仍存在」,才不會用錯補救方式。
接下來到 causal attention 追張量形狀,作業 1 再把這套檢查擴成完整神經網路。官方作業的提交方式與 AI 使用規範仍以當學期 course materials 為準。
課程影片來源
官方錄影入口位於 SCS Panopto。匿名資料夾未載入並提示登入;這表示未取得公開播放內容,不代表沒有錄影。原音與字幕須依課程授權存取。
參考資料
Loading...