နားလည်ထားရမယ့် အချက်
Classification model တစ်ခုသည် image တစ်ခုလုံးအတွက် class score vector တစ်ခုတည်း (shape: num_classes) ထုတ်ပေးပြီး, 'ဒီ image ထဲမှာ ဘာရှိသလဲ' ဆိုတဲ့ single question ကိုသာ ဖြေဆိုသည်။ Semantic segmentation ကတော့ ပိုကျယ်ပြန့်သော question ကို ဖြေဆိုသည် — 'pixel တစ်ခုချင်းစီသည် ဘယ် class ထဲ ပါဝင်သလဲ'။ ဒါကြောင့် segmentation model ၏ output သည် single vector မဟုတ်တော့ဘဲ image ရဲ့ spatial dimension (height, width) ကို ထိန်းသိမ်းထားသော shape (batch, num_classes, H, W) ရှိတဲ့ tensor တစ်ခု ဖြစ်လာသည် — pixel position တစ်ခုစီတိုင်း independent-ဆန်သော class score set တစ်ခုစီ ရရှိသည်ဟု တွေးနိုင်သည်။
Pixel တစ်ခုစီအတွက် final predicted class ကို ရအောင်, class dimension (dim=1) အလိုက် argmax လုပ်လိုက်ရုံသာဖြစ်သည် — ဒီအချိန်မှာ num_classes dimension ကို 'အမြင့်ဆုံး score ရှိတဲ့ class index' တစ်ခုတည်းအဖြစ် collapse ချလိုက်ခြင်းဖြစ်သည်။ ရလဒ်အနေနဲ့ shape (batch, H, W) ရှိသော integer tensor တစ်ခု ရရှိပြီး, pixel position (i, j) တစ်ခုစီရဲ့ value သည် ထို pixel အတွက် predicted class index ကို ကိုယ်စားပြုသည်။ ဒီ output ကို visualize လုပ်ရင် image တစ်ခုလုံးကို class-color-coded region များအဖြစ် ခွဲထားတဲ့ 'mask' တစ်ခုအဖြစ် မြင်ရမည် — classification ရဲ့ 'တစ်ခုတည်းသောlabel' နှင့် လုံးဝ ဆန့်ကျင်ဘက် ဖြစ်သည်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Tutorial Platform တွင် user upload လုပ်သော lesson diagram image များကို screen-reader users များအတွက် alt-text အလိုအလျောက် ဖန်တီးပေးရန် diagram ၏ 'text region' နှင့် 'illustration/diagram region' ကို ခွဲခြား segment လုပ်ပေးမည့် feature တစ်ခု စဉ်းစားနေသည်ဆိုပါစို့။ ဒီလို per-pixel segmentation output ကို ရရှိထားမှသာ text region ကို OCR pipeline သို့ ပို့ပြီး, illustration region ကို visual description pipeline သို့ သီးခြားပို့နိုင်မည်ဖြစ်သည်။
အတူတူ စမ်းရေးကြည့်မယ်
import torch
batch_size, num_classes, height, width = 2, 5, 8, 8
# Fake per-pixel class scores from a segmentation model
segmentation_output = torch.randn(batch_size, num_classes, height, width)
# Collapse the class dimension to get the predicted class per pixel
predicted_mask = segmentation_output.argmax(dim=1)
print(f"segmentation_output shape: {tuple(segmentation_output.shape)}")
print(f"predicted_mask shape: {tuple(predicted_mask.shape)}")
print(f"predicted_mask dtype: {predicted_mask.dtype}")
'segmentation_output shape: (2, 5, 8, 8)', 'predicted_mask shape: (2, 8, 8)', 'predicted_mask dtype: torch.int64' ဟု line သုံးကြောင်း print ထုတ်မည် — argmax သည် class dimension (dim=1, size 5) ကို ဖယ်ရှားလိုက်ပြီး integer index tensor ကို ပြန်ပေးသည်။၅ မိနစ် စမ်းကြည့်
predicted_mask ရှိ pixel များထဲမှ class index 2 ရှိသော pixel အရေအတွက်ကို (predicted_mask == 2).sum() ဖြင့် တွက်ချက်ပြီး print ထုတ်ကြည့်ပါ၊ ပြီးလျှင် num_classes ကို 5 မှ 20 သို့ ပြောင်းပြီး shape များ ဘယ်လို ပြောင်းလဲသွားသလဲ observe လုပ်ပါ။
သတိလေးတစ်ချက်
argmax(dim=1) အစား argmax(dim=0) ကို မှားသုံးမိလျှင် batch dimension ကို collapse ချမိသွားပြီး output shape (num_classes, H, W) ဖြစ်သွားကာ per-pixel class map အနေနဲ့ လုံးဝ အဓိပ္ပာယ်မရှိတော့ပါ။
predicted_mask (dtype int64) ကို cross-entropy loss target အဖြစ် တိုက်ရိုက် သုံးနေစဉ် ground-truth mask ကို float dtype ဖြင့် ချန်ထားခဲ့ရင် nn.CrossEntropyLoss သည် dtype mismatch error တက်နိုင်သည်။
Wikipedia — Image segmentation — Computer Vision