နားလည်ထားရမယ့် အချက်
Contrastive self-supervised learning က computer vision မှာ ကြုံနေရတဲ့ label ပြဿနာကို ဖြေရှင်းပေးပါတယ်။ လူတွေက ပုံတွေကို bounding box ဆွဲတာ၊ caption ရေးတာလုပ်ဖို့ နှေးပြီး ကုန်ကျစရိတ်များပေမယ့် ကွန်ပျူတာအတွက်တော့ ပုံတစ်ပုံတည်းရဲ့ မတူညီတဲ့ version နှစ်မျိုးကို ဖန်တီးဖို့က အလွန်လွယ်ကူပါတယ်။ ဒီနည်းလမ်းက အဲဒီအချက်ကနေတိုက်ရိုက် training signal ကို ဖန်တီးပြီး human annotation ကို အားမကိုးတော့ပါဘူး။ Label မရှိတဲ့ ပုံတစ်ပုံကို ယူပြီး independent random augmentation နှစ်မျိုး (crop တစ်ခု၊ color shift တစ်ခု၊ flip တစ်ခု) သုံးလိုက်ရင် ကြည့်ရတာ ကွဲပြားပေမယ့် အနှစ်သာရအတူတူပါတဲ့ view နှစ်ခု ရရှိပါတယ်။ Shared encoder တစ်ခုက ဒီ view နှစ်ခုစလုံးကို embedding vector အဖြစ် process လုပ်ပြီး model ကမြင်ရတဲ့ 'label' တစ်ခုတည်းက ဒီ embedding နှစ်ခုဟာ မူရင်းပုံတစ်ပုံတည်းကနေ လာတယ်ဆိုတဲ့ ရိုးရှင်းတဲ့အချက်ပါပဲ။ ဒါကြောင့် ၎င်းတို့ embedding space ထဲမှာ နီးကပ်နေသင့်ပြီး၊ မဆိုင်ရာပုံတစ်ပုံရဲ့ embedding ကတော့ ဝေးကွာနေသင့်ပါတယ်။ ပုံထဲမှာ ဘာပါလဲဆိုတာ လူဆုံးဖြတ်ပေးခြင်းမရှိဘဲ supervision အားလုံးဟာ data ရဲ့ ကိုယ်ပိုင် structure ကနေ self-generated ဖြစ်ပါတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Tutorial Platform ပေါ်မှာ user တွေ upload လုပ်တဲ့ lesson screenshot နဲ့ diagram ပုံပေါင်း ထောင်ချီရှိပေမယ့် ဘယ်ပုံနှစ်ပုံက near-duplicate ဖြစ်နေလဲဆိုတာ manually label လုပ်ဖို့ လက်တွေ့မမှန်နိုင်ပါဘူး။ Content moderation team က self-supervised encoder တစ်ခုကို လွတ်လပ်တဲ့ ပုံအများအပြားနဲ့ train လုပ်ထားပြီး၊ upload အသစ်တစ်ခုစီရဲ့ embedding ကို ရှိပြီးသား ပုံတွေရဲ့ embedding တွေနဲ့ cosine similarity တိုင်းတာနိုင်ပါတယ်။ Similarity score က threshold တစ်ခုထက်မြင့်ရင် ပုံနှစ်ပုံကို duplicate ဖြစ်နိုင်ချေရှိတယ်လို့ ဖြတ်ပြီး review queue ထဲ ပို့နိုင်ပါတယ် — 'duplicate/not duplicate' လို့ label ထားတဲ့ dataset တစ်ခုမှ မလိုအပ်ဘဲပါ။
အတူတူ စမ်းရေးကြည့်မယ်
import torch
import torch.nn as nn
import torch.nn.functional as F
import torchvision.transforms as T
torch.manual_seed(0)
# a single synthetic "image" - pretend it's a 32x32 RGB photo
image = torch.rand(3, 32, 32)
# two independent augmentation pipelines applied to the SAME image
augment_1 = T.Compose([
T.RandomHorizontalFlip(p=1.0),
T.RandomErasing(p=1.0, scale=(0.05, 0.15)),
])
augment_2 = T.Compose([
T.ColorJitter(brightness=0.4, contrast=0.4),
T.RandomRotation(degrees=15),
])
view_1 = augment_1(image)
view_2 = augment_2(image)
class SmallEncoder(nn.Module):
def __init__(self):
super().__init__()
self.conv = nn.Sequential(
nn.Conv2d(3, 8, kernel_size=3, stride=2, padding=1), # 32x32 -> 16x16
nn.ReLU(),
nn.Conv2d(8, 16, kernel_size=3, stride=2, padding=1), # 16x16 -> 8x8
nn.ReLU(),
nn.AdaptiveAvgPool2d(1),
)
self.project = nn.Linear(16, 8)
def forward(self, x):
features = self.conv(x).flatten(1) # (batch, 16)
return self.project(features) # (batch, 8) embedding
encoder = SmallEncoder()
# add a batch dimension: (1, 3, 32, 32) -> encoder -> (1, 8)
embedding_1 = encoder(view_1.unsqueeze(0))
embedding_2 = encoder(view_2.unsqueeze(0))
similarity = F.cosine_similarity(embedding_1, embedding_2)
print("Embedding 1 shape:", embedding_1.shape)
print("Embedding 2 shape:", embedding_2.shape)
print("Cosine similarity between the two views:", similarity.item())
Embedding 1 shape: torch.Size([1, 8]) နဲ့ Embedding 2 shape: torch.Size([1, 8]) ကို print ထုတ်ပါတယ်။ Cosine similarity တန်ဖိုးကတော့ torch.manual_seed(0) သတ်မှတ်ထားလို့ run တိုင်း တူညီတဲ့ float တစ်ခု ထွက်ပေမယ့် encoder ကို train မလုပ်ရသေးဘဲ random weight ဖြင့်ပဲ ရှိနေတဲ့အတွက် -1.0 နဲ့ 1.0 ကြားက value တစ်ခုသာ ဖြစ်ပြီး 1.0 ကို နီးစပ်ဖို့ အာမခံချက်မရှိပါဘူး (untrained encoder ဖြစ်လို့ semantic similarity ကို တကယ်တမ်း ဖမ်းယူထားတာ မဟုတ်သေးပါ)။၅ မိနစ် စမ်းကြည့်
Code ကို ပြောင်းလဲပြီး လုံးဝမတူညီတဲ့ synthetic image ဒုတိယတစ်ပုံ (image_2 = torch.rand(3, 32, 32)) ဖန်တီးကာ ၎င်းရဲ့ view တစ်ခုကို encoder ကနေ ဖြတ်ပါ။ ပြီးရင် original image ရဲ့ view တစ်ခုနဲ့ image_2 ရဲ့ view ကြား cosine similarity ကို တွက်ချက်ပြီး original image ရဲ့ view နှစ်ခုကြား similarity နဲ့ နှိုင်းယှဉ်ကြည့်ပါ — untrained encoder မှာတောင် ဘယ် pattern မျိုးမြင်ရနိုင်လဲ စဉ်းစားပါ။
သတိလေးတစ်ချက်
Augmentation တွေကို လွန်ကဲစွာသုံးမိရင် (ဥပမာ RandomErasing ရဲ့ scale ကို အလွန်ကြီးထားခြင်း) view နှစ်ခုက အနှစ်သာရ တူညီမှုကို ဆုံးရှုံးသွားပြီး encoder က object ကို မထောက်ခံဘဲ noise pattern ကိုသာ match လုပ်ဖို့ သင်ယူသွားနိုင်ပါတယ်။
Negative pair (မတူညီတဲ့ ပုံများ) လုံးဝမပါဘဲ positive pair တစ်ခုတည်းနဲ့သာ train လုပ်ရင် encoder က content ကို လျစ်လျူရှုပြီး embedding အားလုံးကို constant vector တစ်ခုတည်းဆီ map လုပ်နိုင်ပါတယ် (representation collapse) — ဒီလိုဖြစ်ရင် cosine similarity က ဘာပုံနှစ်ပုံအတွက်မဆို 1.0 နီးပါးအမြဲထွက်ပါလိမ့်မယ်။
Wikipedia — Self-supervised learning — Computer Vision