“ผมรักคุณ” เธอไม่เข้าใจ แต่เครื่องเข้าใจ

patharanor
Super AI Engineer
Published in
5 min readMar 28, 2021

หรืออาจเป็นเพราะว่าเราคุยกันคนละภาษา…

Assumed situation, thank you the article https://theconversation.com/love-in-the-time-of-algorithms-would-you-let-artificial-intelligence-choose-your-partner-152817 for the image.

การที่เราจะสื่อสารอะไรออกไปนั้น ย่อมเกิดจากสิ่งเร้าภายนอกมากระทำกับเรา ซึ่งกระบวนตั้งแต่ต้นจนจบประกอบไปด้วยการฟัง, คิด และพูด สิ่งเร้าในที่นี้คือบทสนทนาของคู่สนทนานั่นเอง โดยบทสนทนาที่เคยผ่านหูหรือเคยรับฟังมาก่อน เราจะรู้สึกว่ามันคุ้นๆ เพราะข้อมูลเหล่านี้เราเก็บไว้ใน คลังข้อมูล เรียนรู้ และนำมาวิเคราะห์ในอนาคต นั่นหมายถึง การที่เราจะสื่อสารอะไรออกไปสักอย่าง ย่อมมาจากข้อมูลในอดีตที่เคยได้รับฟัง หรือเรียนรู้มานั่นเอง

แล้วในอดีตเราคุยอะไรกัน จนทำให้วันนี้ ผมต้องบอกรักเธอ…

อันนี้ต้องขอออกตัวก่อนว่า sequence ข้างต้นที่มีการส่งข้อมูลจาก ASR -> NLP -> text-to-speech นั้น เป็นเพียงเหตุการณ์สมมุติเพื่อที่จะใช้ในการลำดับการอธิบายใน part ของ ASR , NLP และ text-to-speech เท่านั้น

การฟัง

เรามาเริ่มที่การฟังกันก่อน มนุษย์ทุกคนใช้หูในการรับสาร แต่สิ่งที่ผมคุ้นเคยนั้นผมจะใช้การถอดรหัสในแบบของผม ที่เคยเรียนรู้มาจาก auto-speech recognition (ASR) โดยถอดความจากเสียง แล้วจึงนำข้อความที่ได้ เหล่านั้นมาแปลความอีกทีหนึ่ง (“ผม” ในที่นี้คือ เจ้าหุ่นในภาพนะครับ)

จุดสำคัญของ speech-to-text อยู่ที่ part ของ decoding ประกอบไปด้วย 3-processes หลักๆ ดังนี้ :

  • Language model เป็นการกำหนดค่าคำหนึ่งๆว่าตามด้วยอะไรได้บ้าง เช่น “ฉัน” ตามด้วยคำว่า “อยาก” มีค่า probability 0.17 หรือ “ฉัน” ตามด้วยคำว่า “รัก” มีค่า probability 0.83 เป็นต้น
  • Pronoun dict เป็นการกำหนดว่าแต่ละคำมีคำอ่านว่าอย่างไร เช่น “ฉัน” ออกเสียงได้เป็น “ch a n^” และ “อยาก” ออกเสียงเป็น “j aa k^” เป็นต้น
  • Acoustic model กำหนดว่าหน่วยเสียงหนึ่งออกเสียงได้เป็นอย่างไร

ซึ่งการได้มาทั้ง 3-parts นั้นจำต้องนำเสียงพูดของคนกับคำ(word) มาให้ model เรียนรู้เสียก่อน โดยเสียงนั้นมีหลายโทนเสียง ทำให้การแปลงเสียงออกมาเป็นคำนั้นต่างกันออกไปตามค่าความน่าจะเป็น(probability) ที่เคยเรียนรู้นั่นเอง อาจจะมองในมุมที่เราฟังชาวต่างชาติคุยกันก็ได้ ในบางครั้งเจ้าของภาษาเขาพูดเร็วจนเราฟังไม่ทัน เราอาจจะมี moment ประมาณว่า “น่าจะพูดว่า…” อะไรก็ว่าไป นั่นแหละคือความน่าจะเป็นที่ผมพูดถึง ยิ่งถ้าเราฟังเยอะ เราก็จะคุ้นชินมากขึ้น จะเรียกว่า train ให้เยอะก็ไม่เชิง (แต่ ASR นั้นไซร้ … แค่ train อย่างเดียวไม่จบ ต้อง tune ด้วยจ้า T_T)

