โครงการ AI builders กับ AI สร้างภาพจากข้อความสร้างโดยเด็กมัธยมปลาย (ที่เกือบจะขึ้นปี 1)

Purich Siritip
6 min readJun 21, 2022

บทความนี้จะอธิบายถึงการทำ Machine learning model สร้างภาพจากข้อความและความรู้สึกที่ได้เข้าร่วมโครงการ AI Builders ตลอด 10 สัปดาห์ โดยในด้านโมเดลผู้เขียนพยายามเทรนให้รับข้อความในภาษาไทยและสร้างเป็นรูปที่สอดคล้องกับข้อความออกมา

ภาพตัวอย่างจากโมเดล VQGAN-ThCLIP

สารบัญเนื้อหา

จุดประสงค์การทำโมเดล

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

โมเดลที่ใช้ในการสร้างภาพ

โมเดลที่ผู้เขียนเลือกใช้คือ VQGANxCLIP โดยประกอบไปด้วย 2 ส่วนหลัก ๆ คือ VQGAN และ CLIP ซึ่ง VQGAN จะทำหน้าที่เป็นเสมือนผู้วาดรูปและ CLIP จะทำหน้าที่เป็นคนที่คอยกำกับรูปที่ VQGAN วาดว่าตรงกับข้อความที่เราวาดไปแค่ไหน

ผู้เขียนเลือกที่จะให้ความสำคัญกับ CLIP model เพราะสามารถนำไปเป็น Loss function ให้กับ​ Generative model หลาย ๆ ตัวนอกจาก VQGAN ได้ไม่ว่าจะเป็น VAE หรือ diffusion

CLIP & VQGAN ฉบับรวบรัด

ผู้เขียนได้อธิบาย CLIP และ VQGAN ไว้ในบทความก่อนหน้านี้แบบเข้าใจง่ายแล้ว สามารถอ่านบทความได้ที่นี่เพื่อความเข้าใจที่ชัดเจนยิ่งขึ้น

CLIP เป็นโมเดลที่เป็นสะพานเชื่อมระหว่างรูปภาพกับข้อความโดยจะทำการ Embed ทั้งสองอย่างนี้ให้อยู่ใน latent space ขนาดเท่ากันจึงสามารถนำทั้ง Text embedding และ Image embedding มาเปรียบเทียบความเหมือนความต่างได้โดยใช้วิธีการทางคณิตศาตร์ต่าง ๆ CLIP จะประกอบไปด้วยโมเดลหลัก 2 ส่วนคือ Text encoder และ Image encoder

VQGAN เป็นโมเดลประเภท Generative โดยจะประกอบไปด้วย Generator และ Discriminator โมเดลสองตัวนี้จะแข่งกันและพัฒนาตัวเองไปพร้อม ๆ กันจนในที่สุด Discriminator ไม่สามารถเอาชนะ Generator ได้ เราจึงจะนำ Generator ไปสร้างภาพต่อ นอกจากนี้ก่อนที่ทั้งสองโมเดลนี้จะแข่งกัน Generator จะได้เรียนรู้โครงสร้างของภาพที่ตัวเองจะสร้างไว้ก่อน เปรียบเสมือนมีสมุดเปล่าที่เอาไว้จดวิธีการสร้างสิ่งต่าง ๆ ลงไป

เนื่องจากการจะสร้างรูปจาก VQGAN นั้นต้องมี Random input (กลุ่มตัวเลขแบบสุ่ม) ส่งเข้าไปให้ Generator จึงจะสร้างเป็นรูปต่าง ๆ ได้และแน่นอนว่าเราไม่สามารถรู้ได้ว่าการสุ่มแบบไหนจะให้รูปที่เราต้องการได้ จึงต้องใช้ CLIP คอยกำกับและค่อย ๆ เปลี่ยน Random input เหล่านี้ให้เป็นรูปที่เราต้องการ

วิธีแรกในการเทรน CLIP

