နားလည်ထားရမယ့် အချက်
PyTorch ရဲ့ `nn.Module` က network တိုင်းရဲ့ base class ဖြစ်တယ်—layer တွေကို `__init__` ထဲမှာ attribute အနေနဲ့ ကြေညာပြီး၊ data က ဘယ်လိုစီးဆင်းမလဲဆိုတာကို `forward()` ထဲမှာ ဖော်ပြရတယ်။ `nn.Linear(in_features, out_features)` က အသုံးအများဆုံး layer ဖြစ်တယ်—`x @ W^T + b` ကို တွက်တဲ့ fully-connected layer ဖြစ်ပြီး W နဲ့ b ကတော့ PyTorch က auto initialize လုပ်ပေးတဲ့ learnable parameter တွေပါ။ ဒီ computation အတူတူကို weight tensor တွေကို manual create လုပ်ပြီး raw tensor operation အနေနဲ့ ရေးလို့ရပေမယ့်၊ `nn.Module` ကို subclass လုပ်တာက raw tensor math မှာ မပါတဲ့ အကျိုးကျေးဇူး အများကြီးရရှိစေတယ်—declare လုပ်ထားတဲ့ parameter တိုင်းကို PyTorch က auto discover လုပ်ပေးတယ် (ဒါကြောင့် `model.parameters()` က tensor တွေကို လက်ဖြင့် စာရင်းပြုစုစရာမလိုဘဲ update လိုအပ်တာအားလုံးကို optimizer ဆီ ပေးအပ်နိုင်တယ်)၊ `model.to(device)` တစ်ခေါ်တည်းနဲ့ parameter အားလုံးကို GPU ဆီ ရွှေ့နိုင်တယ်၊ `torch.save`/`load_state_dict` က weight အားလုံး save/restore လုပ်တာကို ကိုင်တွယ်ပေးတယ်၊ ပြီးတော့ module တွေက compose လုပ်နိုင်တယ်—network ကြီးတစ်ခုက network သေးတွေကို sub-layer အနေနဲ့ ပါဝင်စေနိုင်တယ်။ ဒီ composability ကြောင့်ပဲ layer နှစ်ခုပါတဲ့ classifier ကနေ block များစွာပါတဲ့ transformer အထိ architecture အစစ်တွေဟာ pattern အခြေခံတစ်ခုတည်းကနေ တည်ဆောက်ထားခြင်း ဖြစ်ပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Tutorial Platform က နောက်ဆုံးမှာ ထုတ်လွှင့်မယ့် sentiment classifier—feedback comment ရဲ့ numeric representation ကိုယူပြီး positive/negative ခန့်မှန်းတာ—ဟာ nn.Module အတိအကျပါပဲ—comment ရဲ့ feature vector နဲ့ ကိုက်ညီအောင် size ချိန်ထားတဲ့ input layer၊ nn.Linear hidden layer တစ်ခု ဒါမှမဟုတ် တစ်ခုထက်ပိုပြီး၊ score တစ်ခု ထုတ်ပေးမယ့် output layer တို့ ပါဝင်တယ်။ ဒီလို define လုပ်ထားတာက class အတူတူကို နောက်ပိုင်းမှာ GPU ဆီရွှေ့တာ၊ train လုပ်ပြီးရင် save လုပ်တာ၊ architecture ကြီးတစ်ခု (နောက် chapter တွေထဲက CNN ဒါမှမဟုတ် transformer) နဲ့ ပြောင်းလဲသုံးတာတွေကို platform ရဲ့ ကျန်တဲ့ training/serving code က ခေါ်သုံးပုံ မပြောင်းလဲစေဘဲ လုပ်ဆောင်နိုင်စေတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
import torch
import torch.nn as nn
class TinyNet(nn.Module):
def __init__(self):
super().__init__()
self.layer1 = nn.Linear(10, 5) # 10 input features -> 5 hidden units
self.layer2 = nn.Linear(5, 1) # 5 hidden units -> 1 output
def forward(self, x):
x = torch.relu(self.layer1(x))
return self.layer2(x)
model = TinyNet()
sample_input = torch.randn(4, 10) # batch of 4 examples, 10 features each
output = model(sample_input)
print("Output shape:", output.shape)
print("Number of parameters:", sum(p.numel() for p in model.parameters()))Output shape: torch.Size([4, 1]) ကို print ထုတ်တယ်—batch 4 ခုစီရဲ့ example တစ်ခုချင်းအတွက် prediction တစ်ခုစီပေါ့—ပြီးတော့ Number of parameters: 61 (layer1 ရဲ့ weight+bias ကနေ 55, layer2 ကနေ 6) ကိုပါ print ထုတ်ပါတယ်။၅ မိနစ် စမ်းကြည့်
TinyNet ထဲကို nn.Linear layer တတိယတစ်ခု ထပ်ထည့်ပါ (ဥပမာ 5 -> 5 -> 1 ကို 5 -> 3 -> 1 အဖြစ် ပြောင်းပါ)၊ forward pass ကို ပြန် run ပြီး parameter count စုစုပေါင်း ဘယ်လိုပြောင်းလဲသွားလဲ print ထုတ်ကြည့်ပါ။
သတိလေးတစ်ချက်
Layer တွေ assign မလုပ်ခင် super().__init__() ခေါ်ဖို့ မေ့တာ—nn.Module က internal bookkeeping စနစ်တကျ setup လုပ်ဖို့ ကိုယ်ပိုင် __init__ ကို အားထားနေတယ်၊ ကျော်သွားရင် layer တွေက model.parameters() ထဲမှာ တိတ်တိတ်ဆိတ်ဆိတ် ပေါ်လာမှာ မဟုတ်ဘူး။
Layer ချင်း input feature dimension ကို ရောထွေးမိတာ (ဥပမာ layer2 က layer1 ရဲ့ output size နဲ့ မကိုက်ညီတဲ့ input size ကို မျှော်လင့်နေတာ)—model define လုပ်တဲ့အချိန်မှာ error မတက်ဘဲ forward pass ပထမဆုံးအကြိမ် run မှ shape-mismatch RuntimeError တက်တယ်။
PyTorch Docs — Build the Neural Network — Deep Learning