โดย tool ที่ใช้ train นั้นมีอยู่หลายตัว แต่ผมขออนุญาตแนะนำ Apache Kaldi เพราะนิยมใช้กันค่อนข้างมาก สามารถลองเล่นได้ที่นี่

ซึ่งตัว dataset ที่เป็นเสียงนั้นเอามาจาก CommonVoice ของทาง Mozilla ซึ่งมีอยู่หลายภาษา แต่อยากจะบอกว่าภาษาไทยยังไม่ค่อยมีคนรู้จักมากสักเท่าไหร่ ฉะนั้น dataset ที่เป็นเสียงไทยยังค่อนข้างมีน้อยอยู่

หากท่านใดสนใจสามารถเข้าไปขายเสียง เอ้ย !!! เพิ่มเสียง หรือมาช่วยตรวจสอบความถูกต้องของคำ กับเสียงพูด เพื่อให้ภาษาไทยเรามี dataset เยอะๆเหมือนภาษาอื่นๆ ได้ ที่นี่ ครับ

ตัว Apache Kaldi นั้น จะมีการปรับจูนค่าตอน train ให้เหมาะกับ dataset เอาไว้แล้วระดับนึงสำหรับภาษาอังกฤษ นั่นหมายถึงเราต้องมานั่งปรับจูนค่าใหม่ให้เหมาะกับ dataset ภาษาไทยของเรานั่นเอง T_T

ส่วนที่เราจะต้องปรับจูนกันอยู่ในส่วนของ acoustic model training ซึ่งมีทั้งหมด 5 ส่วนด้วยกัน ดังนี้ :

  • monophone: เรียนรู้แค่ phone นั้นๆ
  • tri1 : เพิ่ม delta feature เข้ามา ที่คาดหมายคือ เพิ่ม feature แล้วจะทำให้มันเรียนรู้ได้ดีขึ้น
  • tri2b : ตัวนี้จะเอาปัจจัยเสียงรอบข้างมาใช้ในการเรียนรู้ด้วย(ทำ transform โดย train ด้วย LDA+MLLT system)
  • tri3b : อ้างอิงเสียงผู้พูดเข้ามาใช้ในการเรียนรู้ด้วย (ทำ LDA+MLLT+SAT โดยอิง feature ของผู้พูดด้วยเราจะเห็น boudary ของ phone มีการขยับ)
  • tri4b : คล้าย tri3b แต่ต่างกันที่มีการปรับขนาดฐานข้อมูล เพิ่มหรือลดถึงจะดี อันนี้ต้องลองปรับจูนกันเองเนื่องจาก dataset ที่ใช้นั้นอาจต่างกัน ส่วนนี้สามารถลด Word Error Rate(WER) ได้

เมื่อ signal ที่ผ่าน model ที่เรา train มาเมื่อข้างต้นแล้ว เราจะได้เป็นคำๆออกมา เท่านี้ก็จบ part ของ ASR แล้ว

แค่ฟังก็เหนื่อยแล้ว จริงๆแล้วรายละเอียดส่วนของ ASR นั้นยังมีรายละเอียดอีกมาก ถ้ามีโอกาสผมจะมาอธิบายเพิ่มเติมอีกทีหนึ่ง เรามาดูส่วนของการคิดกันต่อดีกว่า

การคิด

