การจำแนกเสียงพูดและเสียงเพลงด้วยโมเดล Siamese Networks
ในบทความก่อนหน้า เราได้ทดลองใช้ Convolutional Neural Network (CNN) เพื่อจำแนกเสียงพูดและเสียงเพลง ในวันนี้เราจะมาทดลองจำแนกเสียงพูดและเสียงเพลงโดยใช้โมเดล Siamese networks
ซึ่งโดยปกติส่วนใหญ่เราจะพบเห็นการใช้งานโมเดล Siamese networks ในงานเกี่ยวกับรูปภาพ ดังนั้นในบทความนี้เราจึงจะลองนำเอาโมเดล Siamese networks ไปประยุกต์ใช้ที่เกี่ยวกับเสียงบ้าง (แต่จริงๆ เราก็ใช้วิธีแปลงเสียงให้มีหน้าตาข้อมูลคล้ายกับข้อมูลรูปภาพอยู่ดี อิอิ)
ก่อนจะไปเขียนโค้ดกันเราไปรู้จักกันก่อนว่าโมเดล Siamese networks เป็นอย่างไร และเราจะนำข้อมูลที่เป็นเสียงมาใช้ต้องทำอย่างไร
Siamese Networks คืออะไร?
ปัญหาอย่างหนึ่งที่เรามักเจอเมื่อเทรนโมเดล Classification ด้วยเทคนิค Deep learning คือต้องอาศัยข้อมูลตัวอย่างปริมาณมากในแต่ละคลาสมาเทรนข้อมูล เพื่อให้ได้โมเดลที่ทำงานได้ใกล้เคียงกับความสามารถของมนุษย์ ซึ่งในโลกความเป็นจริงนั้นๆ ไม่ใช่ว่าทุกปัญหาจะมีข้อมูลตัวอย่างในปริมาณที่มากพอที่จะทำให้ได้โมเดลที่แก้ปัญหานั้นได้อย่างถูกต้อง (ในบทความนี้เรายังไม่มองถึงการใช้เทคนิค Transfer learning นะครับ) ดังนั้นในช่วงไม่กี่ปีที่ผ่านมาเริ่มมีงานวิจัยที่ทำออกมาแก้ปัญหาดังกล่าว ซึ่งอาศัยข้อมูลตัวอย่างเพียงไม่กี่ตัวอย่างในแต่ละคลาสเพื่อมาทำนายข้อมูลที่ไม่มีป้ายกำกับ โดยใช้เทคนิคการเรียนรู้แบบ Meta learning
Meta learning เป็นเทคนิคการเรียนที่มีความเกี่ยวข้องกับเทคนิค Deep learning ซึ่งโมเดลที่ได้จากเทคนิคนี้เรียกได้ว่าเป็นโมเดลอเนกประสงค์มากๆ เพราะเมื่อเทรนโมเดลไปแล้วครั้งหนึ่ง ก็สามารถที่จะนำโมเดลดังกล่าวไปใช้เพื่อแก้ปัญหาในงานที่มีลักษณะใกล้เคียงกับโมเดลนั้น โดยไม่จำเป็นต้องเทรนอะไรเพิ่มเติมอีก จำเห็นได้ว่ากระบวนการเรียนรู้ของ Meta learning นั้นจะค่อนข้างใกล้เคียงกับมนุษย์มาก เพราะปกติมนุษย์เพียงได้เห็นหรือได้ยินอะไรเพียงแค่ไม่กี่ครั้งก็สามารถจำแนกได้แล้วว่าภาพหรือเสียงนั้นคืออะไร
โมเดลหนึ่งที่นิยมนำมาประยุกต์ใช้คือ Siamese networks ซึ่งคำว่า Siamese ก็มาจาก “แฝดสยาม อิน-จัน” ที่เป็นที่รู้จักของฝรั่ง ถ้าพูดแบบนี้เราก็พอจะรู้แล้วว่าโมเดลนี้จะมีการเทรนโมเดลที่จะใช้การเปรียบเทียบ embeddings 2 ตัวพร้อมกันในการคำนวณหา loss
โดย Objective ของ loss function ของโมเดลนี้คือพยายามเพิ่มระยะห่างระหว่างกลุ่มหรือลดระยะห่างภายในกลุ่มเดียวกัน
ทั่วไปแล้วโมเดล Siamese networks ประกอบด้วย sub-network 2 ตัวที่มีโครงสร้างและคอนฟิกที่เหมือนกันจึงทำให้ต้องการปริมาณข้อมูลตัวอย่างที่น้อยลงและมีแนวโน้มที่จะเกิด overfitting ที่น้อย หน้าที่หลักของ sub-network นั้นมีไว้สำหรับสกัดคุณลักษณะเวกเตอร์ (N✕1)
เมื่อได้ผลลัพธ์แล้วก็ได้ตัวชี้วัดบางอย่าง (เช่น Euclidean distance, Cosine similarity, Manhattan เป็นต้น) มาเปรียบเทียบความคลายคลึงของคุณลักษณะเวกเตอร์ทั้งสอง (ยิ่งคล้ายคลึงกันระยะห่างก็ยิ่งใกล้ 0)
เราจะนำข้อมูลเสียงมาใช้ได้อย่างไร?
ในการจำแนกข้อมูลที่เป็นเสียง เราไม่สามารถนำข้อมูลเสียงดิบมาเป็น input ให้กับโมเดลได้โดยตรง ดังนั้นเราจึงต้องนำข้อมูลเสียงเหล่านั้นมาผ่านกระบวนการบางอย่างก่อนนำไปใช้งาน โดยสามารถแบ่งได้เป็น 2 รูปแบบ:
- Time domain - แต่ละ sample จะแสดงถึงการเปลี่ยนแปลงของสัญญาณเสียง เทคนิคที่ใช้กันเช่น Central Moments, Zero-Crossing Rate, Root Mean Square Energy, Tempo เป็นต้น
- Frequency domain - ในแต่ละ timestamp จะแสดงถึงค่า amplitude สำหรับความถึ่นั้นๆ เทคนิคที่ใช้กันเช่น Mel-Frequency Cepstral Coefficients, Chroma, Spectral Centroid, Spectral Contrast, Spectral Bandwidth เป็นต้น
ถึงแม้ว่าในหลายเทคนิคจะมีความสามารถในการเรียนรู้จาก Feature ได้ดีก็ตาม แต่เราก็ควรจะเลือกใช้วิธีการสกัดคุณลักษณะสำคัญ (Feature Extraction) ที่เหมาะสมและตอบโจทย์กับงานของเรามากที่สุด ในปัจจุบันสำหรับแอพพลิเคชั่นส่วนใหญ่มักจะเลือกใช้วิธีการสกัดคุณลักษณะแบบ Frequency domain เพื่อนำเสนอข้อมูลเสียง
เรามาเริ่มกันเลยดีกว่า :)
การเตรียมข้อมูลเสียง
ชุดข้อมูลที่ใช้เป็น GTZAN ซึ่งสามารถดาวน์โหลดในเว็บ Kaggle ได้เลย ซึ่งในชุดข้อมูลแบ่งคลาสของข้อมูลออกเป็น 2 คลาสคือ Music และ Speech ในแต่ละคลาสจะมีไฟล์เสียง 64 ไฟล์ แต่ละไฟล์มีความยาวเสียง 30 วินาที
คุณลักษณะของไฟล์เสียงในชุดข้อมูลนี้
- เป็นฟอร์แมต WAV
- sampling rate 22.05kHz.
- sampling size 16bit
- บันทึกเสียงในรูปแบบ mono
จากนั้นแบ่งไฟล์เสียงออกเป็นเป็น 3 ชุด (random) คือ
- training 60%
- validation 20%
- testing 20%
ก่อนที่จะนำไฟล์เสียงไปสกัดคุณลักษณะสำคัญ เราจำเป็นจะต้องมาไฟล์เสียงมาผ่านการประมวลผลสัญญาณเสียงเบื้องต้น โดยการปรับสเกลของสัญญาณและการเน้นสัญญาณขั้นต้น (Pre-emphasis) ด้วยการนำสัญญาณเสียงมาผ่านวงจรกรองอันดับที่ 1 เพื่อให้สัญญาณเสียงชัดเจนขึ้นและลดสัญญาณรบกวนให้น้อยลง
หลังจากนั้นนำสัญญาณที่ประมวณผลในขั้นตอนก่อนหน้าแล้วมาแบ่งย่อยเป็นช่วงสั้นๆ เพื่อนำมาใช้เป็นตัวอย่างข้อมูลสำหรับเสียงในแต่ละคลาส โดยในแต่ละช่วงหรือแต่ละตัวอย่างข้อมูลจะมีความยาวประมาณ 950 ms (สัญญาณเสียงขนาด 20,480 sampling) และมีการทับซ้อน 50% ของขนาดตัวอย่างข้อมูลหรือเท่ากับสัญญาณเสียงขนาด 10,240 sampling ดังนั้นในแต่ละเพลงจะมีจำนวนตัวอย่างข้อมูล 63 ตัวอย่าง
หลังจากแบ่งเสียงเป็นช่วงสั้นๆ แล้ว เราจะนำเสียงแต่ละช่วงมาสกัดคุณลักษณะสำคัญที่จะนำมาใช้เป็นตัวแทนของเสียงนั้นๆ ในการทดลองนี้เราจะใช้การสกัดคุณลักณะสำคัญจากค่าสัมประสิทธ์เซปสตรัมบนสเกลเมล (Mel Frequency Cepstral Coefficient หรือ MFCC) เป็นเทคนิคที่ถูกพัฒนามาจากเทคนิคเซปตรัม ด้วยการปรับสเกลของเปคตรัมให้อยู่บนสเกลที่เหมาะสมสำหรับการได้ยินของมนุษย์ ซึ่งสามารถได้ยินเสียงเป็นเชิงเส้นตั้งแต่ 0–1,000 Hz โดยการดึงเอาสัญญาณเสียงในช่วงความถี่ต่ำให้มีความสำคัญกว่าช่วงความถี่สูง จึงเกิดการพัฒนาสเกลของสเปคตรัมที่สามารถเก็บรายละเอียดของสัญญาณเสียงในช่วงความถี่ต่ำได้มากกว่าที่เรียกว่า สเกลเมล (Mel Scale) โดยมีขั้นตอนการคำนวณเพื่อหาค่าดังภาพด้านล่าง
แต่เนื่องจาก MFCC นั้นไม่ได้แสดงถึงการเปลี่ยนแปลงของค่า cepstral coefficients กับเวลา ดังนั้นเราจึงเพิ่มการหาอนุพันธ์อันดับที่หนึ่ง (Delta MFCC) เข้าไปด้วย ดังนั้นสุดท้ายแล้วเราจะได้ข้อมูลขนาด 60 แถว (ช่วงคลื่น) ✕ 41 คอลัมน์ (เฟรม) ✕ 2 จำนวนชั้นของข้อมูล (Channel)
จากนั้นเรามาสร้าง sub-network ของโมเดล Siamese Network กัน โดยจริงๆ แล้วโมเดลของ Siamese Network จะเป็น MLP, LSTM, หรือ CNN ก็ได้ ซึ่งในบทความนี้ขอหยิบเอา CNN มาใช้งาน โดยมีโครงสร้างของ Network ประกอบไปด้วยชั้น convolutional ท้ังหมด จำนวน 3 ชั้นการประมวลผล โดยแต่ละ convolutional จะถูกคำนวณค่าบนข้อมูลคุณลักษณะสำคัญของเสียงที่ได้ในแต่ละ filter กับค่าน้ำหนัก โดยผ่าน activation function และในระหว่างชั้น convolutional จะมีชั้น max pooling คั่นอยู่เพื่อใช้ลดรายละเอียดของคุณลักษณะลง โดยการเลือกค่าที่มากที่สุดในแต่ละตัวกรอง
ซึ่ง sub-network จะให้ผลลัพธ์เป็นคุณลักษณะเวกเตอร์ขนาด 128✕1
จากนั้นนำผลลัพธ์ทั้ง 2 มาหาความคล้ายคลึงกันด้วยการคำนวณ Manhattan distance หรือ L1 Norm
ในขั้นตอนการเทรนโมเดล ในแต่ละชุดการเทรน (Batches) เราจะใช้ชุดเสียงจำนวน 64 คู่เสียง แบ่งเป็นคู่เสียงที่เหมือนกันจำนวน 32 คู่เสียง และเสียงที่ต่างกันจำนวน 32 คู่เสียง โดยฝึกสอนจำนวน 100 รอบ (Epochs) ซึ่งในแต่ละรอบใช้ชุดเทรน (Number batches per epoch) จำนวน 100 ชุด ในแต่ละชุดเสียงกำหนด label เป็น 1 สำหรับคู่เสียงที่เหมือนกันและเป็น 0 สำหรับคู่เสียงที่ต่างกัน
การเทรนโมเดลครั้งนี้เราจะเลือกใช้ optimization algorithms เป็น Adams ด้วยอัตราการเรียนรู้ 0.001 หากค่าความแม่นยำไม่เปลี่ยนแปลงค่าจากก่อนหน้าในทุก 10 รอบ จะมีการปรับอัตราการเรียนรู้ลดลง 10 เท่า และเลือกใช้ loss function เป็น binary crossentropy เนื่องจากโมเดลใช้ทำนายเพียงแค่ใช่หรือไม่
หลังจากที่เราเทรนโมเดลไป ส่วนที่เราจะนำมาใช้เพื่อสกัดคุณลักษณะสำคัญเฉพาะของเสียงนั้นคือ sub-network ของ Siamese network
การกระจายตัวของข้อมูลก่อนเทรนโมเดล
การกระจายตัวของข้อมูลหลังเทรนโมเดล
จากภาพด้านบน (a) จะเห็นว่าจุดของข้อมูลก่อนผ่านโมเดลจะมีการทับซ้อนกันค่อนข้างสูงจนทำให้การแยกกลุ่มนั้นทำได้ยาก ส่วนภาพ (b) จะเห็นว่าจุดของข้อมูลถูกแยกออกเป็นกลุ่มอย่างชัดเจน จะมีการทับซ้อนกันอยู่เพียงไม่กี่จุด ซึ่งอาจจะเกิดจากข้อมูลในจุดนั้นมีความคล้ายคลึงกับอีกกลุ่มหนึ่งค่อนข้างสูง (ข้อมูลเสียงความยาวที่ค่อนข้างสั้น จึงมีโอกาสที่เสียงจะมีความคล้ายคลึงกันสูง)
การประยุกต์ใช้งานโมเดล
เราสามารถนำโมเดล sub-network ที่ได้จากการเทรน Siamese network มาสกัดคุณลักษณะสำคัญเฉพาะ จากนั้นเราอาจจะนำข้อมูลคุณลักษณะสำคัญเฉพาะที่ได้ไปประยุกต์ใช้ดังนี้
- นำข้อมูลไปใช้งานด้วย Machine learning algorithms เช่น Logistic Regression, k-Nearest Neighbor, Support Vector Machines (SVM) เป็นต้น ซึ่งเป็นการเพิ่มประสิทธิภาพให้ตัว algorithm เองด้วย
- นำข้อมูลที่ได้ไปเก็บในฐานข้อมูล และใช้ algorithm อย่าง nearest neighbor search เพื่อค้นหาข้อมูลในฐานข้อมูลอีกที
References:
Andrew Ng course on Deep Learning Specialization on Coursera
C4W4L03 Siamese Network on the deeplearning.ai YouTube channel.