နားလည်ထားရမယ့် အချက်
Linear (fully-connected) layer တွေကို ကြားထဲမှာ ဘာမှ မထည့်ဘဲ ဘယ်နှစ်ခုပဲ ထပ်ချထားထား၊ သင်္ချာအရ ရလဒ်က linear layer တစ်ခုတည်းနဲ့ အတူတူပဲ ဖြစ်သွားတယ် — matrix multiplication ကို ထပ်ခါထပ်ခါ လုပ်ရင်တောင် ရလဒ်က matrix multiplication တစ်ခုတည်းသာ ဖြစ်နေတာကြောင့်ပါ။ ဆိုလိုတာက layer တစ်ရာပါတဲ့ linear network တစ်ခုနဲ့ layer တစ်ခုပဲပါတဲ့ network တစ်ခုက expressive power အတူတူပဲရှိတယ် — ဘယ်လောက်နက်နက် ကြည့်ကြည့် data ကို straight line (or flat hyperplane) တစ်ခုနဲ့ပဲ ပိုင်းခြားနိုင်တာပါ။ Activation function တွေက layer တစ်ခုချင်းစီကြားမှာ nonlinear function ထည့်ပေးလိုက်ခြင်းအားဖြင့် ဒီပြဿနာကို ဖြေရှင်းပေးပြီး network ကို ကွေးကောက်နေတဲ့ complex decision boundary တွေကို တကယ်တမ်း approximate လုပ်နိုင်အောင် လုပ်ပေးတယ်။ ReLU (max(0, x)) ကတော့ modern network အများစုမှာ default choice ဖြစ်တယ် — တွက်ရလွယ်ပြီး gradient က 0 ဒါမှမဟုတ် 1 ပဲ ဖြစ်တာကြောင့် training အတွင်း gradient စီးဆင်းမှု ကောင်းစေတယ် — ဒါပေမဲ့ input က အမြဲ negative ဖြစ်နေတဲ့ neuron တစ်ခုက gradient 0 အမြဲရနေပြီး လုံးဝ သင်ယူတာ ရပ်သွားနိုင်တယ်၊ ဒါကို 'dying ReLU' လို့ခေါ်တယ်။ Sigmoid ကတော့ input ဘယ်လိုပဲရှိရှိ (0, 1) ကြားထဲ squash လုပ်ပေးတယ်၊ probability အတွက် အသုံးဝင်ပေမဲ့ extreme value တွေမှာ saturate ဖြစ်ပြီး gradient က သုညနီးပါး ဖြစ်သွားတတ်တာကြောင့် deep network တွေမှာ training ကို နှေးစေတယ် သို့မဟုတ် ရပ်သွားစေတယ်။ Tanh ကတော့ sigmoid ရဲ့ zero-centered ဗားရှင်းလို့ ဆိုနိုင်ပြီး (-1, 1) ကြားထဲ squash လုပ်တယ်၊ sigmoid ထက် training အနည်းငယ် ပိုကောင်းလေ့ရှိပေမဲ့ saturation ပြဿနာတူတူပဲ ရှိနေတယ်။
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
Tutorial Platform က learner feedback တွေကို positive၊ neutral၊ negative လို့ classify လုပ်ဖို့ model တစ်ခု တည်ဆောက်တဲ့အခါ input text embedding တွေက complicated ဖြစ်ပြီး nonlinear ပုံစံနဲ့ အပြန်အလှန် သက်ရောက်နေတယ် — 'not bad at all' နဲ့ 'not good at all' က စကားလုံးတစ်လုံးပဲ ကွာပေမဲ့ အဓိပ္ပာယ်က ဆန့်ကျင်ဘက်ဖြစ်နေတယ်၊ ဒီလို pattern ကို linear layer တွေချည်း ထပ်ချထားလည်း ဘယ်တော့မှ ပိုင်းခြားနိုင်မှာ မဟုတ်ဘူး။ ဒီ sentiment classifier ထဲက hidden layer တိုင်းမှာ နောက်ထပ် layer နဲ့ ကြားထဲ nonlinear activation လိုအပ်တယ်၊ မဟုတ်ရင် layer ဘယ်လောက်ပဲ ထပ်ချချ network တစ်ခုလုံးက သင်္ချာအရ linear layer တစ်ခုတည်းအဖြစ် ကျဉ်းသွားလိမ့်မယ်။ Team ကတော့ hidden layer တွေအတွက် ReLU ကို ရွေးမှာဖြစ်တယ်၊ ဘာဖြစ်လို့လဲဆိုတော့ training မြန်ပြီး network ရဲ့ depth တစ်လျှောက် vanishing gradient ကို ရှောင်နိုင်လို့ပါ၊ ပြီးတော့ နောက်ဆုံး layer အတွက်တော့ sigmoid ကို ချန်ထားမှာဖြစ်တယ်၊ output ကို (0, 1) ကြားထဲ squash လုပ်ပေးတာက platform ကို feedback တွေကို 'positive ဖြစ်နိုင်ချေ' အလိုက် threshold ချမယ် ဒါမှမဟုတ် rank လုပ်မယ်ဆိုရင် ရှင်းလင်းတဲ့ probability တန်ဖိုး ပေးနိုင်လို့ပါ။
အတူတူ စမ်းရေးကြည့်မယ်
import torch
x = torch.tensor([-2.0, -0.5, 0.0, 0.5, 2.0])
relu_out = torch.relu(x)
sigmoid_out = torch.sigmoid(x)
tanh_out = torch.tanh(x)
print("Input: ", x)
print("ReLU: ", relu_out)
print("Sigmoid:", sigmoid_out)
print("Tanh: ", tanh_out)Input tensor နဲ့အတူ ReLU၊ sigmoid၊ tanh output တွေကို print ထုတ်ကြည့်ရင် ReLU က negative value အားလုံးကို သုညဖြစ်စေပြီး၊ sigmoid က အားလုံးကို (0, 1) ကြားထဲ squash လုပ်ပြီး tanh က အားလုံးကို (-1, 1) ကြားထဲ squash လုပ်ပေးတာကို တွေ့ရမယ်။၅ မိနစ် စမ်းကြည့်
အလားတူ tensor အတွက် `torch.nn.functional.leaky_relu` ကို ထပ်ထည့်ပြီး negative value တွေအတွက် output ကို ReLU ရဲ့ output နဲ့ နှိုင်းယှဉ်ကြည့်ပါ။
သတိလေးတစ်ချက်
Output layer တစ်ခုတည်းမှာသာမဟုတ်ဘဲ deep network ရဲ့ hidden layer တိုင်းမှာ sigmoid ကို သုံးလိုက်ခြင်း — saturating gradient ကြောင့် deep network တွေကို train လုပ်ရတာ အလွန်နှေးသွားနိုင်သလို မဖြစ်နိုင်ဘူးအထိ ဖြစ်နိုင်တယ်၊ ဒါကြောင့် hidden layer တွေအတွက် ReLU က default ဖြစ်လာတာ။
'သေနေတဲ့' ReLU neuron (output 0 အမြဲထွက်နေတာ) ဟာ သူ့ဘာသာသူ ပြန်ပြေလာမယ်လို့ ထင်ထားခြင်း — negative input တွေအတွက် gradient က အတိအကျ 0 ဖြစ်နေတာကြောင့် standard gradient descent က weight ကို positive ဘက် ဘယ်တော့မှ ပြန်တွန်းပေးနိုင်မှာ မဟုတ်ဘူး။
Wikipedia — Activation function — Deep Learning