หลังจากที่เราแปลงเสียงมาเป็นข้อความแล้ว ข้อความเหล่านี้จะถูกนำมาเข้า NLP pipeline โดย NLP เป็นกระบวนการนึงที่ใช้ความรู้ทางด้านภาษาศาสตร์ (linguistics) เข้ามาช่วยในการตีความ input ในรูปของประโยคแบบที่มนุษย์ได้ยิน ออกมาเป็นๆคำๆ(tokenization) และหาความสอดคล้องกันระหว่างคำใดๆ เพื่อที่จะเชื่อมโยงไปสู่คำตอบของประโยคนั้นๆ ซึ่งมี step ดังนี้

  • Sentence Segmentation — เป็นการแยกประโยคหลายๆประโยค ออกเป็นประโยคย่อยๆ หรือหา end of sentence (EOF) ยกตัวอย่างเช่น ในภาษาอังกฤษนั้นอาจจะเป็น “.” หรือ “,” แต่ในภาษาไทยนี่ยากเลย หาจุดสิ้นสุดประโยคมาก
  • Word Tokenization — หลังจากที่เราได้ประโยคมาแล้ว เราก็แยกเป็นคำๆต่อ สำหรับภาษาอังกฤษจะมีเว้นวรรคก็ดูจะ make sense ในการตัดอยู่ แต่ในภาษาไทยนี่ยากอีกแล้ว เพราะภาษาไทยดิ้นได้เยอะอยู่ เช่น ตากลม มันหมายถึง “ตา” + “กลม” หรือ “ตาก” + “ลม” T_T
  • Parts of Speech — หรือ POS เป็นการระบุหรือ add tag ให้คำนั้นๆ ว่าเป็น part ไหนของ speech ซึ่งประกอบไปด้วย nouns, pronouns, adjectives, verbs, adverbs, prepositions, conjunctions และ interjections แล้วเราจะระบุไปทำไม? ระบุไว้เพื่อให้ทราบ grammar ของประโยคนั่นเอง
ตัวอย่าง POS ในภาษาไทย
  • Text Lemmatization — หรือ Lemma เป็นการแปลงคำให้อยู่ในรูปฟอร์มพื้นฐานที่มีอยู่ใน dictionary โดยวิเคราะห์จากหลักไวยกรณ์ของภาษานั้นๆ ในการแปรคำ ผันคำ เพื่อกำจัด Inflection ของคำ เช่น เพศ, Tense, เสียง, อารมณ์, จำนวน และอื่นๆ
  • Identifying Stop Words — ตัว stop word เป็นคำที่พบบ่อยในประโยค แต่ไม่ได้มีผลในการสื่อความหมายสักเท่าไร ถ้าในภาษาไทยก็ เช่น “นี้”, “นํา”, “นั้น”, “นัก”, “นอกจาก”, “ทุก”, “ที่สุด”, “ที่”, “ทําให้”, “ทํา”, “ทาง”, “ทั้งนี้”, “ดัง”, “ซึ่ง”, …, “และ”, “แรก”, “แบบ”, “ๆ” เป็นต้น คำเหล่านี้จะถูกลบออกเพื่อให้ข้อความมีขนาดเล็กลง ทำให้ process ได้ไวขึ้น แต่ก็อาจจะทำให้ความหมายบางอย่างที่เกี่ยวข้องกับคำดังกล่าวหายไปได้ด้วย (stop word ไม่เหมาะที่จะใช้ใน deep learning เพราะอาจทำให้ performance ตกได้)
  • Dependency Parsing — ในส่วนนี้จริงๆอธิบายกันยาว แต่คร่าวๆคือในประโยคหนึ่งๆที่เราถอดความออกมาเป็นคำด้วย process ที่ผ่านมาแล้วข้างต้น คำแต่ละคำจะมีการเชื่อมโยงกันผ่าน grammar ของภาษานั้นๆ เช่น “ผมรักคุณ” จะมี part ของ ประธาน + กริยา + กรรม โดยที่ “รัก” สัมพันธ์กับ “ผม” และ “รัก” สัมพันธ์กับ “คุณ” จากตัวอย่าง root ของความสัมพันธ์เริ่มที่คำว่า “รัก” หรือก็คือ verb นั่นเอง สิ่งเหล่านี้เป็นโครงสร้างของ grammar โดยมากจะอธิบายผ่านทาง tree เจ้าตัว dependency parsing นี้จะเข้ามา extract sentence ของ tree ดังกล่าว เพื่อให้ได้ความหมายตาม grammar ที่ควรจะเป็นนั่นเอง
  • Named Entity Recognition — หรือ NER ใช้ในการระบุชนิดของคำๆนั้น และจัดหมวดหมู่ของคำ เช่น Thailand => Place เป็นต้น
  • Coreference Resolution — เป็นการหาคำที่มีความหมายเดียวกันในประโยค part นี้ค่อนข้างสำคัญใน high level (พวก deep learning) ซึ่งจะใช้ในการสรุปใจความของ content ใดๆ, ทำระบบถามตอบ รวมถึงสกัดข้อมูลที่สำคัญๆออกมาจากบทความ เป็นต้น

