ใน ep นี้เราจะมาศึกษาอีก Concept นึงที่สำคัญของ NLP คือ Language Model หรือ โมเดลของภาษา ซึ่งถ้าโมเดลของเรามีความสามารถที่จะเข้าใจภาษาโดยภาพรวมได้ดีระดับหนึ่งแล้ว ก็จะส่งผลให้โมเดลนั้นทำงานเฉพาะทาง เช่น Classification, Sentiment Analysis, Machine Translation, Question-Answer ได้ดีขึ้นไปด้วยในตัว
Language Model คืออะไร

Language Model คือ โมเดลว่าภาษานั้นเป็นอย่างไร ในทางสถิติคือ Probability Distribution ของลำดับของคำต่าง ๆ ว่าน่าจะเป็นคำอะไร เช่น ถ้าเราเข้าใจภาษาอังกฤษบ้าง เราก็จะพอเดาได้ว่าคำอะไรน่าจะอยู่ในช่องว่าง Somsak is a tall ______. และคำอะไรไม่น่าจะอยู่
ในทางปฏิบัติ เราสามารถใช้วิธี Bag-of-word ดูทีละคำ (Uni-Gram) ทีละหลาย ๆ คำ N-Gram ดูคำที่มาก่อน ดูคำที่มาทีหลัง หรือทั้งสองทิศทาง Bi-direction และใช้โมเดลคณิตศาสตร์ได้หลากหลาย
แต่ในเคสนี้ เราจะใช้ Neural Network แบบ Recurrent Neural Network – RNN แบบหนึ่ง เรียกว่า AWD_LSTM ที่ถูกเทรนด้วย Corpus ข้อความจาก Dumps Wikipedia ภาษาไทย โดยให้โมเดลเดาคำต่อไปเรื่อย ๆ (เป็น Label แบบ Self-supervised Learning)
เมื่อเราได้ Language Model จาก Wikipedia ภาษาไทย มาแล้ว เราสามารถใส่ข้อความภาษาไทยเริ่มต้นเข้าไปให้ Language Model เดาคำที่น่าจะเป็นคำต่อไป หรือก็คือ Generate Text สร้างข้อความใหม่ต่อ ๆ ไปได้
AWD_LSTM Model Architecture

AWD_LSTM เป็น LSTM / Recurrent Neural Network (RNN) แบบหนึ่ง ที่มีการใช้ DropOut / DropConnect หลากหลายแบบภายในส่วนต่าง ๆ ของโมเดล อย่างชาญฉลาด จะอธิบายต่อไป