ผู้เขียนใช้ Architecture และ วิธีการเทรนคล้ายกับบทความ Simple Implementation of OpenAI CLIP model: A Tutorial
โดยใช้ RN50 เป็น Image encoder และใช้ WangchanBerta เป็น Text encoder ภาษาไทยแต่เนื่องจากทั้งสองโมเดลนี้ Encode latent space ออกมาด้วยขนาดที่ต่างกันจึงต้องใส่ Projection head เข้าไปที่เลเยอร์สุดท้ายของแต่ละโมเดลเพื่อทำให้ latent space เท่ากันที่ขนาด [1, 256]

ชุดข้อมูล

ผู้เขียนเลือกที่จะทดลองกับข้อมูลขนาดเล็กก่อนแล้วดูประสิทธิภาพที่ได้ จากนั้นจึงค่อย ๆ เพิ่มขนาดชุดข้อมูลไปเรื่อย ๆ ชุดข้อมูลแรกที่ใช้คือ flickr8k ประกอบด้วยรูปจำนวน 8,000 รูป โดยแต่ละรูปประกอบด้วยคำอธิบายภาษาอังกฤษ 5 ประโยครวมทั้งหมด 40,000 ประโยค เนื่องด้วยผู้เขียนอยากทำ CLIP ภาษาไทยจึงใช้โมเดลแปลภาษาอังกฤษเป็นไทยพัฒนาโดยสถาบันวิจัยปัญญาประดิษฐ์ประเทศไทยผ่านแพ็คเกจ Pythainlp

ภาพบางส่วนจากชุดข้อมูล flickr8k Source

วิเคราะห์ชุดข้อมูล

ชุดข้อมูลที่ผ่านการแปลมาแล้วพบว่าส่วนมากแปลได้ตรงความหมาย แต่จะมีบางคำที่แปลผิดบริบทเช่น A man is doing a trick with a bike แปลเป็น ผู้ชายกําลังเล่นกลกับจักรยานและมีบางส่วนที่เมื่อแปลมาแล้วมีการเติม “ค่ะ” ท้ายประโยคโดยไม่สมเหตุสมผลเช่น two babies are sitting in their highchair แปลเป็น เด็กสองคนนั่งอยู่บนเก้าอี้สูงค่ะ นอกจากนี้พบว่ารูปส่วนมากเกี่ยวกับคนกำลังทำกิจกรรมต่าง ๆ มีรูปสัตว์ประปราย

ผลจากการเทรนโมเดล

ผู้เขียนได้นำ CLIP ที่เทรนไปใช้เป็น Loss function ให้กับ VQGAN โดยมี Parameters ที่เทรนคือ Random input (z) ผลที่ได้ ตัวโมเดลเริ่มเข้าใจคำแล้วสร้างเป็นภาพได้แต่ยังสร้างได้ไม่สมบูรณ์เช่น ใน text prompt มีคำว่าหมา รูปที่ได้จะมีหัวกับตัวอยู่แยกกัน นอกจากนี้ตัวโมเดลยังไม่สามารถเข้าใจ text prompt สั้น ๆ ได้

ภาพที่ได้จากโมเดล

ขยายชุดข้อมูลและเทรนอีกครั้ง

เนื่องจากผลยังไม่เป็นที่น่าพอใจผู้เขียนจึงขยับชุดข้อมูลไปที่ flickr30k โดยชุดข้อมูล flickr30k มีโครงสร้างเหมือนกับ flickr8k และส่วนมากจะประกอบไปด้วยภาพแนวเดียวกันกับ flickr8k ผู้เขียนได้ใช้โมเดลแปลภาษาตัวเดิมเพื่อแปลจากอังกฤษเป็นไทย

ภาพบางส่วนจากชุดข้อมูล flickr30k Source

ผลจากการเทรนอีกครั้ง

