Thuta Learning
Deep Learning with PyTorch
IntermediateAIintermediate

Image Classifier တစ်ခု တည်ဆောက်ခြင်း

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Image Classifier တစ်ခု တည်ဆောက်ခြင်း concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • နမူနာ PyTorch code ကို ကိုယ်တိုင် run ပြီး output စစ်နိုင်ရန်
  • Tutorial Platform project နှင့် production scenario တွင် မှန်ကန်စွာအသုံးချနိုင်ရန်

နားလည်ထားရမယ့် အချက်

အလုပ်လုပ်တဲ့ image classifier တစ်ခုက almost always two-stage ပုံစံတူတူကိုပဲ လိုက်နာတယ် — Conv2d၊ activation၊ pooling layer တွေ အလှည့်ကျ ပါဝင်တဲ့ feature extractor တစ်ခုက raw image ကို learned feature set သေးသေးလေးတစ်ခုအဖြစ် တဖြည်းဖြည်း compress လုပ်ပေးပြီး၊ ပြီးရင် Linear layer တစ်ခု ဒါမှမဟုတ် နှစ်ခုပါတဲ့ classifier head တစ်ခုက ဒီ feature တွေကို class တစ်ခုချင်းစီအတွက် score (logit) အဖြစ် map လုပ်ပေးတယ်။ Feature extractor ရဲ့ အလုပ်ကတော့ representation ဖြစ်တယ် — raw pixel တွေကို abstract ဖြစ်ပြီး discriminative feature တွေအဖြစ် ပြောင်းပေးတာ — classifier head ရဲ့ အလုပ်ကတော့ decision ဖြစ်တယ် — ဒီ feature တွေကို နောက်ဆုံး ဆုံးဖြတ်ချက်အဖြစ် ပေါင်းစပ်ပေးတာ။ ဒီနှစ်ခုကြားမှာ `Flatten` step တစ်ခု ရှိတယ်၊ conv layer တွေက image တစ်ခုချင်းစီအတွက် multi-dimensional (channels, height, width) tensor ကို output ထုတ်ပေမဲ့ Linear layer တွေက sample တစ်ခုချင်းစီအတွက် flat vector ကို မျှော်လင့်ထားလို့ပါ။ Output layer မှာတော့ model အတွင်း activation function ကိုယ်ပိုင် မပါဘူး — raw logit၊ class တစ်ခုစီအတွက် တစ်ခုစီ ထုတ်ပေးပြီး loss function (ပုံမှန်အားဖြင့် cross-entropy) က training အတွင်း ဒီ logit တွေကို class probability အဖြစ် ပြောင်းဖို့ softmax ကို internal အနေနဲ့ apply လုပ်ပေးတယ်။ ဒီ feature-extractor-plus-head pattern တူတူကပဲ CNN သေးသေးလေးကနေ ယနေ့ vision model အကြီးဆုံးတွေအထိ scale ဖြစ်တယ်၊ stage တစ်ခုချင်းစီမှာ layer ပိုများပြီး ပိုတိုးတက်တဲ့ layer တွေ ထပ်ထည့်ရုံပါပဲ။

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Duplicate/low-quality lesson image detector ကို တည်ဆောက်ခြင်းက ဒီပုံစံအတိုင်းပဲ ဖစ်စည်းဆောက်ရတာဖြစ်တယ် — Conv2d+ReLU+MaxPool block နှစ်ခုလောက်က upload လုပ်ထားတဲ့ screenshot တစ်ခုချင်းစီကို texture၊ blur၊ layout cue တွေ ဖမ်းမိထားတဲ့ feature map သေးသေးလေးတစ်ခုအဖြစ် compress လုပ်ပေးပြီး၊ Flatten နဲ့ Linear layer တစ်ခု ဒါမှမဟုတ် နှစ်ခုက ဒါကို output category တစ်ခုချင်းစီ — 'sharp original'၊ 'blurry duplicate'၊ 'watermarked' — အတွက် score အဖြစ် ပြောင်းပေးတယ်။ Model တစ်ခုလုံးက `nn.Module` တစ်ခုတည်းသာ ဖြစ်နေတာကြောင့် platform က ဒါကို save လုပ်ပြီး image-upload pipeline ထဲ load လုပ်ကာ course author က screenshot အသစ်တစ်ခု upload လုပ်တဲ့ခဏတွင်း forward pass ကို run လုပ်ကာ published lesson ဆီ မရောက်ခင် low-quality ဒါမှမဟုတ် duplicate image တွေကို flag လုပ်နိုင်တယ်။

အတူတူ စမ်းရေးကြည့်မယ်

python
import torch
import torch.nn as nn