เรามาเริ่มกันเลยดีกว่า
ใน ep นี้เราจะมาศึกษาอีก Concept นึงที่สำคัญของ NLP คือ Language Model หรือ โมเดลของภาษา ซึ่งถ้าโมเดลของเรามีความสามารถที่จะเข้าใจภาษาโดยภาพรวมได้ดีระดับหนึ่งแล้ว ก็จะส่งผลให้โมเดลนั้นทำงานเฉพาะทาง เช่น Classification, Sentiment Analysis, Machine Translation, Question-Answer ได้ดีขึ้นไปด้วยในตัว
Language Model คืออะไร¶
Language Model คือ โมเดลว่าภาษานั้นเป็นอย่างไร ในทางสถิติคือ Probability Distribution ของลำดับของคำต่าง ๆ ว่าน่าจะเป็นคำอะไร เช่น ถ้าเราเข้าใจภาษาอังกฤษบ้าง เราก็จะพอเดาได้ว่าคำอะไรน่าจะอยู่ในช่องว่าง Somsak is a tall _. และคำอะไรไม่น่าจะอยู่
ในทางปฏิบัติ เราสามารถใช้วิธี Bag-of-word ดูทีละคำ (Uni-Gram) ทีละหลาย ๆ คำ N-Gram ดูคำที่มาก่อน ดูคำที่มาทีหลัง หรือทั้งสองทิศทาง Bi-direction และใช้โมเดลคณิตศาสตร์ได้หลากหลาย
แต่ในเคสนี้ เราจะใช้ Neural Network แบบ Recurrent Neural Network - RNN แบบหนึ่ง เรียกว่า AWD_LSTM ที่ถูกเทรนด้วย Corpus ข้อความจาก Dumps Wikipedia ภาษาไทย โดยให้โมเดลเดาคำต่อไปเรื่อย ๆ
เมื่อเราได้ Language Model จาก Wikipedia ภาษาไทย มาแล้ว เราสามารถใส่ข้อความภาษาไทยเริ่มต้นเข้าไปให้ Language Model เดาคำที่น่าจะเป็นคำต่อไป หรือก็คือ Generate Text สร้างข้อความใหม่ต่อ ๆ ไปได้
0. Install¶
! nvidia-smi
ติดตั้ง Library ที่จำเป็น
! pip install sklearn_crfsuite -q
! pip install https://github.com/PyThaiNLP/pythainlp/archive/dev.zip -q
! pip install fastai2 -q
! pip install emoji -q
1. Import¶
from fastai2.basics import *
from fastai2.text.all import *
from pythainlp.ulmfit import *
from pythainlp.tokenize import THAI2FIT_TOKENIZER
2. Dummy Dataset¶
สั่ง Download Dummy Dataset ขนาดเล็ก มาสำหรับใช้สร้าง Model แต่เราจะไม่ได้ใช้ Dataset ส่วนนี้มาทำงานอะไร เพราะเป็นภาษาอังกฤษ
imdb = untar_data(URLs.IMDB_SAMPLE)
dummy_df = pd.read_csv(imdb/'texts.csv')
# dummy_df.head()
3. Data pipeline¶
class XThaiTokenizer():
def __init__(self, lang: str = "th", split_char=' ', **kwargs):
self.split_char=split_char
self.lang = lang
def __call__(self, items): return (THAI2FIT_TOKENIZER.word_tokenize(t) for t in items)
def add_special_cases(self, toks):
pass
โหลด Vocab Dictionary ของ Wikipedia ภาษาไทย เตรียมเอาไว้ใส่ใน Data Pipeline เนื่องจากเราจะใช้ Pre-train Model เราจึงต้องใช้ Vocab เดียวกันกับโมเดลนั้น ๆ
thwiki_vocab = pickle.load(open(THWIKI_LSTM['itos_fname'],'rb'))
len(thwiki_vocab), thwiki_vocab[:20]
สร้าง Data Pipeline ด้วย fastai2 DataBlock API โดยใส่ tokenizer และ vocab จากด้านบน
imdb_lm = DataBlock(blocks=TextBlock.from_df('text', is_lm=True, tok_func=XThaiTokenizer, vocab=thwiki_vocab, sep=''),
get_x=ColReader('text'),
splitter=ColSplitter())
# imdb_lm.summary(dummy_df, bs=64, seq_len=72)
สร้าง DataLoader จาก DataBlock
dls = imdb_lm.dataloaders(dummy_df, bs=64, seq_len=72)
เช็คขนาด Vocab ของ DataLoader อีกที จะเห็นว่าเท่ากันกับ Vocab จาก Wikipedia ภาษาไทย ที่เราโหลดมา
len(dls.vocab)
เราสามารถเรียก show_batch ดูข้อมูลได้ แต่เนื่องจาก Dataset ภาษาอังกฤษ แต่ตัดคำไทย Vocab Dictionary เป็นภาษาไทย อาจจะมีคำภาษาอังกฤษน้อย คำที่ไม่อยู่ใน Vocab ก็จะกลายเป็น UNK ไปหมด
# dls.show_batch(max_n=5)
4. Model¶
สร้าง Language Model Learning ด้วยโมเดล AWD_LSTM โดยกำหนด Hyperparameter ให้ตรงตาม Pre-trained คือ emb_sz=400, n_hid=1550, n_layers=4, pad_token=1 แต่ไม่ต้องโหลด Weight มาด้วย pretrained=False
# language_model_learner??
# AWD_LSTM??
config = dict(emb_sz=400, n_hid=1550, n_layers=4, pad_token=1, tie_weights=True, out_bias=True,
output_p=0.25, hidden_p=0.1, input_p=0.2, embed_p=0.02, weight_p=0.15)
trn_args = dict(drop_mult=0.9, clip=0.12, alpha=2, beta=1)
learn = language_model_learner(dls, AWD_LSTM, config=config, pretrained=False, **trn_args)
ดูสถิติโมเดล
learn.summary()
5. Load Pretrained Model¶
โหลด Weight และ Vocab ของ Pre-trained Model จากใน pythainlp.ulmfit เราจะได้โมเดลที่เข้าใจ ภาษาไทยใน Wikipedia มาเรียบร้อย
# THWIKI_LSTM??
learn.load_pretrained(THWIKI_LSTM['wgts_fname'], THWIKI_LSTM['itos_fname'])
6. Generate Text¶
เมื่อเราได้โมเดลที่โหลดทุกอย่างเรียบร้อย พร้อมทำงาน เราจะมาลอง Generate Text กัน
ตัวอย่าง 1¶
print(learn.predict('ประวัติศาสตร์ไทย เริ่มต้นขึ้นเมื่อ', 200, temperature=0.8))
ตัวอย่าง 2¶
Generate 5 ครั้ง เพื่อเปรียบเทียบ
TEXT = "ประวัติศาสตร์ไทย เริ่มต้นขึ้นเมื่อ"
N_WORDS = 50
N_SENTENCES = 5
preds = [learn.predict(TEXT, N_WORDS, temperature=0.6)
for _ in range(N_SENTENCES)]
preds
ตัวอย่าง 3¶
เราสามารถปรับ temperature เพื่อให้ได้คำที่หลากหลายยิ่งขึ้น
TEXT = "ประวัติศาสตร์ไทย เริ่มต้นขึ้นเมื่อ"
N_WORDS = 50
N_SENTENCES = 5
preds = [learn.predict(TEXT, N_WORDS, temperature=0.9)
for _ in range(N_SENTENCES)]
preds
Credit¶