# Training Pipeline ကို Debugging လုပ်ခြင်း[[debugging-the-training-pipeline]]

သင်ဟာ [Chapter 7](/course/chapter7) က အကြံပြုချက်တွေကို သေချာလိုက်နာပြီး သတ်မှတ်ထားတဲ့ task တစ်ခုပေါ်မှာ model တစ်ခုကို train ဒါမှမဟုတ် fine-tune လုပ်ဖို့ script တစ်ခုကို လှလှပပ ရေးသားခဲ့ပြီးပါပြီ။ ဒါပေမယ့် `model.fit()` command ကို run လိုက်တဲ့အခါ၊ ကြောက်စရာကောင်းတဲ့ အမှားတစ်ခု ဖြစ်ပေါ်လာပါတယ် 😱! ဒါမှမဟုတ် ပိုဆိုးတာက၊ အရာအားလုံး အဆင်ပြေပြီး training က အမှားမရှိဘဲ run နေပေမယ့်၊ ရရှိလာတဲ့ model က အသုံးမကျပါဘူး။ ဒီအပိုင်းမှာ၊ ဒီလိုပြဿနာမျိုးတွေကို debug လုပ်ဖို့ ဘာတွေလုပ်နိုင်လဲဆိုတာ ပြသပေးပါမယ်။

## Training Pipeline ကို Debugging လုပ်ခြင်း[[debugging-the-training-pipeline]]

`model.fit()` မှာ error တစ်ခုကြုံတွေ့ရတဲ့ ပြဿနာကတော့ ၎င်းဟာ source များစွာကနေ လာနိုင်တာကြောင့်ပါပဲ။ ဘာလို့လဲဆိုတော့ training က အများအားဖြင့် သင်အဲဒီအချိန်အထိ လုပ်ဆောင်ခဲ့တဲ့ အရာများစွာကို စုစည်းထားလို့ပါပဲ။ ပြဿနာက သင့် dataset မှာ တစ်ခုခု မှားနေတာ ဒါမှမဟုတ် datasets ရဲ့ elements တွေကို အုပ်စုဖွဲ့ဖို့ ကြိုးစားတဲ့အခါ ပြဿနာတစ်ခုခု ဖြစ်နေတာမျိုး ဖြစ်နိုင်ပါတယ်။ ဒါမှမဟုတ် model code မှာ တစ်ခုခု မှားနေတာ ဒါမှမဟုတ် သင့် loss function ဒါမှမဟုတ် optimizer မှာ ပြဿနာရှိနေတာမျိုး ဖြစ်နိုင်ပါတယ်။ training အတွက် အရာအားလုံး အဆင်ပြေသွားရင်တောင်၊ သင့် metric မှာ ပြဿနာရှိနေရင် evaluation လုပ်နေစဉ်မှာ တစ်ခုခု မှားယွင်းသွားနိုင်ပါသေးတယ်။

`model.fit()` မှာ ဖြစ်ပေါ်လာတဲ့ error တစ်ခုကို debug လုပ်ဖို့ အကောင်းဆုံးနည်းလမ်းကတော့ ဒီ pipeline တစ်ခုလုံးကို ကိုယ်တိုင် ပြန်လည်စစ်ဆေးပြီး ဘယ်နေရာမှာ မှားယွင်းသွားလဲဆိုတာ ကြည့်ဖို့ပါပဲ။ အဲဒီအခါ error ကို ဖြေရှင်းရတာ အများအားဖြင့် အလွန်လွယ်ကူပါတယ်။

