แต่งเนื้อเพลงแบบ Geek ด้วย machine learning

ผ่านวันวาเลนไทน์ไม่กี่วัน อยากลองทดสอบตัว Recurrent Neural Networks (RNNs) ว่าประสิทธิภาพของมันจะเป็นอย่างไรบ้าง เลยตั้งโจทย์ไว้ว่าลองให้ตัว RNNs แต่งเนื้อเพลงดูว่าจะออกมาเป็นยังไง

สำหรับคนที่ไม่รู้ว่า RNNs คืออะไร อธิบายอย่างสั้นๆ กว้างๆ ได้คือว่า RNNs เป็น neural networks ประเภทหนึ่งที่มีความเชื่อมต่อใน node ของ networks ทำให้สามารถจำค่าของ State ที่เกิดขึ้นก่อนหน้าได้ ทำให้เหมือนกับว่า RNNs สามารถมีหน่วยความจำที่จะประมวลผล input ที่เข้ามาเป็นแบบ sequence ได้

ในบทความอันนี้จะลองทดสอบความสามารถของ RNNs ในการทดลองให้แต่งเนื้อเพลง!! โดยจะ train RNNs และสร้าง model ที่เป็นระดับตัวอักษร ข้อมูลที่ใช้เป็น training data คือ เนื้อเพลงที่เตรียมไว้ประมาณ 12,000 เพลง โดยตัวโมเดลก็จะอ่านเพลงนับไปแต่ละตัวอักษรและสร้างความน่าจะเป็นในการปรากฎของตัวอักษรตัวต่อไปขึ้นมาเป็นโมเดล

ในบทความนี้จะใช้ tools ที่ชื่อ torch-rnn โดยสามารถ install ตามที่อยู่ใน github ได้ https://github.com/jcjohnson/torch-rnn

ในขั้นแรกเราต้องลง libraries ต่างๆ ให้ครบก่อนก่อนที่จะใช้ torch-rnn ได้ (อ่านได้ตาม guide ที่อยู่ใน github)

หลังจาก install ตัว torch-rnn เรียบร้อยแล้วในขั้นแรกเราต้อง prepare data ของเรา โดย file songs.txt นั้นเป็น file ที่ใช้รวมเนื้อเพลงต่างๆ เพื่อไว้ใช้เป็น traning data โดยใช้คำสั่งดังนี้

python scripts/preprocess.py --input_txt data/songs.txt --output_h5 data/songs.h5 --output_json data/songs.json

หลังจากประมวลผลเสร็จก็จะได้ output ออกมาประมาณนี้

Total vocabulary size: 177
Total tokens in file: 11459586
Training size: 9167670
Val size: 1145958
Test size: 1145958
Using dtype <type ‘numpy.uint8’>

ทีนี้ก็ถึงเวลาในการ train ตัว RNNs โดยใช้คำสั่งดังนี้

th train.lua -input_h5 data/songs.h5 -input_json data/songs.json

โดยขั้นตอนนี้จะใช้เวลาค่อนข้างนาน (แล้วแต่ความแรงของเครื่อง) โดยค่า default จะ run 50 epochs

หลังจากกระบวนการ training เสร็จแล้ว ทีนี้ก็พร้อมที่จะให้ตัว RNNs แต่งเนื้อเพลงละ หลังจากเรียนรู้เนื้อเพลงประมาณ 12,000 เพลง โดยใช้คำสั่ง

th sample.lua -checkpoint cv/checkpoint_99000.t7 -length 1000

โดย file checkpoint นั้นเราเลือก file ที่มีเลขสูงที่สุดจากการ train ส่วน length จะเป็นจำนวน character ที่เราต้องการจาก RNNs

หลังจากนั้นก็จะได้เนื้อเพลงมาเป็นดังนี้!!!

ณ หัวใจของเรา
แต่พอเจอไม่เหลืออะไร
ฉันขอเป็นเธอก็พอเข้าใจ
แต่ต่างไงกำลัง
ภายในใจเขานั้นรัก
สองเราอยู่ไหน ยังกลัวห้ามได้แค่ฝัน
อยากให้เธอรู้สึกก็มีแค่ รักใครๆ ที่โหล่ต้องมี
ผมมีเธอ อย่าทำเป็นต้องของใคร
ไม่เชื่อประทับใจ อย่ารู้นะ เธอคนคือหัวใจ
ก็มันร้อนพวกเราก็คงไม่นาน หรือไงส่องจริง
ในเวลาครั้งฉันจะเก่า
ปล่อยฉันผ่านนั้นคือเธอ
ใจจริง หัวใจของเธอจะไป
ทั้งคนเรานั้นมีแค่นำร้ายแล้วได้พบคนในฝัน
อยู่เคียงข้างฉันจะยอมให้มันรักใคร
ยังกลัวจะไม่ยอมต้นทุกครั้ง
Everything is forever
ป่วยทำตัวอะไร อะไรที่มองเห็นใจ
สองเราไม่ดี มันจะนานเท่าไหร่ฉันมีใจกับความงามรักจับใจ
พร้อมเธอก่อนที่แท้จังหวะ อะไรอย่างไร ยังคงรอว่างความฝันให้เธอ
กล่อมดาวอยู่ในหัวใจ
ฉันรอวันที่นั้นรักเรา ช่วยรำคาญใจที่มีไหม
อีกไร ทิ้งมันไปมองไปตายจงมาเหงาใจอยู่จนเหงาใจ
เรียนรู้ท้ายกันอย่างนี้ให้เลือนลาง ไม่อยากเจอ
ให้คำว่ารักง่ายง่าย แกร่งไม่แคร์
อยู่กับฉันมากไป ก็จะรู้เลยว่าฉันเร็ว ยังไม่ขาดเธอ

เป็นยังไงบ้างครับ สำหรับเพลงที่แต่งโดย AI!! จะเห็นว่าตัว RNNs นั้นสามารถเชื่อมคำแต่ละตัวอักษรได้ดีพอสมควร แต่อย่างไรก็ดี ยังไม่สามารถที่จะเชื่อมโยงความสัมพันธ์ในแต่ประโยคให้เป็นใจความได้ เนื่องจาก RNNs นั้นมองเพียงความน่าจะเป็นของตัวอักษรตัวต่อไป โดยยังไม่มีความสามารถในการมองการเชื่อมโยงแบบทั้งระบบนั่นเอง

ข้อสังเกตอีกอย่าง คือ ถึงแม้ว่าการเชื่อมโยงในแต่ละประโยคตัว RNNs ยังไม่สามารถทำได้ดี แต่การเลือกคำของ RNNs นั้นยังมีความน่าสนใจอยู่ โดยที่นักแต่งเพลงอาจจะคิดไม่ถึง แต่มีความไพเราะอยู่ เช่น “กล่อมดาวอยู่ในหัวใจ” ที่ตัว RNNs สามารถเลือกมาได้อย่างน่าสนใจเลยทีเดียว