จาก step ข้างต้น ถ้าเป็นภาษาไทย ท่านสามารถเรียกใช้ผ่าน PyThaiNLP library ได้เลยหรือจะใช้ API ของ AI for Thai ได้เช่นกัน

part ที่กล่าวมาข้างต้นจะออกไปในแนวๆของ rule-based อยู่ แต่จะเป็น input ที่สำคัญในการให้เครื่องได้เรียนรู้ “แล้วเราเรียนรู้กันยังไง ?”

หากใครที่เกิดมาในยุค 2017 เป็นยุคของ transformer ซึ่งกระบวนการเรียนรู้ใน NLP นั้นจะใช้หลักการของ attention (จาก paper ของนักวิจัยของ Google ในหัวข้อ Attention Is All You Need) เสียเป็นส่วนใหญ่

Multi-head attention architecture
Transformer architecture

ซึ่งได้ผลดีกว่าหลักการเดิมที่ใช้ RNN และ CNN(ที่มีปัญหาในเรื่องของการใช้งาน GPU และ Vanishing Gradient ที่ทำให้ข้อมูลบางส่วนหายไปหากรูปประโยคมี content ที่ค่อนข้างยาว) พร้อมยังเพิ่มประสิทธิภาพในการ เรียนรู้รูปประโยคแบบ sequence-to-sequence (Seq2Seq) ที่ใช้ RNN ได้เป็นอย่างดี

Sequence-to-Sequence with RNN และตัวอย่างประโยคที่ส่งเข้ามา (ฝั่ง encoder), ตัว AI จะตอบออกมา(ฝั่ง decoder) ด้วยคำที่มีความน่าจะเป็นของความใก้ลเคียงกันกับคำที่ส่งเข้ามา

เพราะแทนที่เราจะต้องตัดคำบางคำออกซึ่งอาจจะทำให้ความหมายมันหายไป ตัว attention สามารถที่จะยัดประโยคเข้าไปได้ทั้งประโยคได้เลย

ตัว transformer จะใช้หลักการของ multi-head attention ซึ่ง input ที่เข้ามาจะผ่านมายัง embedding layer ก่อน ในชั้นนี้เปรียบเสมือนคลังข้อมูลที่มีคำศัพท์มากมาย แต่มันไม่ได้อยู่ในรูปของ string หรือ text แต่อย่างใด โดยคำหนึ่งคำใดๆ จะถูกแปลงเป็นชุดตัวเลขชุดหนึ่ง หรือก็คือ vector ฉะนั้นยิ่งเรียนรู้คำมากเท่าไหร่ คำต่างๆก็จะถูกแปลงให้อยู่ในรูปของ vector แล้วมาอยู่ใน vector space เดียวกันนั่นเอง โดยคำที่มีใก้ลเคียงกันมักจะอยู่ในตำแหน่งที่ใก้ลๆกัน (ตัวเลข vector เหล่านั้นมาจากการคำนวณความน่าจะเป็นของคำๆนั้นใน context)