ဒါကို သရုပ်ပြဖို့အတွက်၊ [MNLI dataset](https://huggingface.co/datasets/glue) ပေါ်မှာ DistilBERT model တစ်ခုကို fine-tune လုပ်ဖို့ (ကြိုးစားနေတဲ့) အောက်ပါ script ကို ကျွန်တော်တို့ အသုံးပြုပါမယ်။

```py
from datasets import load_dataset
import evaluate
from transformers import (
    AutoTokenizer,
    TFAutoModelForSequenceClassification,
)

raw_datasets = load_dataset("glue", "mnli")

model_checkpoint = "distilbert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)

def preprocess_function(examples):
    return tokenizer(examples["premise"], examples["hypothesis"], truncation=True)

tokenized_datasets = raw_datasets.map(preprocess_function, batched=True)

train_dataset = tokenized_datasets["train"].to_tf_dataset(
    columns=["input_ids", "labels"], batch_size=16, shuffle=True
)

validation_dataset = tokenized_datasets["validation_matched"].to_tf_dataset(
    columns=["input_ids", "labels"], batch_size=16, shuffle=True
)

model = TFAutoModelForSequenceClassification.from_pretrained(model_checkpoint)

model.compile(loss="sparse_categorical_crossentropy", optimizer="adam")

model.fit(train_dataset)
```

သင် ဒါကို run ဖို့ကြိုးစားရင် dataset conversion လုပ်တဲ့အခါ `VisibleDeprecationWarning`s အချို့ရနိုင်ပါတယ် — ဒါက ကျွန်တော်တို့မှာရှိတဲ့ သိထားပြီးသား UX ပြဿနာတစ်ခုဖြစ်လို့ လျစ်လျူရှုပေးပါ။ အကယ်၍ သင်ဟာ နိုဝင်ဘာ ၂၀၂၁ နောက်ပိုင်းမှာ ဒီသင်တန်းကို ဖတ်နေသေးပြီး ဒါက ဆက်ဖြစ်နေသေးတယ်ဆိုရင် @carrigmat ကို ပြင်ပေးဖို့ rage tweets တွေ ပို့ပေးပါ။

ဒါပေမယ့် ပိုပြီးပြင်းထန်တဲ့ ပြဿနာကတော့ ကျွန်တော်တို့ တိုက်ရိုက် error ရတာပါပဲ။ ပြီးတော့ အဲဒါက တကယ်ကို ကြောက်စရာကောင်းလောက်အောင် ရှည်လျားပါတယ်။

```python out
ValueError: No gradients provided for any variable: ['tf_distil_bert_for_sequence_classification/distilbert/embeddings/word_embeddings/weight:0', '...']
```

ဒါဘာကို ဆိုလိုတာလဲ။ ကျွန်တော်တို့ data ပေါ်မှာ train လုပ်ဖို့ ကြိုးစားခဲ့ပေမယ့် gradient မရခဲ့ဘူးလား။ ဒါက အတော်လေး ရှုပ်ထွေးပါတယ်၊ ဒီလိုအရာတစ်ခုကို debug လုပ်ဖို့ ဘယ်လိုစတင်ရမလဲ။ သင်ရတဲ့ error က ပြဿနာဘယ်နေရာမှာလဲဆိုတာကို ချက်ချင်းမပြောပြတဲ့အခါ၊ အကောင်းဆုံးဖြေရှင်းနည်းကတော့ အရာတွေကို အဆင့်ဆင့် ပြန်လည်စစ်ဆေးပြီး၊ အဆင့်တိုင်းမှာ အရာအားလုံး မှန်ကန်နေခြင်းရှိမရှိ သေချာစေဖို့ပါပဲ။ ပြီးတော့၊ စတင်ရမယ့်နေရာကတော့ အမြဲတမ်း...

### သင်၏ Data ကို စစ်ဆေးပါ[[check-your-data]]

ဒါက ပြောစရာမလိုပါဘူး၊ ဒါပေမယ့် သင့် data ပျက်စီးနေတယ်ဆိုရင် Keras က သင့်အတွက် ပြင်ပေးနိုင်မှာ မဟုတ်ပါဘူး။ ဒါကြောင့် ပထမဆုံးအနေနဲ့၊ သင်ရဲ့ training set ထဲမှာ ဘာတွေပါလဲဆိုတာ ကြည့်ဖို့လိုပါတယ်။

`raw_datasets` နဲ့ `tokenized_datasets` ထဲကို ကြည့်ဖို့ ဆွဲဆောင်မှုရှိပေမယ့်၊ data က model ထဲကို ဝင်ရောက်မယ့်နေရာအထိ တိုက်ရိုက်သွားကြည့်ဖို့ ကျွန်တော်တို့ အထူးအကြံပြုပါတယ်။ ဒါက `to_tf_dataset()` function နဲ့ သင်ဖန်တီးထားတဲ့ `tf.data.Dataset` ကနေ output တစ်ခုကို ဖတ်တာကို ဆိုလိုပါတယ်! ဒါဆို ဘယ်လိုလုပ်ရမလဲ။ `tf.data.Dataset` objects တွေက ကျွန်တော်တို့ကို batch လိုက်ပေးပြီး indexing ကို မထောက်ပံ့ပါဘူး၊ ဒါကြောင့် `train_dataset[0]` ကို တိုက်ရိုက်တောင်းလို့ မရပါဘူး။ သို့သော်လည်း၊ batch တစ်ခုကို ယဉ်ယဉ်ကျေးကျေး တောင်းဆိုနိုင်ပါတယ်။

```py
for batch in train_dataset:
    break
```

`break` က loop ကို iteration တစ်ခုအပြီးမှာ ရပ်တန့်စေတာကြောင့်၊ ဒါက `train_dataset` ကနေ ထွက်လာတဲ့ ပထမဆုံး batch ကို ယူပြီး `batch` အဖြစ် သိမ်းဆည်းပါတယ်။ အခု ဘာတွေပါလဲဆိုတာ ကြည့်ရအောင်။

```python out
{'attention_mask': ,
 'label': ,
 'input_ids': }
```

ဒါက မှန်တယ်မလား? ကျွန်တော်တို့ `labels`, `attention_mask` နဲ့ `input_ids` တွေကို model ကို ပေးနေတာဖြစ်ပြီး၊ ဒါတွေအားလုံးက outputs တွေကို တွက်ချက်ဖို့နဲ့ loss ကို တွက်ချက်ဖို့ လိုအပ်တဲ့အရာတွေပါ။ ဒါဆို ဘာလို့ gradient မရှိတာလဲ။ သေချာကြည့်ပါ- ကျွန်တော်တို့ input အဖြစ် dictionary တစ်ခုတည်းကို ပေးနေတာဖြစ်ပေမယ့်၊ training batch တစ်ခုဟာ ပုံမှန်အားဖြင့် input tensor ဒါမှမဟုတ် dictionary တစ်ခုအပြင် labels tensor တစ်ခုပါ ပါဝင်ပါတယ်။ ကျွန်တော်တို့ရဲ့ labels တွေက input dictionary ထဲက key တစ်ခုမျှသာ ဖြစ်နေပါတယ်။

ဒါက ပြဿနာလား။ အမြဲတမ်းတော့ မဟုတ်ပါဘူး! ဒါပေမယ့် ဒါက TensorFlow နဲ့ Transformer models တွေကို train လုပ်တဲ့အခါ သင်ကြုံတွေ့ရမယ့် အဖြစ်အများဆုံး ပြဿနာတွေထဲက တစ်ခုပါပဲ။ ကျွန်တော်တို့ရဲ့ models တွေအားလုံးက loss ကို အတွင်းပိုင်းမှာ တွက်ချက်နိုင်ပါတယ်၊ ဒါပေမယ့် အဲဒီလိုလုပ်ဖို့ labels တွေကို input dictionary ထဲမှာ ပေးဖို့လိုပါတယ်။ ဒါက ကျွန်တော်တို့ `compile()` ကို loss value တစ်ခု မသတ်မှတ်တဲ့အခါ အသုံးပြုတဲ့ loss ပါပဲ။ Keras ကတော့ labels တွေကို input dictionary ကနေ သီးခြားစီ ပေးဖို့ ပုံမှန်အားဖြင့် မျှော်လင့်ပါတယ်၊ ပြီးတော့ သင်အဲဒီလို မလုပ်ရင် loss computations တွေက အများအားဖြင့် အလုပ်လုပ်မှာ မဟုတ်ပါဘူး။

ပြဿနာက ပိုပြီး ရှင်းရှင်းလင်းလင်း ဖြစ်လာပါပြီ- ကျွန်တော်တို့ `loss` argument ကို ပေးခဲ့ပါတယ်၊ ဒါက Keras ကို ကျွန်တော်တို့အတွက် losses တွေ တွက်ချက်ခိုင်းနေတာကို ဆိုလိုပါတယ်၊ ဒါပေမယ့် labels တွေကို model ကို inputs အဖြစ် ပေးခဲ့တာဖြစ်ပြီး Keras မျှော်လင့်တဲ့နေရာမှာ labels အဖြစ် မဟုတ်ပါဘူး! ကျွန်တော်တို့ နှစ်ခုထဲက တစ်ခုကို ရွေးချယ်ဖို့လိုပါတယ်- model ရဲ့ internal loss ကို အသုံးပြုပြီး labels တွေကို ရှိရင်းစွဲနေရာမှာ ထားတာ၊ ဒါမှမဟုတ် Keras losses တွေကို ဆက်လက်အသုံးပြုပြီး labels တွေကို Keras မျှော်လင့်တဲ့နေရာကို ရွှေ့တာ။ ရိုးရှင်းစေဖို့အတွက် ပထမနည်းလမ်းကို ရွေးချယ်ကြရအောင်။ `compile()` ကို အောက်ပါအတိုင်း ပြောင်းလိုက်ပါ။

```py
model.compile(optimizer="adam")
```

အခုဆိုရင် ကျွန်တော်တို့ model ရဲ့ internal loss ကို အသုံးပြုတော့မှာဖြစ်ပြီး၊ ဒီပြဿနာက ဖြေရှင်းပြီးသား ဖြစ်သင့်ပါပြီ။

> [!TIP]
> ✏️ **သင့်အလှည့်!** အခြားပြဿနာတွေကို ဖြေရှင်းပြီးနောက် စိတ်ကြိုက်စိန်ခေါ်မှုတစ်ခုအနေနဲ့၊ ဒီအဆင့်ကို ပြန်လာပြီး model ကို internal loss အစား မူရင်း Keras-computed loss နဲ့ အလုပ်လုပ်အောင် ကြိုးစားနိုင်ပါတယ်။ labels တွေ မှန်ကန်စွာ output ထွက်လာစေဖို့ `to_tf_dataset()` ရဲ့ `label_cols` argument ကို `"labels"` ထည့်ဖို့ လိုအပ်ပါလိမ့်မယ်၊ ဒါက gradients တွေကို ရစေမှာပါ — ဒါပေမယ့် ကျွန်တော်တို့ သတ်မှတ်ထားတဲ့ loss မှာ နောက်ထပ်ပြဿနာတစ်ခု ရှိပါသေးတယ်။ ဒီပြဿနာနဲ့ training က ဆက် run မှာဖြစ်ပေမယ့်၊ သင်ယူမှုက အလွန်နှေးကွေးပြီး high training loss မှာ ရပ်တန့်နေပါလိမ့်မယ်။ ဒါဘာလဲဆိုတာ သင်တွက်ထုတ်နိုင်မလား။
>
> သင်ပိတ်မိနေမယ်ဆိုရင် ROT13-encoded hint တစ်ခု- Vs lbh ybbx ng gur bhgchgf bs FrdhraprPynffvsvpngvba zbqryf va Genafsbezref, gurve svefg bhgchg vf `ybtvgf`. Jung ner ybtvgf?
>
> ပြီးတော့ ဒုတိယ hint- Jura lbh fcrpvsl bcgvzvmref, npgvingvbaf be ybffrf jvgu fgevatf, Xrenf frgf nyy gur nethzrag inyhrf gb gurve qrsnhygf. Jung nethzragf qbrf FcnefrPngrtbevpnyPebffragebcl unir, naq jung ner gurve qrsnhygf?

အခု training လုပ်ကြည့်ရအောင်။ ကျွန်တော်တို့ gradients တွေ ရသင့်ပါပြီ၊ ဒါကြောင့် မျှော်လင့်ပါတယ် ( ominious music ) `model.fit()` ကို ခေါ်လိုက်တာနဲ့ အရာအားလုံး အဆင်ပြေသွားပါလိမ့်မယ်။

```python out
  246/24543 [..............................] - ETA: 15:52 - loss: nan
```

အိုး မဟုတ်ဘူး။

`nan` က သိပ်ပြီး အားပေးစရာကောင်းတဲ့ loss value တစ်ခု မဟုတ်ပါဘူး။ ဒါတောင် ကျွန်တော်တို့ data ကို စစ်ဆေးခဲ့ပြီးပါပြီ၊ ကောင်းကောင်းမွန်မွန်ပါပဲ။ ဒါက ပြဿနာမဟုတ်ဘူးဆိုရင် နောက်ဘယ်ကို ဆက်သွားရမလဲ။ နောက်ထပ် ရှင်းရှင်းလင်းလင်း လုပ်ဆောင်ရမယ့်အဆင့်ကတော့...

### သင်၏ Model ကို စစ်ဆေးပါ[[check-your-model]]

`model.fit()` က Keras မှာ တကယ်ကို ကောင်းမွန်တဲ့ convenience function တစ်ခုပါ၊ ဒါပေမယ့် ဒါက သင့်အတွက် အရာများစွာကို လုပ်ဆောင်ပေးပြီး၊ ဒါက ပြဿနာဘယ်နေရာမှာ ဖြစ်ပေါ်ခဲ့လဲဆိုတာ အတိအကျရှာဖွေဖို့ ပိုခက်ခဲစေပါတယ်။ သင် model ကို debug လုပ်နေတယ်ဆိုရင်၊ အမှန်တကယ် အကူအညီဖြစ်စေနိုင်တဲ့ နည်းလမ်းတစ်ခုကတော့ batch တစ်ခုတည်းကို model ကို ပေးပြီး အဲဒီ batch တစ်ခုတည်းအတွက် outputs တွေကို အသေးစိတ်ကြည့်ဖို့ပါပဲ။ model က error တွေ ထုတ်နေတယ်ဆိုရင် နောက်ထပ် အသုံးဝင်တဲ့ အကြံပြုချက်တစ်ခုကတော့ model ကို `run_eagerly=True` နဲ့ `compile()` လုပ်ဖို့ပါပဲ။ ဒါက ဒါကို အများကြီး နှေးကွေးစေမှာဖြစ်ပေမယ့်၊ error messages တွေကို ပိုပြီး နားလည်ရလွယ်ကူစေပါလိမ့်မယ်။ ဘာလို့လဲဆိုတော့ ၎င်းတို့က သင့် model ရဲ့ code ထဲမှာ ဘယ်နေရာမှာ ပြဿနာဖြစ်ခဲ့လဲဆိုတာ အတိအကျ ဖော်ပြပေးပါလိမ့်မယ်။

ဒါပေမယ့် အခုအတွက်ကတော့ ကျွန်တော်တို့ `run_eagerly` မလိုအပ်သေးပါဘူး။ ကျွန်တော်တို့ အရင်ရခဲ့တဲ့ `batch` ကို model ထဲကို run ကြည့်ပြီး outputs တွေ ဘယ်လိုပုံစံလဲဆိုတာ ကြည့်ရအောင်။

```py
model(batch)
```

```python out
TFSequenceClassifierOutput(loss=, logits=, hidden_states=None, attentions=None)
```

ကောင်းပါပြီ၊ ဒါက ရှုပ်ထွေးပါတယ်။ အရာအားလုံး `nan` ပါပဲ! ဒါပေမယ့် ဒါက ထူးဆန်းတယ်မလား။ ကျွန်တော်တို့ရဲ့ logits တွေအားလုံး ဘယ်လိုလုပ် `nan` ဖြစ်သွားတာလဲ။ `nan` ဆိုတာ "not a number" ကို ဆိုလိုပါတယ်။ `nan` values တွေက သုညနဲ့စားခြင်းလိုမျိုး မလုပ်ရတဲ့ operation တစ်ခုကို လုပ်ဆောင်တဲ့အခါ မကြာခဏ ဖြစ်ပေါ်ပါတယ်။ ဒါပေမယ့် machine learning မှာ `nan` အကြောင်း သိထားရမယ့် အလွန်အရေးကြီးတဲ့ အရာတစ်ခုကတော့ ဒီ value က *ပျံ့နှံ့တတ်တယ်* ဆိုတာပါပဲ။ သင် number တစ်ခုကို `nan` နဲ့ မြှောက်လိုက်ရင်၊ output ကလည်း `nan` ဖြစ်ပါတယ်။ ပြီးတော့ သင့် output၊ သင့် loss ဒါမှမဟုတ် သင့် gradient မှာ `nan` တစ်ခုခု ရခဲ့ရင်၊ ဒါက သင့် model တစ်ခုလုံးကို လျင်မြန်စွာ ပျံ့နှံ့သွားပါလိမ့်မယ် -- ဘာလို့လဲဆိုတော့ အဲဒီ `nan` value က သင့် network ထဲကို ပြန်လည်ရောက်ရှိသွားတဲ့အခါ၊ သင် `nan` gradients တွေရပါလိမ့်မယ်၊ ပြီးတော့ weight updates တွေကို အဲဒီ gradients တွေနဲ့ တွက်ချက်တဲ့အခါ၊ သင် `nan` weights တွေရပါလိမ့်မယ်၊ ပြီးတော့ အဲဒီ weights တွေက `nan` outputs တွေကို ပိုပြီး တွက်ချက်ပေးပါလိမ့်မယ်။ မကြာခင်မှာ network တစ်ခုလုံးက `nan`s တွေရဲ့ block ကြီးတစ်ခု ဖြစ်လာပါလိမ့်မယ်။ ဒါက ဖြစ်သွားပြီဆိုတာနဲ့၊ ပြဿနာဘယ်ကစလဲဆိုတာ မြင်ဖို့ အတော်လေး ခက်ခဲပါတယ်။ `nan` ဘယ်ကနေ စတင်ဝင်ရောက်လာလဲဆိုတာ ကျွန်တော်တို့ ဘယ်လို ခွဲခြားနိုင်မလဲ။

အဖြေကတော့ ကျွန်တော်တို့ရဲ့ model ကို *reinitialize* လုပ်ဖို့ ကြိုးစားတာပါပဲ။ training စတင်ပြီးတာနဲ့၊ ကျွန်တော်တို့ `nan` တစ်ခုခု ရခဲ့ပြီး ဒါက model တစ်ခုလုံးကို လျင်မြန်စွာ ပျံ့နှံ့သွားခဲ့ပါတယ်။ ဒါကြောင့်၊ model ကို checkpoint တစ်ခုကနေ load လုပ်ပြီး weight updates တွေ မလုပ်ဘဲ၊ ဘယ်နေရာမှာ `nan` value ရလဲဆိုတာ ကြည့်ရအောင်။

```py
model = TFAutoModelForSequenceClassification.from_pretrained(model_checkpoint)
model(batch)
```

ကျွန်တော်တို့ ဒါကို run လိုက်တဲ့အခါ၊ အောက်ပါအတိုင်း ရပါလိမ့်မယ်။

```py out
TFSequenceClassifierOutput(loss=, logits=, hidden_states=None, attentions=None)
```

*အခု*တော့ တစ်ခုခု ရလာပြီ! ကျွန်တော်တို့ရဲ့ logits တွေမှာ `nan` values တွေ မရှိတော့ဘူးဆိုတာ စိတ်ချရပါတယ်။ ဒါပေမယ့် ကျွန်တော်တို့ loss မှာ `nan` values အနည်းငယ်ကို တွေ့ရပါတယ်။ ဒါက အဲဒီ samples တွေနဲ့ပတ်သက်တဲ့ ဘာတစ်ခုခုက ဒီပြဿနာကို ဖြစ်စေတာလဲ။ ဘယ်အရာတွေလဲဆိုတာ ကြည့်ရအောင် (ဒီ code ကို သင်ကိုယ်တိုင် run မယ်ဆိုရင်၊ dataset ကို shuffle လုပ်ထားတာကြောင့် သင်မတူညီတဲ့ indices တွေ ရနိုင်တယ်ဆိုတာ သတိပြုပါ)။

```python
import numpy as np

loss = model(batch).loss.numpy()
indices = np.flatnonzero(np.isnan(loss))
indices
```

```python out
array([ 1,  2,  5,  7,  9, 10, 11, 13, 14])
```

ဒီ indices တွေကနေ ဘယ် samples တွေလာလဲဆိုတာ ကြည့်ရအောင်။

```python
input_ids = batch["input_ids"].numpy()
input_ids[indices]
```

```python out
array([[  101,  2007,  2032,  2001,  1037, 16480,  3917,  2594,  4135,
        23212,  3070,  2214, 10170,  1010,  2012,  4356,  1997,  3183,
         6838, 12953,  2039,  2000,  1996,  6147,  1997,  2010,  2606,
         1012,   102,  6838,  2001,  3294,  6625,  3773,  1996,  2214,
         2158,  1012,   102,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  1998,  6814,  2016,  2234,  2461,  2153,  1998, 13322,
         2009,  1012,   102,  2045,  1005,  1055,  2053,  3382,  2008,
         2016,  1005,  2222,  3046,  8103,  2075,  2009,  2153,  1012,
          102,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  1998,  2007,  1996,  3712,  4634,  1010,  2057,  8108,
         2025,  3404,  2028,  1012,  1996,  2616, 18449,  2125,  1999,
         1037,  9666,  1997,  4100,  8663, 11020,  6313,  2791,  1998,
         2431,  1011,  4301,  1012,   102,  2028,  1005,  1055,  5177,
         2110,  1998,  3977,  2000,  2832,  2106,  2025,  2689,  2104,
         2122,  6214,  1012,   102,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  1045,  2001,  1999,  1037, 13090,  5948,  2007,  2048,
         2308,  2006,  2026,  5001,  2043,  2026,  2171,  2001,  2170,
         1012,   102,  1045,  2001,  3564,  1999,  2277,  1012,   102,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  2195,  4279,  2191,  2039,  1996,  2181,  2124,  2004,
         1996,  2225,  7363,  1012,   102,  2045,  2003,  2069,  2028,
         2451,  1999,  1996,  2225,  7363,  1012,   102,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  2061,  2008,  1045,  2123,  1005,  1056,  2113,  2065,
         2009,  2428, 10654,  7347,  2030,  2009,  7126,  2256,  2495,
         2291,   102,  2009,  2003,  5094,  2256,  2495,  2291,  2035,
         2105,  1012,   102,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  2051,  1010,  2029,  3216,  2019,  2503,  3444,  1010,
         6732,  1996,  2265,  2038, 19840,  2098,  2125,  9906,  1998,
         2003,  2770,  2041,  1997,  4784,  1012,   102,  2051,  6732,
         1996,  2265,  2003,  9525,  1998,  4569,  1012,   102,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101,  1996, 10556,  2140, 11515,  2058,  1010,  2010,  2162,
         2252,  5689,  2013,  2010,  7223,  1012,   102,  2043,  1996,
        10556,  2140, 11515,  2058,  1010,  2010,  2252,  3062,  2000,
         1996,  2598,  1012,   102,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0],
       [  101, 13543,  1999,  2049,  6143,  2933,  2443,   102,  2025,
        13543,  1999,  6143,  2933,  2003,  2443,   102,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0,     0,     0,     0,     0,     0,
            0,     0,     0,     0]])
```

ဒီထဲမှာ အများကြီးပါပေမယ့် ထူးဆန်းတာမျိုး မရှိပါဘူး။ labels တွေကို ကြည့်ရအောင်။

```python out
labels = batch['labels'].numpy()
labels[indices]
```

```python out
array([2, 2, 2, 2, 2, 2, 2, 2, 2])
```

အာ! `nan` samples တွေအားလုံးမှာ label တူတူရှိပြီး၊ အဲဒါက label 2 ပါ။ ဒါက အရမ်းကောင်းတဲ့ သဲလွန်စတစ်ခုပါပဲ။ ကျွန်တော်တို့ရဲ့ label က 2 ဖြစ်တဲ့အခါမှသာ `nan` loss ရတာက ကျွန်တော်တို့ model မှာရှိတဲ့ labels အရေအတွက်ကို စစ်ဆေးဖို့ အလွန်ကောင်းတဲ့ အချိန်ဖြစ်တယ်လို့ အကြံပြုပါတယ်။

```python
model.config.num_labels
```

```python out
2
```

အခု ကျွန်တော်တို့ ပြဿနာကို မြင်ပါပြီ- model က classes နှစ်ခုပဲ ရှိတယ်လို့ ထင်နေပေမယ့်၊ labels တွေက 2 အထိ ရောက်နေပါတယ်၊ ဒါက တကယ်တော့ classes သုံးခုရှိတယ်လို့ ဆိုလိုပါတယ် (ဘာလို့လဲဆိုတော့ 0 ကလည်း class တစ်ခု ဖြစ်လို့ပါ)။ ဒီလိုနဲ့ `nan` ကို ရခဲ့တာပါ -- မရှိတဲ့ class တစ်ခုအတွက် loss ကို တွက်ချက်ဖို့ ကြိုးစားခဲ့တာကြောင့်ပါ! ဒါကို ပြောင်းလဲပြီး model ကို ထပ်မံ fit လုပ်ကြည့်ရအောင်။

```
model = TFAutoModelForSequenceClassification.from_pretrained(model_checkpoint, num_labels=3)
model.compile(optimizer='adam')
model.fit(train_dataset)
```

```python out
  869/24543 [>.............................] - ETA: 15:29 - loss: 1.1032
```

ကျွန်တော်တို့ train လုပ်နေပါပြီ! `nan`s တွေ မရှိတော့ဘူး၊ ပြီးတော့ ကျွန်တော်တို့ရဲ့ loss က ကျဆင်းနေပါတယ်... တစ်နည်းအားဖြင့်ပေါ့။ သင် ခဏလောက် ကြည့်နေမယ်ဆိုရင် သင်နည်းနည်း စိတ်မရှည်ဖြစ်လာနိုင်ပါတယ်။ ဘာလို့လဲဆိုတော့ loss value က မြင့်တက်နေဆဲမို့ပါပဲ။ ဒီနေရာမှာ training ကို ရပ်ပြီး ဒီပြဿနာကို ဘာကဖြစ်စေနိုင်မလဲဆိုတာ စဉ်းစားကြည့်ရအောင်။ ဒီအဆင့်မှာတော့ data နဲ့ model နှစ်ခုလုံး အဆင်ပြေတယ်လို့ ကျွန်တော်တို့ ယုံကြည်ပါတယ်။ ဒါပေမယ့် ကျွန်တော်တို့ model က ကောင်းကောင်း သင်ယူနေတာ မဟုတ်ပါဘူး။ တခြားဘာကျန်သေးလဲ။ အချိန်ရောက်ပြီ...

### သင်၏ Hyperparameters များကို စစ်ဆေးပါ[[check-your-hyperparameters]]

အပေါ်က code ကို ပြန်ကြည့်လိုက်ရင်၊ `batch_size` မှလွဲပြီး hyperparameter တစ်ခုမှ သင်မတွေ့နိုင်ပါဘူး၊ ပြီးတော့ ဒါက ဖြစ်နိုင်ခြေရှိတဲ့ တရားခံတစ်ဦးလို့ မထင်ပါဘူး။ ဒါပေမယ့် မလှည့်စားပါနဲ့၊ hyperparameters တွေက အမြဲတမ်းရှိနေပြီး၊ သင်မမြင်နိုင်ဘူးဆိုရင် အဲဒါတွေ ဘယ်လို သတ်မှတ်ထားလဲဆိုတာ သင်မသိဘူးလို့ပဲ ဆိုလိုပါတယ်။ အထူးသဖြင့် Keras အကြောင်း အရေးကြီးတဲ့အချက်တစ်ခုကို မှတ်ထားပါ- သင် loss, optimizer, ဒါမှမဟုတ် activation function ကို string နဲ့ သတ်မှတ်လိုက်ရင်၊ _၎င်းရဲ့ arguments အားလုံးကို ၎င်းတို့ရဲ့ default values တွေအတိုင်း သတ်မှတ်လိုက်ပါလိမ့်မယ်_။ ဒါက strings တွေကို အသုံးပြုတာက အလွန်အဆင်ပြေပေမယ့်၊ ဒီလိုလုပ်တဲ့အခါ အလွန်သတိထားသင့်ပါတယ်။ ဘာလို့လဲဆိုတော့ ဒါက သင့်ဆီကနေ အရေးကြီးတဲ့အရာတွေကို အလွယ်တကူ ဝှက်ထားနိုင်လို့ပါပဲ။ (အပေါ်က optional challenge ကို စမ်းကြည့်နေသူတိုင်း ဒီအချက်ကို သေချာမှတ်သားထားသင့်ပါတယ်)။

ဒီကိစ္စမှာ၊ ကျွန်တော်တို့ argument ကို string နဲ့ ဘယ်နေရာမှာ သတ်မှတ်ခဲ့လဲ။ ကျွန်တော်တို့ loss ကို string နဲ့ စတင်သတ်မှတ်ခဲ့ပေမယ့် အခုတော့ အဲဒီလို မလုပ်တော့ပါဘူး။ ဒါပေမယ့် optimizer ကို string နဲ့ သတ်မှတ်နေပါတယ်။ ဒါက ကျွန်တော်တို့ဆီကနေ တစ်ခုခုကို ဝှက်ထားနိုင်မလား။ [၎င်းရဲ့ arguments](https://www.tensorflow.org/api_docs/python/tf/keras/optimizers/Adam) တွေကို ကြည့်ရအောင်။

ဒီနေရာမှာ ထူးခြားတာ တစ်ခုခုရှိလား။ မှန်ပါတယ် -- learning rate! ကျွန်တော်တို့ ရိုးရိုး `adam` string ကို အသုံးပြုတဲ့အခါ၊ default learning rate ဖြစ်တဲ့ 0.001 (ဒါမှမဟုတ် 1e-3) ကို ရရှိမှာပါ။ ဒါက Transformer model တစ်ခုအတွက် အလွန်မြင့်မားပါတယ်။ ယေဘုယျအားဖြင့်၊ သင့် models တွေအတွက် 1e-5 နဲ့ 1e-4 ကြား learning rates တွေကို စမ်းသပ်ဖို့ ကျွန်တော်တို့ အကြံပြုပါတယ်၊ ဒါက ကျွန်တော်တို့ ဒီနေရာမှာ အမှန်တကယ် အသုံးပြုနေတဲ့ value ထက် ၁၀ ဆမှ ၁၀၀ ဆအထိ နည်းပါတယ်။ ဒါက အဓိကပြဿနာတစ်ခု ဖြစ်နိုင်တယ်လို့ ထင်ရတာကြောင့် ဒါကို လျှော့ချဖို့ ကြိုးစားရအောင်။ ဒါကိုလုပ်ဖို့၊ ကျွန်တော်တို့ actual `optimizer` object ကို import လုပ်ဖို့လိုပါတယ်။ အဲဒီလိုလုပ်ရင်း၊ မြင့်မားတဲ့ learning rate နဲ့ train လုပ်တာက weights တွေကို ထိခိုက်စေနိုင်တဲ့အတွက် model ကို checkpoint ကနေ reinitialize လုပ်ရအောင်။

```python
from tensorflow.keras.optimizers import Adam

model = TFAutoModelForSequenceClassification.from_pretrained(model_checkpoint)
model.compile(optimizer=Adam(5e-5))
```

> [!TIP]
> 💡 သင် 🤗 Transformers ကနေ `create_optimizer()` function ကိုလည်း import လုပ်နိုင်ပါတယ်။ ဒါက သင့်ကို မှန်ကန်တဲ့ weight decay နဲ့ learning rate warmup နဲ့ decay ပါဝင်တဲ့ AdamW optimizer ကို ပေးပါလိမ့်မယ်။ ဒီ optimizer က default Adam optimizer နဲ့ ရရှိတဲ့ ရလဒ်တွေထက် အနည်းငယ် ပိုကောင်းတဲ့ ရလဒ်တွေကို မကြာခဏ ထုတ်လုပ်ပေးပါလိမ့်မယ်။

အခု၊ အသစ်၊ ပိုကောင်းမွန်တဲ့ learning rate နဲ့ model ကို fit လုပ်ကြည့်နိုင်ပါပြီ။

```python
model.fit(train_dataset)
```

```python out
319/24543 [..............................] - ETA: 16:07 - loss: 0.9718
```

အခု ကျွန်တော်တို့ရဲ့ loss က တကယ်ကို ကျဆင်းနေပါပြီ! Training က နောက်ဆုံးမှာ အလုပ်လုပ်နေပုံရပါတယ်။ ဒီနေရာမှာ သင်ခန်းစာတစ်ခု ရှိပါတယ်- သင့် model က run နေပေမယ့် loss က မကျဆင်းဘူးဆိုရင်၊ ပြီးတော့ သင့် data က အဆင်ပြေတယ်လို့ သင်သေချာတယ်ဆိုရင်၊ learning rate နဲ့ weight decay လိုမျိုး hyperparameters တွေကို စစ်ဆေးတာက ကောင်းပါတယ်။ အဲဒီနှစ်ခုထဲက တစ်ခုခုကို အလွန်အမင်း မြင့်မားစွာ သတ်မှတ်တာက training ကို high loss value မှာ "ရပ်တန့်" စေနိုင်ခြေ အများဆုံးပါပဲ။

## အခြားဖြစ်နိုင်ခြေရှိသော ပြဿနာများ[[other-potential-issues]]

အပေါ်က script ထဲက ပြဿနာတွေကို ကျွန်တော်တို့ ဖော်ပြခဲ့ပြီးပါပြီ၊ ဒါပေမယ့် သင်ကြုံတွေ့ရနိုင်တဲ့ အခြား common errors အချို့ ရှိပါသေးတယ်။ (အလွန်မပြည့်စုံသေးတဲ့) စာရင်းတစ်ခုကို ကြည့်ရအောင်။

### Out-of-memory errors များကို ကိုင်တွယ်ဖြေရှင်းခြင်း[[dealing-with-out-of-memory-errors]]

memory ကုန်ဆုံးနေကြောင်း ပြသတဲ့ လက္ခဏာကတော့ "OOM when allocating tensor" လိုမျိုး error ပါပဲ — OOM က "out of memory" ရဲ့ အတိုကောက်ပါ။ ဒါက large language models တွေနဲ့ အလုပ်လုပ်တဲ့အခါ အလွန်အဖြစ်များတဲ့ အန္တရာယ်တစ်ခုပါပဲ။ သင်ဒါကို ကြုံတွေ့ရရင်၊ batch size ကို တစ်ဝက်လျှော့ချပြီး ထပ်ကြိုးစားကြည့်တာက ကောင်းပါတယ်။ ဒါပေမယ့် models တချို့က *အလွန်* ကြီးမားတယ်ဆိုတာ သတိရပါ။ ဥပမာ၊ full-size GPT-2 မှာ parameters 1.5B ပါဝင်ပါတယ်၊ ဒါက model ကို သိမ်းဆည်းဖို့အတွက် 6 GB of memory လိုအပ်ပြီး၊ ၎င်းရဲ့ gradients တွေအတွက် နောက်ထပ် 6 GB လိုအပ်ပါလိမ့်မယ်! full GPT-2 model ကို train လုပ်တာက သင်ဘယ် batch size ကို အသုံးပြုပါစေ VRAM 20 GB ကျော် လိုအပ်မှာဖြစ်ပြီး၊ GPUs အနည်းငယ်သာ ဒါကို ပိုင်ဆိုင်ပါတယ်။ `distilbert-base-cased` လိုမျိုး ပိုပေါ့ပါးတဲ့ models တွေကတော့ run ရတာ အများကြီး ပိုလွယ်ကူပြီး၊ train လုပ်ရတာလည်း ပိုမြန်ဆန်ပါတယ်။

> [!TIP]
> သင်တန်းရဲ့ နောက်အပိုင်းမှာ၊ memory footprint ကို လျှော့ချပြီး အကြီးဆုံး models တွေကို fine-tune လုပ်နိုင်စေမယ့် ပိုမိုအဆင့်မြင့်တဲ့ နည်းလမ်းတွေကို ကျွန်တော်တို့ ကြည့်ရှုသွားမှာပါ။

### Hungry Hungry TensorFlow 🦛[[hungry-hungry-tensorflow]]

TensorFlow ရဲ့ ထူးခြားတဲ့ အချက်တစ်ချက်ကတော့ သင် model တစ်ခု load လုပ်တာ ဒါမှမဟုတ် training လုပ်တာနဲ့ တပြိုင်နက် သင့် GPU memory အားလုံးကို သူ့ဘာသာသူ ခွဲဝေယူပြီး၊ လိုအပ်သလို အဲဒီ memory ကို ခွဲခြမ်းပေးပါတယ်။ ဒါက PyTorch လိုမျိုး အခြား frameworks တွေရဲ့ လုပ်ဆောင်ပုံနဲ့ ကွာခြားပါတယ်။ PyTorch က memory ကို CUDA နဲ့ လိုအပ်သလို ခွဲဝေယူတာမျိုး မလုပ်ပါဘူး။ TensorFlow နည်းလမ်းရဲ့ အားသာချက်တစ်ခုကတော့ memory ကုန်သွားတဲ့အခါ အသုံးဝင်တဲ့ errors တွေ ပေးတတ်ပြီး၊ CUDA kernel တစ်ခုလုံး crash မဖြစ်ဘဲ အဲဒီအခြေအနေကနေ ပြန်လည်ကောင်းမွန်လာနိုင်တာပါပဲ။ ဒါပေမယ့် အရေးကြီးတဲ့ အားနည်းချက်တစ်ခုလည်း ရှိပါတယ်- သင် TensorFlow processes နှစ်ခုကို တစ်ပြိုင်နက်တည်း run မယ်ဆိုရင်၊ **သင် ဆိုးရွားတဲ့ အခြေအနေတစ်ခုနဲ့ ကြုံတွေ့ရပါလိမ့်မယ်**။

သင် Colab ပေါ်မှာ run နေတယ်ဆိုရင် ဒါကို စိုးရိမ်စရာမလိုပါဘူး၊ ဒါပေမယ့် သင် locally run နေတယ်ဆိုရင် ဒါက သေချာပေါက် ဂရုစိုက်သင့်တဲ့အရာတစ်ခုပါ။ အထူးသဖြင့်၊ notebook tab တစ်ခုကို ပိတ်လိုက်တာနဲ့ အဲဒီ notebook က အမြဲတမ်း ပိတ်သွားတာ မဟုတ်ဘူးဆိုတာ သတိပြုပါ။ သင် run နေတဲ့ notebooks တွေကို (green icon ရှိတဲ့ ones) ရွေးပြီး directory listing မှာ ကိုယ်တိုင် ပိတ်ဖို့ လိုအပ်နိုင်ပါတယ်။ TensorFlow ကို အသုံးပြုနေတဲ့ run နေတဲ့ notebook တစ်ခုခုက သင့် GPU memory အများအပြားကို ဆက်ကိုင်ထားနိုင်ပြီး၊ ဒါက သင်စတင်တဲ့ notebook အသစ်တိုင်းမှာ အလွန်ထူးဆန်းတဲ့ ပြဿနာအချို့ ကြုံတွေ့ရနိုင်တယ်လို့ ဆိုလိုပါတယ်။

သင့် code မှာ CUDA, BLAS, ဒါမှမဟုတ် cuBLAS နဲ့ပတ်သက်တဲ့ errors တွေ အရင်က အလုပ်လုပ်ခဲ့တာကနေ ရလာပြီဆိုရင်၊ ဒါက အများအားဖြင့် တရားခံပါပဲ။ `nvidia-smi` လို command တစ်ခုကို အသုံးပြုပြီး စစ်ဆေးနိုင်ပါတယ် — သင့်လက်ရှိ notebook ကို ပိတ်လိုက်တာ ဒါမှမဟုတ် restart လုပ်လိုက်တဲ့အခါ၊ သင့် memory အများစုက လွတ်နေလား၊ ဒါမှမဟုတ် အသုံးပြုနေဆဲလား။ အသုံးပြုနေဆဲဆိုရင်၊ တခြားတစ်ခုခုက ဒါကို ကိုင်ထားတာ ဖြစ်ပါတယ်။

### သင်၏ Data ကို စစ်ဆေးပါ (ထပ်မံ၍!)[[check-your-data-again]]

သင့် data ကနေ တစ်ခုခု သင်ယူနိုင်တယ်ဆိုမှပဲ သင်၏ model က သင်ယူပါလိမ့်မယ်။ data ကို ပျက်စီးစေတဲ့ bug တစ်ခုခုရှိနေရင် ဒါမှမဟုတ် labels တွေက ကျပန်းသတ်မှတ်ထားတယ်ဆိုရင်၊ သင်၏ dataset ပေါ်မှာ model training က ကောင်းကောင်းဖြစ်လာမှာ မဟုတ်ပါဘူး။ ဒီနေရာမှာ အသုံးဝင်တဲ့ ကိရိယာတစ်ခုက `tokenizer.decode()` ပါပဲ။ ဒါက `input_ids` တွေကို strings တွေအဖြစ် ပြန်ပြောင်းပေးတာကြောင့်၊ သင် data ကို ကြည့်ရှုပြီး သင့် training data က သင်လိုချင်တာကို သင်ပေးနေခြင်းရှိမရှိ သိနိုင်ပါတယ်။ ဥပမာ၊ အပေါ်မှာ ကျွန်တော်တို့ လုပ်ခဲ့သလို သင့် `tf.data.Dataset` ကနေ `batch` တစ်ခု ရပြီးနောက်၊ ပထမဆုံး element ကို အောက်ပါအတိုင်း decode လုပ်နိုင်ပါတယ်။

```py
input_ids = batch["input_ids"].numpy()
tokenizer.decode(input_ids[0])
```

ပြီးရင် ဒါကို ပထမဆုံး label နဲ့ အောက်ပါအတိုင်း နှိုင်းယှဉ်နိုင်ပါတယ်။

```py
labels = batch["labels"].numpy()
label = labels[0]
```

သင့် data ကို ဒီလိုကြည့်ရှုနိုင်ပြီဆိုတာနဲ့၊ သင်ကိုယ်တိုင် အောက်ပါမေးခွန်းတွေကို မေးနိုင်ပါတယ်။

- decode လုပ်ထားတဲ့ data က နားလည်ရလွယ်ကူလား။
- labels တွေကို သင်သဘောတူလား။
- အခြား labels တွေထက် ပိုအဖြစ်များတဲ့ label တစ်ခုခု ရှိလား။
- model က random answer/အမြဲတမ်း အဖြေတူတူကို ခန့်မှန်းရင် loss/metric က ဘယ်လောက်ဖြစ်သင့်လဲ။

သင့် data ကို ကြည့်ပြီးနောက်၊ model ရဲ့ predictions အချို့ကို ကြည့်ပါ -- သင့် model က tokens တွေကို ထုတ်လုပ်တယ်ဆိုရင် ဒါတွေကိုလည်း decode လုပ်ကြည့်ပါ။ အကယ်၍ model က အမြဲတမ်း တူညီတဲ့အရာကို ခန့်မှန်းနေတယ်ဆိုရင် ဒါက သင့် dataset က category တစ်ခုကို ဘက်လိုက်နေတာကြောင့် ဖြစ်နိုင်ပါတယ် (classification problems အတွက်)၊ ဒါကြောင့် oversampling rare classes လိုမျိုး နည်းလမ်းတွေက အကူအညီဖြစ်နိုင်ပါတယ်။ တစ်နည်းအားဖြင့်၊ ဒါက bad hyperparameter settings လိုမျိုး training ပြဿနာတွေကြောင့်လည်း ဖြစ်နိုင်ပါတယ်။

training မလုပ်ခင် သင့် initial model ပေါ်မှာ သင်ရတဲ့ loss/metric က random predictions တွေအတွက် သင်မျှော်လင့်ထားတဲ့ loss/metric နဲ့ အလွန်ကွာခြားနေတယ်ဆိုရင်၊ သင့် loss ဒါမှမဟုတ် metric ကို တွက်ချက်တဲ့ နည်းလမ်းကို သေချာပြန်စစ်ဆေးပါ၊ ဘာလို့လဲဆိုတော့ အဲဒီမှာ bug တစ်ခု ရှိနေနိုင်လို့ပါပဲ။ သင်နောက်ဆုံးမှာ ပေါင်းထည့်တဲ့ losses အများအပြားကို အသုံးပြုနေတယ်ဆိုရင်၊ ၎င်းတို့သည် scale တူညီကြောင်း သေချာပါစေ။

သင့် data က perfect ဖြစ်တယ်လို့ သင်သေချာပြီဆိုရင်၊ model က ဒါကို test တစ်ခုတည်းနဲ့ train လုပ်နိုင်လားဆိုတာ သင်ကြည့်နိုင်ပါတယ်။

### Model ကို Batch တစ်ခုတည်းနဲ့ Overfit လုပ်ခြင်း[[overfit-your-model-on-one-batch]]

Overfitting က အများအားဖြင့် training လုပ်တဲ့အခါ ကျွန်တော်တို့ ရှောင်ရှားဖို့ ကြိုးစားရတဲ့အရာပါ။ ဘာလို့လဲဆိုတော့ ဒါက model က ကျွန်တော်တို့ လိုချင်တဲ့ general features တွေကို မှတ်မိဖို့ မသင်ယူဘဲ training samples တွေကိုပဲ အလွတ်ကျက်နေတာကို ဆိုလိုလို့ပါ။ သို့သော်လည်း၊ သင့် model ကို batch တစ်ခုတည်းပေါ်မှာ အကြိမ်ကြိမ်အခါခါ train လုပ်ဖို့ ကြိုးစားတာက သင်ပြဿနာကို ပုံဖော်ထားတဲ့အတိုင်း သင် train လုပ်ဖို့ ကြိုးစားနေတဲ့ model က ဖြေရှင်းနိုင်ခြင်းရှိမရှိ စစ်ဆေးဖို့ ကောင်းမွန်တဲ့ test တစ်ခုပါ။ ဒါက သင့် initial learning rate က မြင့်မားလွန်းခြင်းရှိမရှိ သိရှိဖို့လည်း ကူညီပေးပါလိမ့်မယ်။

သင် `model` ကို သတ်မှတ်ပြီးတာနဲ့ ဒါကိုလုပ်ဆောင်တာက အလွန်လွယ်ကူပါတယ်၊ training data ရဲ့ batch တစ်ခုကို ယူပြီး၊ အဲဒီ `batch` ကို သင့် dataset အားလုံးအဖြစ် သတ်မှတ်ကာ၊ epochs အများအပြားအတွက် ဒါကို fit လုပ်လိုက်ပါ။

```py
for batch in train_dataset:
    break

# model.compile() ကို run ပြီး သင့် optimizer ကို သတ်မှတ်ထားကြောင်း၊
# ပြီးတော့ သင်အသုံးပြုနေတယ်ဆိုရင် သင့် loss/metrics တွေကို သတ်မှတ်ထားကြောင်း သေချာပါစေ။

model.fit(batch, epochs=20)
```

> [!TIP]
> 💡 သင့် training data က unbalanced ဖြစ်နေတယ်ဆိုရင်၊ labels အားလုံးပါဝင်တဲ့ training data batch တစ်ခုကို တည်ဆောက်ထားကြောင်း သေချာပါစေ။

ရရှိလာတဲ့ model ဟာ `batch` ပေါ်မှာ perfect နီးပါး ရလဒ်တွေ ရရှိသင့်ပြီး၊ loss က 0 နီးပါး (ဒါမှမဟုတ် သင်အသုံးပြုနေတဲ့ loss အတွက် အနိမ့်ဆုံးတန်ဖိုး) သို့ လျင်မြန်စွာ ကျဆင်းသင့်ပါတယ်။

သင့် model ကို ဒီလို perfect ရလဒ်တွေ မရရှိနိုင်ဘူးဆိုရင်၊ သင်ပြဿနာကို ပုံဖော်ထားတဲ့ နည်းလမ်း ဒါမှမဟုတ် သင့် data မှာ တစ်ခုခု မှားနေတယ်လို့ ဆိုလိုပါတယ်၊ ဒါကြောင့် ဒါကို ပြင်ဆင်သင့်ပါတယ်။ သင် overfitting test ကို အောင်မြင်အောင် လုပ်ဆောင်နိုင်မှသာ သင့် model က တကယ်ကို သင်ယူနိုင်တယ်ဆိုတာ သေချာနိုင်ပါလိမ့်မယ်။

> [!WARNING]
> ⚠️ ဒီ overfitting test ပြီးရင် သင် model ကို ပြန်လည်ဖန်တီးပြီး recompile လုပ်ရပါလိမ့်မယ်။ ဘာလို့လဲဆိုတော့ ရရှိလာတဲ့ model က သင့် full dataset ပေါ်မှာ အသုံးဝင်တဲ့အရာတစ်ခုခုကို ပြန်လည်သင်ယူနိုင်မှာ မဟုတ်လို့ပါပဲ။

### ပထမဆုံး Baseline မရခင် ဘာမှ မညှိပါနှင့်[[dont-tune-anything-until-you-have-a-first-baseline]]

Intense hyperparameter tuning ကို Machine Learning ရဲ့ အခက်ခဲဆုံး အပိုင်းအဖြစ် အမြဲတမ်း အလေးပေးပြောဆိုကြပေမယ့်၊ ဒါက metric ပေါ်မှာ အနည်းငယ် တိုးတက်မှုရရှိအောင် ကူညီပေးမယ့် နောက်ဆုံးအဆင့်တစ်ခုမျှသာ ဖြစ်ပါတယ်။ သင့် hyperparameters တွေအတွက် *အလွန်* ဆိုးရွားတဲ့ တန်ဖိုးတွေ (ဥပမာ- Transformer model နဲ့ default Adam learning rate 1e-3 ကို အသုံးပြုခြင်း) က သင်ယူမှုကို အလွန်နှေးကွေးစေနိုင်ပါတယ် ဒါမှမဟုတ် လုံးဝ ရပ်တန့်သွားစေနိုင်ပါတယ်၊ ဒါပေမယ့် အချိန်အများစုမှာ "သင့်လျော်သော" hyperparameters တွေ (ဥပမာ- learning rate 1e-5 ကနေ 5e-5 အထိ) က သင့်ကို ကောင်းမွန်တဲ့ ရလဒ်တွေ ပေးဖို့ အဆင်ပြေပြေ အလုပ်လုပ်ပါလိမ့်မယ်။ ဒါကြောင့်၊ သင့် dataset ပေါ်မှာ သင်ရရှိထားတဲ့ baseline ကို ကျော်လွန်တဲ့အရာတစ်ခု မရမချင်း အချိန်ကုန်ပြီး ကုန်ကျစရိတ်များတဲ့ hyperparameter search ကို မလုပ်ဆောင်ပါနဲ့။

သင့်မှာ ကောင်းမွန်လုံလောက်တဲ့ model တစ်ခု ရရှိပြီဆိုတာနဲ့၊ အနည်းငယ် စတင်ပြင်ဆင်နိုင်ပါပြီ။ မတူညီတဲ့ hyperparameters တွေနဲ့ run တွေ ထောင်ပေါင်းများစွာကို လုပ်ဆောင်ဖို့ မကြိုးစားပါနဲ့၊ ဒါပေမယ့် hyperparameter တစ်ခုအတွက် မတူညီတဲ့ values နှစ်ခုနဲ့ run အချို့ကို နှိုင်းယှဉ်ပြီး ဘယ်ဟာက အကြီးမားဆုံး အကျိုးသက်ရောက်မှုရှိလဲဆိုတာ စိတ်ကူးရအောင် လုပ်ပါ။

သင် model ကိုယ်တိုင်ကို ပြင်ဆင်နေတယ်ဆိုရင်၊ ရိုးရှင်းအောင်ထားပြီး သင်ကျိုးကြောင်းဆီလျော်စွာ အကြောင်းပြလို့ မရတဲ့အရာတွေကို မစမ်းသပ်ပါနဲ့။ သင့်ရဲ့ ပြောင်းလဲမှုက မရည်ရွယ်ဘဲ ဖြစ်ပေါ်လာတဲ့ အကျိုးဆက်တွေ မရှိဘူးဆိုတာ သေချာစေဖို့ overfitting test ကို အမြဲတမ်း ပြန်လုပ်ပါ။

### အကူအညီတောင်းပါ[[ask-for-help]]

မျှော်လင့်ပါတယ် ဒီအပိုင်းက သင့်ပြဿနာကို ဖြေရှင်းဖို့ ကူညီပေးမယ့် အကြံပြုချက်အချို့ကို သင်တွေ့ခဲ့ရပါလိမ့်မယ်။ ဒါပေမယ့် မဟုတ်ဘူးဆိုရင်၊ [forums](https://discuss.huggingface.co/) မှာ community ကို အမြဲတမ်း အကူအညီတောင်းနိုင်တယ်ဆိုတာ မှတ်ထားပါ။

အကူအညီဖြစ်နိုင်မယ့် နောက်ထပ် အရင်းအမြစ်အချို့ကတော့ အောက်ပါအတိုင်းပါ။

- Joel Grus ရဲ့ ["Reproducibility as a vehicle for engineering best practices"](https://docs.google.com/presentation/d/1yHLPvPhUs2KGI5ZWo0sU-PKU3GimAk3iTsI38Z-B5Gw/edit#slide=id.p)
- Cecelia Shao ရဲ့ ["Checklist for debugging neural networks"](https://towardsdatascience.com/checklist-for-debugging-neural-networks-d8b2a9434f21)
- Chase Roberts ရဲ့ ["How to unit test machine learning code"](https://medium.com/@keeper6928/how-to-unit-test-machine-learning-code-57cf6fd81765)
- Andrej Karpathy ရဲ့ ["A Recipe for Training Neural Networks"](http://karpathy.github.io/2019/04/25/recipe/)

ဟုတ်ပါတယ်၊ neural nets တွေကို train လုပ်တဲ့အခါ သင်ကြုံတွေ့ရတဲ့ ပြဿနာတိုင်းဟာ သင့်အမှားကြောင့် မဟုတ်ပါဘူး။ 🤗 Transformers ဒါမှမဟုတ် 🤗 Datasets library ထဲမှာ တစ်ခုခု မမှန်ဘူးလို့ ထင်တာနဲ့ ကြုံတွေ့ရရင်၊ သင် bug တစ်ခုနဲ့ ကြုံတွေ့ခဲ့တာ ဖြစ်နိုင်ပါတယ်။ သင်ဒါနဲ့ ပတ်သက်ပြီး အကုန်လုံး ကျွန်တော်တို့ကို သေချာပြောပြသင့်ပါတယ်၊ ပြီးတော့ နောက်အပိုင်းမှာ ဒါကို ဘယ်လိုအတိအကျ လုပ်ဆောင်ရမလဲဆိုတာ ကျွန်တော်တို့ ရှင်းပြပေးပါမယ်။

## ဝေါဟာရ ရှင်းလင်းချက် (Glossary)

*   **Training Pipeline**: Machine Learning မော်ဒယ်တစ်ခုကို data preprocessing မှစ၍ model training, evaluation အထိ ပါဝင်သော အဆင့်များစွာရှိသည့် လုပ်ငန်းစဉ်။
*   **Debug**: ကွန်ပျူတာပရိုဂရမ်တစ်ခုရှိ အမှားများ (bugs) ကို ရှာဖွေ၊ ဖော်ထုတ်ပြီး ပြင်ဆင်ခြင်း။
*   **Fine-tune**: ကြိုတင်လေ့ကျင့်ထားပြီးသား (pre-trained) မော်ဒယ်တစ်ခုကို သီးခြားလုပ်ငန်းတစ်ခု (specific task) အတွက် အနည်းငယ်သော ဒေတာနဲ့ ထပ်မံလေ့ကျင့်ပေးခြင်းကို ဆိုလိုပါတယ်။
*   **Model**: Artificial Intelligence (AI) နယ်ပယ်တွင် အချက်အလက်များကို လေ့လာပြီး ခန့်မှန်းချက်များ ပြုလုပ်ရန် ဒီဇိုင်းထုတ်ထားသော သင်္ချာဆိုင်ရာဖွဲ့စည်းပုံများ။
*   **`model.fit()`**: Keras (TensorFlow) တွင် model ကို training လုပ်ရန် အသုံးပြုသော method။
*   **Error**: ပရိုဂရမ်တစ်ခု အလုပ်လုပ်နေစဉ် ဖြစ်ပေါ်လာသော ပြဿနာတစ်ခုကြောင့် ၎င်းသည် ပုံမှန်အတိုင်း ဆက်လက်လုပ်ဆောင်နိုင်ခြင်းမရှိခြင်း။
*   **Crappy (Model)**: စွမ်းဆောင်ရည် ညံ့ဖျင်းသော သို့မဟုတ် အသုံးမကျသော model။
*   **Dataset**: AI မော်ဒယ်တွေ လေ့ကျင့်ဖို့အတွက် အသုံးပြုတဲ့ ဒေတာအစုအဝေးတစ်ခုပါ။
*   **Batch Elements**: dataset အတွင်းရှိ elements များစွာကို တစ်ပြိုင်နက်တည်း လုပ်ဆောင်နိုင်ရန် အုပ်စုဖွဲ့ခြင်း။
*   **Loss Function**: Model ၏ ခန့်မှန်းချက်များနှင့် အမှန်တကယ် labels များကြား ကွာခြားမှုကို တိုင်းတာသော function။
*   **Optimizer**: Model ၏ weights များကို training လုပ်နေစဉ်အတွင်း loss ကို လျှော့ချရန်အတွက် ချိန်ညှိပေးသော algorithm။
*   **Evaluation**: Model ၏ စွမ်းဆောင်ရည်ကို တိုင်းတာခြင်း။
*   **Metric**: Model ၏ စွမ်းဆောင်ရည်ကို တိုင်းတာရန် အသုံးပြုသော တန်ဖိုးများ (ဥပမာ- accuracy, F1 score)။
*   **`load_dataset()`**: Hugging Face Datasets library မှ dataset များကို download လုပ်ပြီး cache လုပ်ရန် အသုံးပြုသော function။
*   **`evaluate` Library**: Model ၏ metrics များကို တွက်ချက်ရန်အတွက် Hugging Face မှ ပံ့ပိုးပေးသော library။
*   **`AutoTokenizer`**: Hugging Face Transformers library မှာ ပါဝင်တဲ့ class တစ်ခုဖြစ်ပြီး မော်ဒယ်အမည်ကို အသုံးပြုပြီး သက်ဆိုင်ရာ tokenizer ကို အလိုအလျောက် load လုပ်ပေးသည်။
*   **`TFAutoModelForSequenceClassification`**: TensorFlow framework အတွက် sequence classification task အတွက် Transformer model ကို အလိုအလျောက် load လုပ်ပေးသော class။
*   **`raw_datasets`**: preprocessing မလုပ်ရသေးသော dataset။
*   **`model_checkpoint`**: pretrained model ၏ အမည် သို့မဟုတ် path။
*   **`tokenizer`**: စာသားကို tokens အဖြစ် ပြောင်းလဲပေးသော ကိရိယာ။
*   **`preprocess_function`**: dataset ကို preprocessing လုပ်ရန်အတွက် function။
*   **`examples["premise"]`**: MNLI dataset ၏ premise column မှ data။
*   **`examples["hypothesis"]`**: MNLI dataset ၏ hypothesis column မှ data။
*   **`truncation=True`**: Tokenizer ကို အရှည်ဆုံး sequence အထိ ဖြတ်တောက်ရန် သတ်မှတ်ခြင်း။
*   **`tokenized_datasets`**: tokenizer ဖြင့် preprocessing လုပ်ထားသော dataset။
*   **`map()` Method**: 🤗 Datasets library မှာ ပါဝင်တဲ့ method တစ်ခုဖြစ်ပြီး dataset ရဲ့ element တစ်ခုစီ ဒါမှမဟုတ် batch တစ်ခုစီပေါ်မှာ function တစ်ခုကို အသုံးပြုနိုင်စေသည်။
*   **`batched=True`**: `map()` method မှာ အသုံးပြုသော argument တစ်ခုဖြစ်ပြီး function ကို dataset ရဲ့ element အများအပြားပေါ်မှာ တစ်ပြိုင်နက်တည်း အသုံးပြုစေသည်။
*   **`train_dataset`**: training အတွက် အသုံးပြုမည့် dataset။
*   **`to_tf_dataset()` Method**: 🤗 Datasets library မှ dataset ကို TensorFlow `tf.data.Dataset` object အဖြစ် ပြောင်းလဲပေးသော method။
*   **`columns=["input_ids", "labels"]`**: `tf.data.Dataset` တွင် ပါဝင်မည့် columns များ။
*   **`batch_size=16`**: training အတွက် တစ်ကြိမ်လျှင် အသုံးပြုမည့် samples အရေအတွက်။
*   **`shuffle=True`**: dataset ကို training မလုပ်မီ ရောနှော (shuffle) ရန် သတ်မှတ်ခြင်း။
*   **`validation_dataset`**: validation အတွက် အသုံးပြုမည့် dataset။
*   **`model.compile()`**: Keras တွင် model ကို training အတွက် ပြင်ဆင်ရန် (optimizer, loss, metrics) အသုံးပြုသော method။
*   **`loss="sparse_categorical_crossentropy"`**: Multi-class classification အတွက် အသုံးပြုသော loss function။
*   **`optimizer="adam"`**: Adam optimizer ကို အသုံးပြုခြင်း။
*   **`VisibleDeprecationWarning`**: Python တွင် နောက်ပိုင်း version များတွင် ဖယ်ရှားခံရနိုင်သော feature တစ်ခုကို အသုံးပြုခြင်းကြောင့် ပေါ်ပေါက်လာသော warning။
*   **UX Issue (User Experience Issue)**: အသုံးပြုသူ အတွေ့အကြုံနှင့် ပတ်သက်သော ပြဿနာ။
*   **`ValueError`**: Python တွင် value မှားယွင်းစွာ ပေးပို့မိသောအခါ ဖြစ်ပေါ်လာသော error။
*   **Gradients**: Deep learning တွင် model ၏ weights များကို update လုပ်ရန်အတွက် loss function ၏ derivative (ပြောင်းလဲမှုနှုန်း)။
*   **`tf.data.Dataset`**: TensorFlow တွင် efficient data input pipeline များကို တည်ဆောက်ရန် အသုံးပြုသော API။
*   **`batch`**: `tf.data.Dataset` မှ တစ်ကြိမ်လျှင် ထုတ်ပေးသော data အစုအဝေး။
*   **`labels`**: model က ခန့်မှန်းရမည့် အမှန်တကယ် တန်ဖိုးများ။
*   **`attention_mask`**: မော်ဒယ်ကို အာရုံစိုက်သင့်သည့် tokens များနှင့် လျစ်လျူရှုသင့်သည့် (padding) tokens များကို ခွဲခြားပေးသည့် binary mask။
*   **`input_ids`**: Tokenizer မှ ထုတ်ပေးသော tokens တစ်ခုစီ၏ ထူးခြားသော ဂဏန်းဆိုင်ရာ ID များ။
*   **Input Tensor**: model သို့ ပေးပို့သော multi-dimensional array (tensor)။
*   **Keras**: TensorFlow တွင် deep learning models များကို တည်ဆောက်ရန် အသုံးပြုသော high-level API။
*   **Internal Loss**: Transformer models များတွင် ၎င်းတို့ကိုယ်တိုင် loss များကို တွက်ချက်နိုင်သော အင်္ဂါရပ်။
*   **`model.config.num_labels`**: model configuration တွင် သတ်မှတ်ထားသော output classes အရေအတွက်။
*   **`Adam` (Optimizer)**: Adaptive Moment Estimation ဟုခေါ်သော optimizer algorithm တစ်ခု။
*   **Hyperparameters**: Model ကို training မလုပ်မီ သတ်မှတ်ပေးရသော parameters များ (ဥပမာ- learning rate, batch size)။
*   **`learning_rate`**: Training လုပ်ငန်းစဉ်အတွင်း model ၏ weights များကို မည်မျှပြောင်းလဲရမည်ကို ထိန်းချုပ်သော parameter။
*   **`weight_decay`**: Model ၏ weights များ အလွန်အမင်း မကြီးထွားစေရန် ထိန်းချုပ်သော regularization technique။
*   **`AdamW`**: Weight decay ကို မှန်ကန်စွာ ကိုင်တွယ်သော Adam optimizer ၏ ပြုပြင်ထားသော version။
*   **Learning Rate Warmup**: Training အစတွင် learning rate ကို ဖြည်းဖြည်းချင်း မြှင့်တင်ခြင်း။
*   **Learning Rate Decay**: Training လုပ်နေစဉ် learning rate ကို ဖြည်းဖြည်းချင်း လျှော့ချခြင်း။
*   **"Stall" (Training)**: Training လုပ်ငန်းစဉ် ရပ်တန့်သွားခြင်း သို့မဟုတ် တိုးတက်မှု မရှိတော့ခြင်း။
*   **OOM (Out Of Memory) Error**: ကွန်ပျူတာ၏ မှတ်ဉာဏ် (memory) မလုံလောက်ခြင်းကြောင့် ဖြစ်ပေါ်လာသော error။
*   **Allocating Tensor**: Memory တွင် tensor တစ်ခုအတွက် နေရာချထားခြင်း။
*   **GPT-2**: Generative Pre-trained Transformer 2, OpenAI မှ ဖန်တီးသော large language model။
*   **Parameters (Model)**: Model ၏ လေ့ကျင့်နိုင်သော weights နှင့် biases များ။
*   **VRAM (Video RAM)**: GPU တွင် အသုံးပြုသော memory။
*   **`distilbert-base-cased`**: DistilBERT model ၏ base version, cased text ပေါ်တွင် လေ့ကျင့်ထားသည်။
*   **TensorFlow Quirk**: TensorFlow ၏ ထူးခြားသော သို့မဟုတ် ပုံမှန်မဟုတ်သော လုပ်ဆောင်ပုံ။
*   **CUDA**: NVIDIA မှ GPU များပေါ်တွင် parallel computing (ပြိုင်တူတွက်ချက်မှု) အတွက် ဖန်တီးသော platform နှင့် API။
*   **PyTorch**: Facebook (ယခု Meta) က ဖန်တီးထားတဲ့ open-source machine learning library တစ်ခုဖြစ်ပြီး deep learning မော်ဒယ်တွေ တည်ဆောက်ဖို့အတွက် အသုံးပြုပါတယ်။
*   **CUDA Kernel**: GPU ပေါ်တွင် run ရန် ရေးသားထားသော function။
*   **BLAS (Basic Linear Algebra Subprograms)**: vector နှင့် matrix operations များအတွက် standard API။
*   **cuBLAS**: NVIDIA CUDA အတွက် BLAS library။
*   **`nvidia-smi`**: NVIDIA GPU များ၏ အခြေအနေ (ဥပမာ- memory usage) ကို စစ်ဆေးရန်အတွက် command-line utility။
*   **`tokenizer.decode()`**: Tokenized input IDs များကို မူရင်းစာသားအဖြစ် ပြန်ပြောင်းပေးသော tokenizer method။
*   **Corrupt Data**: ပျက်စီးနေသော သို့မဟုတ် မှားယွင်းနေသော ဒေတာ။
*   **Randomly Attributed Labels**: ကျပန်းသတ်မှတ်ထားသော labels များ။
*   **Biased Dataset**: သီးခြား category တစ်ခု သို့မဟုတ် အုပ်စုတစ်ခုကို အချိုးမညီမျှစွာ ကိုယ်စားပြုသော dataset။
*   **Oversampling Rare Classes**: dataset ထဲက နည်းပါးတဲ့ classes တွေရဲ့ samples တွေကို တိုးမြှင့်ခြင်း။
*   **Baseline (Model)**: အခြား models များကို နှိုင်းယှဉ်ရန်အတွက် စွမ်းဆောင်ရည်ကို တိုင်းတာရန် အသုံးပြုသော အခြေခံ model။
*   **Hyperparameter Tuning**: Model ၏ hyperparameters များကို အကောင်းဆုံး စွမ်းဆောင်ရည် ရရှိရန်အတွက် ချိန်ညှိခြင်း။
*   **`git_commit()` Method**: `Repository` class မှ commit လုပ်ရန်အတွက် method။
*   **`git_pull()` Method**: `Repository` class မှ pull လုပ်ရန်အတွက် method။
*   **`git_push()` Method**: `Repository` class မှ push လုပ်ရန်အတွက် method။
*   **`Repository` Class**: `huggingface_hub` library မှ Git repository များကို ကိုင်တွယ်ရန်အတွက် class။
*   **`merge`**: Git တွင် မတူညီသော branches များမှ ပြောင်းလဲမှုများကို ပေါင်းစပ်ခြင်း။
*   **API (Application Programming Interface)**: ဆော့ဖ်ဝဲလ် နှစ်ခုကြား အပြန်အလှန် ချိတ်ဆက်ဆောင်ရွက်နိုင်ရန် လမ်းကြောင်းဖွင့်ပေးသော အစုအဝေး (set of rules) များ။
*   **TensorFlow**: Google က ဖန်တီးထားတဲ့ open-source machine learning library တစ်ခုဖြစ်ပြီး deep learning မော်ဒယ်တွေ တည်ဆောက်ဖို့အတွက် အသုံးပြုပါတယ်။
*   **Python**: အသုံးများသော programming language တစ်ခု။
*   **Markdown Files**: Plain text format တစ်ခုဖြစ်ပြီး formatting syntax ကို အသုံးပြု၍ စာသားကို ပုံစံချခြင်း။
*   **Callback**: Keras မှာ training လုပ်နေစဉ် သတ်မှတ်ထားတဲ့ အဆင့်တွေမှာ အလိုအလျောက် run ဖို့ သတ်မှတ်ထားတဲ့ function တစ်ခု။
*   **CLI (Command Line Interface)**: ကွန်ပျူတာကို စာသား command တွေနဲ့ ထိန်းချုပ်တဲ့ interface။
*   **`huggingface_hub`**: Hugging Face Hub နဲ့ ချိတ်ဆက်ဖို့အတွက် Python client library။
*   **Logits**: Neural network ရဲ့ final output layer ကနေ ထွက်လာတဲ့ raw, unnormalized prediction scores တွေ။
*   **`sparse_categorical_crossentropy`**: Multi-class classification အတွက် အသုံးပြုသော loss function (labels တွေကို integer indices အဖြစ် ပေးတဲ့အခါ)။