โมเดลสามารถสร้างรูปสอดคล้องกับ text prompt ได้ แต่รูปส่วนมากที่ได้จะมีบางส่วนของภาพที่ดูเหมือนยังวาดไม่เสร็จ

ภาพที่สร้างจากโมเดลที่เทรนโดยชุดข้อมูลที่ใหญ่ขึ้น

วิธีที่สองในการเทรน CLIP

ผลของ CLIP ที่เทรนจากโมเดล flickr30k ก็ยังไม่พอใจผู้เขียนอยู่ดี และการเทรนให้ได้ผลลัพธ์ที่น่าพอใจก็ดูเหมือนจะต้องใช้ชุดข้อมูลที่ใหญ่มากและทรัพยากรที่มหาศาล ในระหว่างที่ผู้เขียนกำลังจะถอดใจและกลับไปใช้ชุดข้อมูลที่ใหญ่พอที่จะเทรนไหว ก็ได้เจอ Github : Multilingual-CLIP ที่เสนอวิธีการเทรน CLIP model ในภาษาใดก็ได้ให้มีประสิทธิภาพใกล้เคียงกับ OpenAI’s CLIP ซึ่งวิธีคือการพยายามทำให้ Text encoder ของ CLIP เรา Predict latent space ออกมาให้คล้ายกับของ OpenAI’s CLIP มากที่สุด จากนั้นจึงใช้ Image encoder เดียวกันกับ OpenAI’s CLIP เพื่อทำนายความคล้ายของรูปกับข้อความ ผลจากการเทรนด้วยวิธีนี้โดยอ้างอิงจาก Github ผู้สร้างพบว่าใช้ชุดข้อมูลน้อยกว่าการเทรนโดยวิธีแรกอย่างมากและให้ผลเป็นที่น่าพึงพอใจ ผู้เขียนจึงตัดสินใจใช้วิธีนี้ในการเทรนโมเดล CLIP ภาษาไทยเนื่องด้วยทรัพยากรและเวลาที่มีอยู่อย่างจำกัด

ตัวอย่างการเทรน CLIP โดยใช้ MSE Score Source

วิธีการเทรน CLIP โดยใช้ MSE (Mean Square Error)

ดังที่ได้กล่าวไปว่าวิธีการทำงานของ CLIP จะใช้ Text encoder แปลงข้อความและ Image encoder แปลงรูปให้อยู่ใน latent space เดียวกันโดย OpenAI’s CLIP มี latent space ขนาด [1, 512] ซึ่งมากกว่า latent space ของ CLIP ที่เราเทรนในตอนแรกถึง 2 เท่าทำให้ไม่สามารถนำมาเทรนต่อได้ จึงต้องเริ่มเทรนใหม่ตั้งแต่ต้น ผู้เขียนจะขอสรุปส่วนประกอบที่เราต้องใช้ทั้งหมดในการเทรน CLIP ให้เหมือนของ OpenAI โดยมีส่วนประกอบดังนี้

  • ชุดข้อมูลจำหนึ่งที่อยากจะเทรนโดยข้อมูลชุดนี้ต้องมีทั้งภาษาอังกฤษและภาษาที่เราอยากจะเทรน (ในที่นี้คือภาษาไทย)
  • Text ที่ผ่านการแปลงข้อความจาก Text encoder ของ OpenAI’s CLIP (Text embedding)

ขั้นตอนการเทรนโดยคร่าว ๆ

  1. นำข้อความในภาษาของเราไปแปลงเป็นตัวเลข (embedding)
  2. เทียบความเหมือนของข้อความที่นำไป embedding กับ ข้อความที่นำไป embedding ของ OpenAI’s CLIP ด้วย MSE
  3. Optimize weight text encoder ของเราโดยใช้ MSE เป็น Loss function

ข้อดีของการเทรนด้วยวิธีนี้

  • สามารถใช้ Image encoder ของ OpenAI’s CLIP มาเป็น Image encoder ของ CLIP เราได้เลยเนื่องจาก Text encoder ของ OpenAI และของเรามีความใกล้เคียงกันมาก
  • เทรนได้เร็วกว่าแบบแรกเพราะเทรนเพียงตัว Text encoder เท่านั้น