ภาพตัวอย่างการแปลง word เป็นเป็น vector

อันนี้เป็น embedding ใน vector space ของผม…

มาถึงพระเอกของเราคือตัว attention

ทำหน้าที่ focus คำทุกคำในประโยคมาเปรียบเทียบกันเอง แล้วเลือก word ที่เหมาะสมออกไป มันจะขึ้นอยู่กับ 3 ส่วนด้วยกัน คือ Q จะทำ dot product กับ K เพื่อหาว่า word vector ตัวไหน ใก้ลเคียงกับ wording นั้นมากที่สุด เพื่อที่จะนำไป match กับ V โดยที่:

  • Query(Q) อยู่ฝั่ง decoder
  • Key(K) และ Value(V) อยู่ใน encoder

สำหรับ encode/decode สามารถมีได้หลาย dimension ยึงลึกยิ่งแม่น (multi-head) แนวคิดนี้เรียก Self-Attention

หลังจากนั้นก็เอาค่าเหล่านั้นเข้า Feed Forward ของ Transformer ซึ่งในเคสนี้ คือ fully connected layer ธรรมดา ๆ ตรงส่วนนี้ทำให้เรายัดประโยคเข้าไปทีเดียวได้เลย ไม่ต้องใส่ทีละ token แบบที่ใช้ RNN

output ที่ได้จะถูกส่งเข้า softmax เพื่อ predict token ถัดไปตามความน่าจะเป็นที่ได้

ภาพตัวอย่าง กระบวนการทำงานของ transformer และตัวอย่าง input/output

ร่ายมาตั้งยาว ผมลืมบอกไปว่าผมมักจะได้ยินประโยคเหล่านี้จากเธอบ่อยๆ …


ฉันมักจะถามเธอเป็นประจำว่าเธอนะรักฉันมั้ย
และหากว่าเธอน่ะบอกว่ารักแล้วเธอน่ะรักแค่ไหน
รักเท่าฟ้าหรือมหาสมุทร
รักเท่าผืนดินหรือผืนน้ำรักฉันที่สุด

ให้บอกว่ารักเท่าจักรวาลมันก็ยังไม่พอ
ก็อยากได้ยินเธอพูดซ้ำ
Like I never heard that before
ก็อยากได้ยินมันทุกวัน
อยากได้ยิน เพียงเธอบอกรักฉันได้มั้ยเธอ

มันทำให้ผมอยากบอกรักเธอจัง…

แต่จะว่าไปประโยคที่เธอพูดมีเนื้อหาคล้ายๆกับเพลง “รักเมียที่สุดในโลก” ของ illslick ที่น้อง Bell cover เหลือเกิน 🤔

หรือที่จริงแล้ว เธอแค่ร้องเพลงให้ผมฟังเท่านั้น…

เอ่ะ!!! หรือเธอแค่กำลัง train ข้อมูลให้ผมอยู่ >,<

การพูด

Part นี้ผมยังมีข้อมูลไม่มากนัก จึงจะขอเน้นไปในส่วนของการแนะนำ APIs หรือ tools แทน ซึ่งในปัจจุบันมีการนำเอาภาษาไทยมาทำ text-to-speech ที่ smooth มากกว่า Siri มีดังนี้ :

ก่อนจบ

ต้องขออภัยทุกท่านไว้ก่อนเลย ด้วยตัวเนื้อหาจริงๆนั้นละเอียดกว่านี้มาก แต่ด้วยระยะเวลาที่จำกัด ผมเลยยกภาพรวมและหยิบบางส่วนมาเป็นน้ำจิ้มเท่านั้น ถ้ามี part ต่อไปจัดหนักแน่นอนจ้า ขอบคุณทุกท่านที่อ่านมาถึงหัวข้อนี้ครับ

--

--

patharanor
Super AI Engineer

Software Development Lead | Cert. Advance Super AI Engineer session 1 — https://www.patharanor.dev