สวัสดีครับทุกท่าน บทความนี้เราจะไปทดลองทำ Thai Romanization ด้วย keras ใน Python กันครับ
Romanization คืออะไร ?
Romanization เป็นการถอดเสียงมาเป็นอักษรโรมัน ตัวอย่างการนำ Romanization มาใช้ เช่น โปรแกรมร้องคาราโอเกะ เป็นต้นสำหรับการถอดเสียงภาษาไทยมาเป็นอักษรโรมัน แม้มีเอกสารของราชบัณฑิตยสถาน กำกับแนวทางไว้ แต่ก็ไม่ใช่เรื่องง่าย เพราะภาษาไทยไม่มีการแบ่งคำ , มีพยางค์กับกฎการออกเสียงที่ซับซ้อน และคำหลาย ๆ คำออกเสียงไม่ตรงกับรูป จึงทำให้การพัฒนากฎการถอดเสียงภาษาไทยมาเป็นอักษรโรมันเป็นเรื่องที่ซับซ้อนอย่างมาก
ทางออกของเรานั้นคือ Deep learning โดยใช้ seq2seq ระดับตัวอักษร
เนื่องจากบทความนี้เป็นบทความที่บอกรายละเอียดในการทำเท่านั้น ไม่ขออธิบายทฤษฎีหรือกระบวนการทำงาน
เตรียมข้อมูล
ให้ทำการโหลดรายการคำภาษาไทยจากอะไรก็ได้มาประมาณเท่าที่ต้องการ บรรทัดละ 1 คำ แล้วบันทึกเป็นไฟล์ txtแล้วทำการติดตั้งโปรแกรม Thai Romanization จาก http://pioneer.chula.ac.th/~awirote/resources/thai-romanization.html
ทำการเปิดโปรแกรมขึ้นมาแล้วไปเมนู Create > Romanized File เลือกไฟล์ที่บันทึกไว้แล้วรอสักครู่ (ขึ้นอยู่กับขนาดไฟล์) เสร็จแล้วจะได้ไฟล์นามสกุล .rom เป็นไฟล์ Romanization
จากนั้นให้ทำรวมไฟล์ txt กับ .rom เข้าเป็นไฟล์เดียวกัน โดยข้อมูลกับ Romanization คู่กันแล้วแยกกันด้วย \t ตัวอย่างเช่น
แมว manoเนื่องจากผมทำหลายไฟล์ทำให้ได้ไฟล์ข้อมูลข้อมูลหลายไฟล์ ผมจึงสร้าง database ด้วย SQLite ขึ้นมา ตั้งชื่อว่า dataset.db และสร้างตาราง data ตามโค้ดดังนี้
คน khon
เสร็จแล้วเขียนโค้ดดึงข้อมูลจากไฟล์ txt และ rom เข้าไปเก็บใน Database ด้วยโค้ดดังนี้
ดึงข้อมูลจาก Databse กลับมาเขียนเป็น csv ไฟล์ตามรูปแบบไฟล์ดังนี้
กองพันทหารปืนใหญ่ kongphanthahanpuenyai
วิฑูรย์ withun
เมตาบอลิสม metabolisom
บ้านหนองเลา bannonglao
อายุษ ayut
แทมปา thaempa
ใช้โค้ด
เราจะได้ data.csv เป็นข้อมูลสำหรับนำไป Train สำหรับทำ Thai Romanization ด้วย keras
Train ข้อมูล
เราจะโค้ดตามเอกสาร A ten-minute introduction to sequence-to-sequence learning in Keras (https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html) ซึ่งทำงานด้วย Sequence-to-sequence learning (Seq2Seq) ในระดับตัวอักษร (character) โดยเป็น LSTMทำการโหลดโค้ดมาจาก https://github.com/keras-team/keras/blob/master/examples/lstm_seq2seq.py
แล้วดัดแปลงโค้ดตรงตัวแปร data_path , num_samples และ epochs
- data_path เปลี่ยน path เป็น ''data.csv"
- num_samples เปลี่ยนเป็นจำนวนบรรทัดทั้งหมดในไฟล์ ''data.csv"
- epochs จำนวนการ Train เปลี่ยนตามความต้องการ
ไฟล์ data.csv ของผม คือ https://github.com/wannaphong/thai-romanization/blob/master/dataset/data.csv มีทั้งหมด 648,241 บรรทัด ผมเปลี่ยนได้ดังนี้
เมื่อรัน
Number of samples: 648240รันโค้ด train หาก train เสร็จไม่มีปัญหาอะไรจะได้ไฟล์ s2s.h5 เป็นไฟล์ model ของ Thai Romanization ที่เราทำขึ้นมา
Number of unique input tokens: 91
Number of unique output tokens: 39
Max sequence length for inputs: 76
Max sequence length for outputs: 90
Train on 518592 samples, validate on 129648 samples
Epoch 1/20
64/518592 [..............................] - ETA: 2:20:15 - loss: 0.7373
128/518592 [..............................] - ETA: 1:16:17 - loss: 0.7081
192/518592 [..............................] - ETA: 54:47 - loss: 0.7065
256/518592 [..............................] - ETA: 44:45 - loss: 0.6996
320/518592 [..............................] - ETA: 38:45 - loss: 0.7010
ใช้งาน Model
โหลดโค้ดจาก https://github.com/keras-team/keras/blob/master/examples/lstm_seq2seq_restore.py มาดัดแปลงตามโค้ดข้างบน แล้วรันNumber of samples: 648240เสร็จแล้วเขียนโค้ดเพิ่มเติมเข้าไปใน lstm_seq2seq_restore.py เพื่อให้สามารถรับ ข้อความภายนอก ที่ต้องการแปลงไปเป็น Romanization ได้
Number of unique input tokens: 91
Number of unique output tokens: 39
Max sequence length for inputs: 76
Max sequence length for outputs: 90
-
Input sentence: คน
Decoded sentence: khon
เวลานำไปใช้งาน เพียงแค่ใช้คำสั่ง rom(ข้อความ) เท่านี้เราก็ได้ Thai Romanization สำหรับใช้งานแล้ว
rom("แมว")
ผลลัพธ์
แมว\n
ปัญหาที่อาจจะพบในการทำ Thai Romanization ด้วย keras
1. ปัญหา MemoryError เช่น
Traceback (most recent call last):เพราะในการ train เป็น train ระดับตัวอักษร ทำให้เกิดการจอง array ในหน่วยความจำขนาดใหญ่มากเกินกว่าที่หน่วยความจำในเครื่องที่ train หรือเครื่องที่เรียกใช้งานจะรับข้อมูลเข้าหน่วยความจำไหว
File "using.py", line 68, in <module>
dtype='float32')
MemoryError
มีทางแก้ 2 วิธี
- เพิ่มแรม
- ลดความยาวสตริงที่ใช้ในการ train
30 ตัวอักษรในฝั่งภาษาไทย ส่วน Romanization ไม่ให้ถึง 90 ตัวอักษร
สำหรับใช้งานได้สำหรับเครื่องแรมขั้นต่ำ 6 GB
2. อยากปรับ % validate
ให้ทำการแก้ไขโค้ด
model.fit([encoder_input_data, decoder_input_data], decoder_target_data,ตรง validation_split โดยพารามิเตอร์นี้เป็นพารามิเตอร์สำหรับแบ่งข้อมูลมา validate จำนวน 0.2 หรือ 20 % ให้ปรับแก้ตรงนี้ตามความต้องการ
batch_size=batch_size,
epochs=epochs,
validation_split=0.2)
3. ปรับจาก LSTM เป็น GRU layer ทำตาม https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html
โค้ดทั้งหมดอยู่ที่ https://github.com/wannaphong/thai-romanization
หากไม่ต้องการ Train ข้อมูลเอง สามารถใช้งาน thai2rom ได้ ผ่าน PyThaiNLP ดังนี้ https://github.com/PyThaiNLP/pythainlp_notebook/blob/master/thai2rom.ipynb
อ่านรายละเอียดเพิ่มเติมเกี่ยวกับ A ten-minute introduction to sequence-to-sequence learning in Keras ได้ที่ https://blog.keras.io/a-ten-minute-introduction-to-sequence-to-sequence-learning-in-keras.html
0 ความคิดเห็น:
แสดงความคิดเห็น
แสดงความคิดเห็นได้ครับ :)