ชุดข้อมูล (once again)

อ้างอิงจาก Gitub : Multilingual-CLIP ผู้สร้างได้สร้าง SwedishCLIP โดยการสุ่มประโยค 2 ล้านประโยคจากชุดข้อมูล GCC + MSCOCO + VizWiz และได้ผลลัพธ์ที่ดี ผู้เขียนจึงใช้ชุดข้อมูล GCC+ MSCOCO เนื่องจากหาได้ง่ายและคล้ายกับชุดข้อมูลที่ผู้สร้างใช้ โดยผู้เขียนสุ่มมา 2 ล้านคำเหมือนของ SwedishCLIP

ภาพบางส่วนจากชุดข้อมูล Google conceptual captions (ซึ่งไม่ได้ใช้ในการเทรนแบบ MSE) Source

วิเคราะห์ชุดข้อมูล (once again)

ชุดข้อมูลที่ผู้เขียนใช้ประกอบไปด้วย Google conceptual caption (GCC)และ Microsoft Common Objects in Context (MSCOCO)โดย GCC รวบรวมข้อมูลรูปภาพและคำอธิบายมาจากโซเชียลมีเดียแบบอัตโนมัติซึ่งประกอบไปด้วยภาพที่หลากหลายเช่น ภาพทิวทัศน์ ภาพการ์ตูนหรือแม้กระทั่งภาพร้านค้า ส่วน MSCOCO จะประกอบไปด้วยภาพที่อยู่ในชีวิตประจำวันเช่น ยานพาหนะ สิ่งของทั่ว ๆ ไปและสัตว์

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

ข้อความบางส่วนที่แปลจากโมเดลแปลไทย

ผลจาการเทรน

ใช้เวลาเทรนประมาณ 25 ชั่วโมงบน aws EC2 instance type p2.xlarge เมื่อลองนำ CLIP ไปเป็น Loss function ให้กับ VQGAN แล้วพบว่าสามารถสร้างรูปตามข้อความที่พิมพ์ได้อย่างน่าพึงพอใจ

ตัวอย่างภาพที่สร้างจากโมเดล

ทดลอง ทดลอง ทดลอง

หลังจากทดสอบหลาย ๆ อย่างผู้เขียนพบว่า

  • Transform ภาพโดยสุ่มเพิ่มระดับ sharpness ให้กับภาพทำให้กราฟ Loss converge เร็วขึ้น
  • iteration ที่เหมาะที่สุดอยู่ระหว่าง 200–300 รอบ

จุดที่ยังทำได้ไม่ดี

  • โมเดลไม่เข้าใจศัพท์แสลง
  • ข้อความที่รับต้องเป็นคำที่เขียนถูกต้องเท่านั้น

ลบสิ่งที่ไม่ต้องการให้อยู่ในภาพด้วย Negative prompt

เฉกเช่นเดียวกับการใช้ CLIP เป็น Loss function ให้กับ VQGAN ซึ่งทำให้เราสามารถสร้างรูปที่ต้องการได้ เราสามารถทำสิ่งที่ตรงกันข้ามคือให้ VQGAN สร้างสิ่งที่เราเขียนไว้ใน Negative prompt ให้น้อยที่สุด

ยกตัวอย่างเช่น ถ้าเป็นข้อความที่ต้องการให้สร้าง (Prompt) เช่น “เครื่องบิน” เมื่อมีสิ่งนั้นอยู่ในรูปแสดงว่าค่า Loss function มีแนวโน้มที่จะลดลง กลับกันถ้าเป็นข้อความที่ไม่อยากให้อยู่ในภาพ (Negative prompt) เช่น “ภาพเบลอ” เมื่อมีภาพเบลออยู่ในรูปจะทำให้ Loss function มีแนวโน้มที่จะเพิ่มขึ้นแทน