class SmallCNN(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.block1 = nn.Sequential(
            nn.Conv2d(3, 8, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
        )
        self.block2 = nn.Sequential(
            nn.Conv2d(8, 16, kernel_size=3, padding=1),
            nn.ReLU(),
            nn.MaxPool2d(2),
        )
        self.flatten = nn.Flatten()
        self.fc1 = nn.Linear(16 * 8 * 8, 32)
        self.fc2 = nn.Linear(32, num_classes)

    def forward(self, x):
        x = self.block1(x)   # 32x32 -> 16x16
        x = self.block2(x)   # 16x16 -> 8x8
        x = self.flatten(x)
        x = torch.relu(self.fc1(x))
        return self.fc2(x)

model = SmallCNN(num_classes=10)

# Fake batch of 4 RGB "images", 32x32 pixels
images = torch.randn(4, 3, 32, 32)
logits = model(images)
print("Output shape:", logits.shape)
You should see
`Output shape: torch.Size([4, 10])` ကို print ထုတ်တယ် — batch ထဲက image 4 ခုအတွက် class logit 10 ခုစီပါတဲ့ row တစ်ခုစီ ရရှိတယ်။

၅ မိနစ် စမ်းကြည့်

Forward pass ပြီးနောက် logit တွေအပေါ် `nn.Softmax(dim=1)` ကို ခေါ်ပြီး ရလဒ်ကို print ထုတ်ကြည့်ကာ row တစ်ခုချင်းစီရဲ့ ပေါင်းလဒ်က 1.0 ဖြစ်နေမှန်း အတည်ပြုပါ။

သတိလေးတစ်ချက်

Linear layer ရဲ့ input size ကို မှားထည့်ခြင်း (ဥပမာ feature map က တကယ်တော့ 8x8 ဖြစ်နေတဲ့အခါ `nn.Linear(16*16*16, 32)` လို့ ရေးမိတာ) — ဒါက flatten လုပ်ထားတဲ့ tensor size နဲ့ မကိုက်ညီတာကြောင့် forward pass ပထမဆုံးမှာပဲ matrix-shape mismatch error တက်လာတယ်။

Training အတွက် `nn.CrossEntropyLoss` သုံးမယ်ဆိုရင် model ရဲ့ forward pass ထဲမှာ `softmax` ကို ကြိုတင် apply လုပ်ခြင်း — ဒီ loss function က softmax ကို internal အနေနဲ့ အလိုအလျောက် apply လုပ်ပြီးသားဖြစ်လို့ နှစ်ကြိမ် apply လုပ်မိရင် gradient တွေ ပျက်စီးပြီး training ကို ထိခိုက်စေတယ်။

PyTorch Docs — Training a Classifier (CIFAR-10)Deep Learning

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Linear layer ရဲ့ input size ကို မှားထည့်ခြင်း (ဥပမာ feature map က တကယ်တော့ 8x8 ဖြစ်နေတဲ့အခါ `nn.Linear(16*16*16, 32)` လို့ ရေးမိတာ) — ဒါက flatten လုပ်ထားတဲ့ tensor size နဲ့ မကိုက်ညီတာကြောင့် forward pass ပထမဆုံးမှာပဲ matrix-shape mismatch error တက်လာတယ်။
  • Training အတွက် `nn.CrossEntropyLoss` သုံးမယ်ဆိုရင် model ရဲ့ forward pass ထဲမှာ `softmax` ကို ကြိုတင် apply လုပ်ခြင်း — ဒီ loss function က softmax ကို internal အနေနဲ့ အလိုအလျောက် apply လုပ်ပြီးသားဖြစ်လို့ နှစ်ကြိမ် apply လုပ်မိရင် gradient တွေ ပျက်စီးပြီး training ကို ထိခိုက်စေတယ်။
  • နမူနာ code ကို production system ပေါ် တိုက်ရိုက်မစမ်းဘဲ local/test environment တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

Forward pass ပြီးနောက် logit တွေအပေါ် `nn.Softmax(dim=1)` ကို ခေါ်ပြီး ရလဒ်ကို print ထုတ်ကြည့်ကာ row တစ်ခုချင်းစီရဲ့ ပေါင်းလဒ်က 1.0 ဖြစ်နေမှန်း အတည်ပြုပါ။

You'll know it worked when: `Output shape: torch.Size([4, 10])` ကို print ထုတ်တယ် — batch ထဲက image 4 ခုအတွက် class logit 10 ခုစီပါတဲ့ row တစ်ခုစီ ရရှိတယ်။

Image Classifier တစ်ခု တည်ဆောက်ခြင်း | Thuta Learning