နားလည်ထားရမယ့် အချက်
PyTorch training loop တစ်ခုက error မတက်ဘဲ run ရသော်လည်း loss ကျမလာဘူးဆိုရင် ခန့်မှန်းချက်နဲ့စမ်းနေမယ့်အစား စနစ်တကျ checklist အစီအစဉ်အတိုင်း စစ်ဆေးသင့်ပါတယ်။ Check တစ်ခုစီက error အမျိုးအစားတစ်ခုလုံးကို ဖယ်ရှားပေးနိုင်လို့ပါ။ ပထမဆုံး — iteration တိုင်းမှာ backward() မခေါ်ခင် optimizer.zero_grad() ကို ခေါ်ထားလား? Gradient တွေဟာ default အနေနဲ့ စုပေါင်းသွားတတ်လို့ zero_grad() ချန်ထားခဲ့ရင် batch တွေအကြား gradient တွေ တိတ်တဆိတ် ပေါင်းလာပြီး update direction ကို မှားစေပါတယ်။ ဒုတိယ — optimizer.step() မခေါ်ခင် loss.backward() ကို တကယ်ခေါ်ထားလား? မခေါ်ထားရင် .grad ဟာ ယခင်တန်ဖိုး (များသောအားဖြင့် None) မှာပဲ ကျန်နေပြီး step() က ဘာမှမလုပ်ဘဲ ဒါမှမဟုတ် အဟောင်း gradient ကိုပဲ ပြန်သုံးနေမှာပါ။ တတိယ — model ကို loop မစခင် .train() mode ထားလား၊ .eval() မှာ ချန်ထားခဲ့သလား? Eval mode ဟာ dropout နဲ့ batch-norm statistics တွေကို ရပ်တန့်ထားလို့ error မပြဘဲ learning capacity ကို ကန့်သတ်ပစ်ပါတယ်။ စတုတ္ထ — learning rate က များလွန်းနေလား (loss ခုန်နေလား NaN ဖြစ်နေလား) ဒါမှမဟုတ် နည်းလွန်းနေလား (epoch ရာချီပြီးတောင် loss နှေးနှေးလေးပဲ ကျနေလား)? ပဉ္စမ — loss function ဟာ task နဲ့ကိုက်ညီလား — classification အတွက် CrossEntropyLoss အစား MSELoss သုံးမိရင် network ကို လုံးဝမှားယွင်းတဲ့ objective ဆီ လေ့ကျင့်ပေးနေမှာဖြစ်ပြီး 'မသင်ယူဘူး' လို့ထင်ရပေမယ့် တကယ်က 'မှားနေတဲ့ဟာကို သင်ယူနေတာ' ဖြစ်ပါတယ်။ Hyperparameter မထိခင် အပေါ်ကနေအောက်ကို အစီအစဉ်တကျ စစ်ဆေးသင့်ပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Thuta Learning ရဲ့ engineering team က course-feedback စာသားထဲက စိတ်ပျက်နေတဲ့ learner တွေကို ဖော်ထုတ်ဖို့ sentiment classifier တစ်ခု release လုပ်လိုက်ပေမယ့် တစ်ပတ်ကြာ train လုပ်ပြီးတဲ့အထိ model က everything ကို neutral label တစ်ခုတည်း ခန့်မှန်းနေဆဲပါ။ Architecture မှားတယ်လို့ သတ်မှတ်ခင်မှာ ဒီ checklist အတိုင်း training script ကို audit လုပ်ဖို့ ခိုင်းထားပါတယ် — batch တိုင်းမှာ zero_grad() run နေလား၊ backward() က step() ရှေ့မှာ ခေါ်ထားလား၊ training လုပ်နေချိန် model က .train() mode ထဲမှာရှိပြီး validation အတွက်ပဲ .eval() ပြောင်းသုံးထားလား၊ learning rate က loss curve နဲ့ ကိုက်ညီလား စစ်ဆေးပါ၊ ပြီးတော့ class-index label ရိုးရိုးနဲ့ MSELoss မဟုတ်ဘဲ CrossEntropyLoss ပဲ တွဲသုံးထားလား သေချာအောင်လုပ်ပါ။ ဒီလို audit habit က model design ကို မထိခင် 'train လုပ်ပေမယ့် မသင်ယူဘူး' ဆိုတဲ့ bug အများစုကို ဖမ်းမိစေပါတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
import torch
import torch.nn as nn
import torch.optim as optim
class FeedbackClassifier(nn.Module):
def __init__(self):
super().__init__()
self.net = nn.Sequential(
nn.Linear(784, 128),
nn.ReLU(),
nn.Dropout(0.3),
nn.Linear(128, 10),
)
def forward(self, x):
return self.net(x)
model = FeedbackClassifier()
optimizer = optim.SGD(model.parameters(), lr=0.01)
criterion = nn.MSELoss()
model.eval() # set up before training starts
for epoch in range(10):
for inputs, labels in train_loader:
inputs = inputs.view(inputs.size(0), -1)
outputs = model(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f"Epoch {epoch}: loss = {loss.item():.4f}")ရေးထားတဲ့အတိုင်း loop ကို run ရင် `Epoch 0: loss = 0.9987`, `Epoch 1: loss = 0.9991`, `Epoch 9: loss = 0.9979` စသဖြင့် ထွက်လာမှာဖြစ်ပြီး loss ဟာ တစ်ပါတည်း မရွေ့လျားသလို ဖြစ်နေမှာပါ — ဒါက လက္ခဏာပါ၊ အကြောင်းရင်း မဟုတ်သေးဘူး၊ အထက်က bug ရှိတဲ့ line တွေကသာ မူလ အကြောင်းရင်းပါ။၅ မိနစ် စမ်းကြည့်
အောက်က training loop ကို line တစ်ကြောင်းချင်း ဖတ်ပြီး planted bug အားလုံး (၃ ခုရှိတယ်) ကို ရှာထုတ်ပါ။ တစ်ခုချင်းစီအတွက် ဘာတန်ဖိုးက မှားနေသလဲ၊ ဘယ် update က တိတ်တဆိတ် မဖြစ်ဘဲကျန်နေသလဲ ရှင်းပြပြီး line တစ်ကြောင်းတည်းနဲ့ ဘယ်လိုပြင်ရမလဲ ရေးပါ။ ဒီ bug တွေထဲက ဘယ်တစ်ခုမှ Python exception မတက်တဲ့အကြောင်းရင်းနဲ့ တကယ့် run တစ်ခုမှာ 'loss မလှုပ်သလိုဖြစ်နေတာ' ပဲ တွေ့ရမယ့်အကြောင်းရင်းကိုပါ ရှင်းပြပါ။
သတိလေးတစ်ချက်
Crash မဖြစ်တဲ့ loop ဆိုတာ 'အများကြီးတော့ မှားမနေဘူး' လို့ ယူဆပြီး learning rate ကိုပဲ ပြင်နေတာ — တကယ့် bug က zero_grad() ပျောက်နေခြင်း ဒါမှမဟုတ် eval() mode မှာ ငြိနေခြင်း ဖြစ်နိုင်တယ်။
loss function, learning rate, model mode စတာတွေကို တစ်ပြိုင်နက်တည်း ကျပန်း ပြောင်းပြီး debug လုပ်တာ — ဘယ် fix က တကယ် အလုပ်ဖြစ်စေတယ်ဆိုတာ ခွဲခြားလို့ မရတော့ဘူး။
PyTorch Docs — Optimization — Deep Learning