โดยปกติแล้วเราจะนิยมให้ Loss function ที่มีค่ามากหมายความว่ายังทำได้ไม่ดีและต้องพยายามทำให้ Loss function น้อยที่สุด

ตัวอย่างภาพที่สร้างจากโมเดลโดยใช้ Negative prompt ร่วมด้วย

ทำให้ภาพสวยอีกระดับด้วย Aesthetic predictor

จาก Github : aesthetic-predictor
aesthetic predictor คือ โมเดลที่ประกอบด้วย Linear layer 1 ชั้นโดยรับ Input เป็นภาพที่แปลงเป็นตัวเลข (Image embedding) และให้ Output เป็นคะแนนจำนวนจริงที่ทำนายความสวยงามของภาพโดยคะแนนสูงหมายถึงภาพที่สวย

ผู้เขียนจึงได้นำ Aesthetic predictor ไปใช้เป็น Loss function ร่วมกับ Text prompt และ Negative prompt โดยให้น้ำหนัก​ (weight) น้อยมากเพราะไม่เช่นนั้นจะทำให้รูปที่ได้ไม่สอดคล้องกับข้อความ

ตัวอย่างภาพที่สร้างจากโมเดลโดยใช้ Negative prompt และ Aesthetic predictor ร่วมด้วย

Text prompt engineering on VQGAN-ThCLIP

รูปต่อไปนี้เป็นรูปสไตล์ของภาพต่าง ๆ ที่ผู้เขียนพบระหว่างการทดลองใช้โมเดล

รูปสไตล์ต่าง ๆ โดยใช้คฤหาสน์เป็นหลักแล้วเปลี่ยนสไตล์

Human evaluation on text-to-image synthesis

ผู้เขียนได้ประเมินความสามารถของ VQGAN-ThCLIP โดยได้เอาไปเทียบกับ VQGAN-OpenAI’s CLIP แบ่งหัวข้อการประเมินเป็น 2 ส่วนคือ

  • ความสอดคล้องของรูปภาพกับข้อความ
  • ความหลากหลายของรูปที่สร้าง

นอกจากนี้ผู้เขียนได้แบ่งข้อความที่ใช้สร้างภาพออกเป็นสามส่วนคือ

  • ข้อความขนาดสั้น
  • ข้อความขนาดปานกลาง
  • ข้อความขนาดยาว

ผู้เขียนได้ทำแบบสอบถามเพื่อประเมินโมเดล มีผู้ร่วมตอบแบบสอบถามทั้งหมด 27 คน พบว่า

  • ข้อความขนาดสั้น VQGAN-ThCLIP ทำได้ดีกว่า VQGAN-CLIP ทั้งด้านความสอดคล้องและความหลากหลาย
  • ข้อความขนาดปานกลาง VQGAN-ThCLIP และ VQGAN-CLIP ทำได้เท่ากันทั้งความสอดคล้องและความหลากหลาย
  • ข้อความขนาดยาว VQGAN-ThCLIP ทำได้ดีกว่า VQGAN-CLIP ในด้านความสอดคล้องแต่ด้อยกว่าในด้านความหลากหลาย

deploy app ด้วย Streamlit

เนื่องด้วยการสร้างรูปด้วย VQGAN-CLIP จำเป็นต้องใช้ GPU ในการรันบวกกับเว็บไซต์ที่ให้ deploy app ฟรีไม่มีบริการ GPU ผู้เขียนจึงตัดสินใจนำแอปไปไว้บน Google colab โดยในการรันแต่ละครั้งผู้ใช้จะได้ VM (virtual machine) มาใช้และ Google colab มีตัวเลือกให้ใช้ GPU ในการรัน จึงเหมาะกับการ deploy app ที่ใช้ GPU

ผู้อ่านสามารถทดลองเล่นได้โดยคลิดที่ลิ้งค์นี้ (คัดลอกมาจากส่วนหนึ่งของบทความที่แล้ว : AI สร้างภาพจากข้อความได้อย่างไร ฉบับเข้าใจง่าย)

  1. เมื่อเข้าไปแล้วให้ทำการ Sign in โดยใช้บัญชี Google

2. เมื่อ Sign in เสร็จแล้วให้กด Runtime -> Run all แล้วรอให้โค้ดรันสักพัก

3. เลื่อนไปด้านล่างสุดแล้วรอจนโค้ดขึ้น url แล้วกดที่ url (url ของแต่ละคนจะไม่เหมือนกัน)

4. เว็บจะเตือนว่าให้ระวังการโดนหลอกถามข้อมูล แต่เว็บของผู้เขียนไม่มีการถามข้อมูลใด ๆ กด Click to Continue ได้เลย

5. หลังจากนั้นพิมพ์คำที่ต้องการให้ AI สร้างแล้วกด Let’s generate! ได้เลย (สามารถเพิ่มสไตล์ของภาพและปรับแต่งโมเดลได้โดยการกดขยายแต่ละส่วน)

What could be improved?

  • เปลี่ยนโมเดลที่ใช้สร้างภาพเป็น diffusion เนื่องจากภาพที่สร้างสวยกว่าแต่ทรัพยากรที่ใช้ก็เยอะขึ้นตามด้วย
  • เทรนโมเดลด้วยข้อความและรูปจากโซเชียลมีเดียเพื่อให้โมเดลเรียนรู้ศัพท์แสลง

ความรู้สึกที่ได้รับหลังจากเข้าร่วมโครงการ AI Builders

ผู้เขียนขออธิบายก่อนว่าโครงการ AI Builders คือ โครงการสำหรับนักเรียนมัธยมต้น-ปลาย ที่สนใจสร้างผลงานโดยใช้เทคนิคทางด้านวิทยาศาสตร์ข้อมูล (Data Science) และปัญญาประดิษฐ์ (Artificial Intelligence) ในโครงการจะมีสอนตั้งแต่พื้นฐานจนถึงการนำผลงานของเราไปใช้จริง นับว่าเป็นโครงการที่มีประโยชน์มากสำหรับคนที่มีความสนใจด้านนี้และอยากมีผลงานของตัวเองกลับออกไปเมื่อจบโครงการ นอกจากนี้ภายในโครงการยังมีพี่ ๆ เมนเทอร์ที่มากไปด้วยประสบการณ์และความรู้จากด้านต่าง ๆ ไม่ว่าจะเป็น Computer vision, Natural language processing หรือ Tabular data ซึ่งเราสามารถเข้าไปขอคำปรึกษาอาจจะเรื่องเป็นโครงงานที่เราทำอยู่หรือเรื่องอื่น ๆ ก็ได้

ความรู้สึกของผู้เขียนที่ได้เข้าร่วมโครงการมาตลอด 10 สัปดาห์

  • Community ของ AI Builders มีความเป็นกันเองสูงมาก เวลามีใครสงสัยหรือติดตรงไหนก็จะมีคนเข้ามาตอบและแก้ไขความสงสัยให้
  • ทุกคนแบ่งปันความรู้ของตัวเอง เมื่อมีความรู้ใหม่ ๆ ออกมาหรือความรู้ที่น่าสนใจก็จะมีคนแบ่งปันเข้ามาในกลุ่มอยู่เสมอ ๆ
  • หัวข้อการบรรยายที่น่าสนใจจากแขกรับเชิญที่มากันอย่างไม่ขาดสาย ซึ่งแต่ละหัวข้อนั้นก็มีแต่เรื่องใหม่ ๆ ที่กำลังเป็นที่จับตามองเช่น Quantum computer, Machine learning, Hardware achitecture

Reference

Special thanks

  • AI Builders
  • mentors of AI Builders (especially, P’Charin and P’Top)

--

--