MTCNN in Detail

MTCNN in Detail

ในบทความนี้เราจะพาทุกคนไปรู้จักกับ (อดีต) State-of-the-Art ของการทำ Face Detection ด้วย Model ที่ชื่อว่า Multi-task Cascaded Convolutional Networks (MTCNN) กันครับ MTCNN ถูกนำเสนอในเปเปอร์ที่ชื่อว่า “Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks” ในปี 2016 โดยที่ถือว่าเป็นวิธีที่ค่อนข้างได้รับความนิยมพอสมควรเห็นได้จากการถูกอ้างอิงมากถึง 2,100 ครั้ง และมี Github Repo หลายที่ที่ใช้เทคนิคที่เสนอในเปเปอร์นี้

เหตุผลหลักที่ทำให้วิธีนี้ได้รับความนิยมอย่างล้นหลามก็เพราะว่ามันมีความแม่นยำที่สูงที่สุด (ณ ตอนที่ถูกตีพิมพ์) ในขณะที่ใช้เวลาในการประมวลผลเร็วกว่าตัวอื่นพอสมควร โดยที่ในบทความนี้ผมจะพาผู้อ่าน ไปรู้จักกับ MTCNN และสาเหตุที่โมเดลนี้ถึงแม่นยำและทำงานรวดเร็ว โดยที่ในบทความนี้เราจะอธิบายขั้นตอนการทำงานของ MTCNN โดยคร่าวซึ่งอาจจะไม่ได้ลงวิธีการ coding สำหรับผู้อ่านที่สนใจจะลองเล่นสามารถเข้าไปตาม github นี้ได้เลยครับ

หลักการที่ MTCNN เสนอคือการทำ Face Detection และ Face Alignment แบบ Multi-Tasking โดยใช้ Neural Network แค่ตัวเดียวเพื่อทำทั้ง 2 อย่างไปพร้อมๆ กัน ซึ่งแตกต่างจากวิธีอื่นๆ สามารถทำงานใดงานหนึ่งเพียงอย่างเดียว โดยที่ประโยชน์ของการทำทั้ง 2 Tasks ใน Network เดียวไม่ได้มีแค่ทำให้เราสามารถทำทั้งสองอย่างได้พร้อมกัน แต่ยังช่วยเพิ่มความแม่นยำให้ทั้ง 2 Tasks อีกด้วย และผลลัพธ์ที่ได้จากวิธีการนี้ยังดีมากๆ ถึงระดับ State-of-the-Art สำหรับ Face Detection ในเวลานั้นเลยทีเดียว

What is Face Detection and Face Alignment ?

ก่อนที่จะไปถึงหลักการทำงานของ MTCNN ผมอยากขออธิบายเรื่อง Face Detection และ Face Alignment ก่อนครับ ซึ่งการทำ Face Detection ผู้อ่านทุกคนน่าจะคุ้นเคยกันอยู่แล้ว แต่ในส่วนของ Face Alignment นั้นอาจจะไม่คุ้นหูกันซักเท่าไหร่

การทำ Face Alignment คือการจัดภาพใบหน้าในรูปที่จับได้ เพราะในความเป็นจริงใบหน้าที่ตรวจจำได้อาจจะไม่ได้ตั้งตรงเสมอไป ดังนั้นเราจึงต้องจัดรูปให้กลับมาตรงเพื่อที่จะได้นำไปใช้ประโยชน์อื่น ๆ ต่อได้ง่าย เช่น การจดจำใบหน้า​ (Face Recognition) เป็นต้น

ซึ่งวิธีหนึ่งที่เป็นที่นิยมในการทำ Face Alignment นั้นคือการหา Keypoint บนหน้า เช่นตาซ้ายตาขวา จมูก ปาก แล้ว Crop ภาพให้จมูกอยู่ตรงกลางภาพ จากนั้นก็ทำการ Transformation ต่างๆ เช่น การ Rotate ให้ตาซ้ายและขวาอยู่ในระดับเดียวกันเป็นต้น

รูปที่ 1

รูปที่ 1

MTCNN

ซึ่งในเปเปอร์ก่อนหน้านั้น เค้ามักจะแยกกันทำระหว่าง Face Detection และ Face Alignment ทีนี้คนเขียนเปเปอร์นี้เค้าเลยเอะใจ ว่าทั้งสองอย่างนี้มันมักจะถูกใช้พร้อมกันอยู่แล้ว และด้วยตัวงานของมันก็มีส่วนที่คล้ายกันอยู่คือต้องการเรียนรู้หน้าเหมือนกัน แล้วถ้าเรารวบมันให้อยู่ในโมเดลเดียวกันให้เรียนรู้ไปพร้อมกันเลยก็น่าจะช่วยให้ Neural Network เรียนรู้ได้ดีขึ้น

Sidenote:

สำหรับคนที่สงสัยว่าทำไมการที่เราเอาสอง task ที่คล้าย ๆ กันมามัดรวมกันมันถึงเรียนรู้ได้ดีขึ้น ก็เพราะว่าใน CNN architecture ที่มักจะมี CNN layers ต่อ ๆ กันหลายชั้น โดยธรรมชาติแล้วพวก Filter ของ CNN ใน Layer แรก ๆ มักจะเรียนรู้ Low-Level Features เช่น การหาขอบของวัตถุในภาพ ซึ่งถ้าเป็นงานที่คล้าย ๆ กันแล้วพวก Low-Level Features ก็มักจะมีลักษณะคล้ายกันด้วย อย่างเช่นใน Face Detection มี Low-Level Features เป็นการ detect ขอบดวงตา ขอบริมฝีปากเป็นต้น ซึ่งการที่ทำให้โมเดลเรียนรู้ทั้งจาก 2 tasks เป็นการเพิ่ม Constraint ของกันและกันให้บังคับให้เรียนรู้อะไรที่สำคัญ ๆ สำหรับสอง tasks นั้นจริง ๆ ป้องกันไม่ให้ไปเรียนรู้หรือจำอะไรไม่สำคัญ

โดยที่ใน MTCNN นั้นเค้าแบ่งขั้นตอนการทำออกเป็น 3 Stages ด้วยกัน หรือก็คือประกอบไปด้วย 3 โมเดลหลักคือ P-Net, R-Net และ O-Net ดังภาพด้านล่าง โดยที่แต่ละโมเดลจะทำงานต่อ ๆ กัน หรือก็คือ Output จากโมเดลแรกจะไปเป็น Input ของโมเดลถัดไป

รูปที่ 2

รูปที่ 2

Sidenote:

อย่าสับสนว่าการมีหลาย ๆ Stages คือการทำ Multi-Task นะ จริง ๆ แล้ว Multi-Task ที่เปเปอร์นี้กล่าวถึงคือการที่เราเทรนให้แต่ละ Stage ทำสอง task ด้วยกัน จะเห็นได้ว่าแต่ละโมเดลในภาพด้านบนมี Output 3 ชุดด้วยกัน ได้แก่ Face Classification, Bounding Box Regression, Facial Landmark Localization ซึ่งสอง Output แรกนั้นคือการทำ Face Detection, และ Output สุดท้ายคือการทำ Face Alignment

โดยที่ตอนเทรนแต่ละ Stage นั้น เราจะนำ Loss จากทั้ง 2 tasks (หรือ 3 Outputs) มาบวกกัน ซึ่งก็คือนำ Binary Cross Entropy Loss จาก Face Classification มาบวกกับ Euclidean Loss ของ Bounding Box Regression และ Face Localization นอกจากนี้ในเปเปอร์เค้าก็ได้มีการตั้ง Weights ของแต่ละ Loss ในแต่ละ Stage ให้แตกต่างกันคือ Stage แรกก็จะเน้น Loss ของ Face Classification มากกว่า แต่ใน Stage สุดท้ายก็จะเน้น Loss ของ Face Localization มากกว่า

ในกระบวนเทรน MTCNN นั้น เราจะเริ่มจากเทรน P-Net ก่อน เมื่อเทรน P-Net จนเก่งในระดับหนึ่งแล้ว เราจะนำ P-Net ไปใช้เพื่อสร้าง traning set ให้ R-Net และเมื่อเทรน R-Net เสร็จแล้ว ก็นำทั้ง P-Net และ R-Net ไปใช้เพื่อสร้าง traning set ให้ O-Net อีกที

ซึ่งชื่อเปเปอร์นี้กันมันมีคำว่า Cascased Convolutional Neural Network ซึ่งก็หมายถึงการมีหลาย ๆ Stages ต่อกันซึ่งเราสามารถมองการต่อกันหลาย ๆ stage นี้เหมือนเป็น boosting algorithm แบบหนึ่งก็ได้

1. Proposal-Network (P-Net)

P-Net เป็นโมเดลแรกซึ่งจะจำนวน Filter และ Depth น้อยที่สุด หรือเรียกรวมๆ ว่ามีความ Complex น้อยที่สุดจากทั้ง 3 โมเดล ซึ่งหน้าที่มันก็ตรงตามชื่อคือตัวมันมีหน้าที่หา Bounding Box ของหน้าในภาพแบบคร่าวๆ และ Propose ให้ Stage ถัดไป

ขั้นตอนการทำงานใน Stage นี้คือ P-Net รับรูปมาแล้ว ผ่านการทำ Image Pyramid หรือการย่อขนาดรูปด้วยลงลงตามลำดับ โดยใน MTCCN จำทำการย่อขนาดรูปทั้งหมด 12 ครั้ง

รูปที่ 3

รูปที่ 3

ที่ต้องทำเช่นนี้เนื่องจากในตัว P-Net นั้นมีจำนวน Filters ของ CNN น้อยมาก ซึ่งเป็นที่รู้กันว่า CNN นั้น เป็น Layer ที่ไม่มี Size-Invaraint หรือก็คือไม่สามารถจับรูปเดียวกันที่มีขนาดแตกต่างกันได้ เค้าเลยใช้วิธีลดขนาดภาพและรันหลาย ๆ รอบแทน และเมื่อมันเจอ Bounding Box ของหน้าคนในขนาดภาพใดแล้ว เราจึงจะคำนวณย้อนกลับมาเป็นตำแหน่งในภาพขนาดจริง ซึ่ง Output ของตัว P-Net จะประกอบไปด้วย Bounding Box จำนวนมาก โดยเราจะเลือกเฉพาะ Bounding Box ด้วย Probability ของการมีใบหน้ามากกว่า Threshold ที่กำหนด และการ Non Maximum Suppression (NMS) ซึ่งจะทำให้เราได้เฉพาะ Bouding Box ที่ไม่ซ้ำกัน

รูปที่ 4

รูปที่ 4

2. Refine-Network (R-Net)

R-Net เป็นโมเดล CNN ที่มีความ Complex เพิ่มมากกว่า P-Net ขึ้นมาอีกหน่อย โดยที่ตัวมันจะรับรูปที่ อยู่ใน Bounding Box ที่ได้จาก P-Net มาเป็น Input ทีละอัน (หรือ R-Net จะ loop ทำทีละ Bounding Box นั่นเอง) จากนั้นมันจะหา Bounding Box ของหน้าในรูปเหล่านั้นอีกทีเพื่อที่เราจะได้ Bounding Box ที่แม่นยำมากขึ้น แล้วจึงทำการคัดเลือกเฉพาะ Bounding Box ที่มี probability ของการมีหน้าเกินค่า Threshold และทำ NMS เพื่อตัด Bounding Box ที่ซ้ำกันออกเหมือนกับใน P-Net

รูปที่ 5

รูปที่ 5

จะเห็นได้ว่าทั้ง P-Net และ R-Net นั้นขั้นตอนคล้าย ๆ กันเลย ต่างกันแค่ input ของ R-Net นั้นจะมาจาก Output ของ P-Net ซึ่งทั้งคู่ก็มี Threshold ในการเลือก Bounding Box เหมือนกัน แต่ว่าใน R-Net นั้นเรามักจะตั้ง Threshold ให้สูงกว่าใน P-Net เพราะว่าใน Stage นี้ โมเดลจะมีความมั่นใจมากขึ้นกว่าเดิมแล้ว เช่นใน P-Net จะตั้ง Threshold ไว้ประมาณ 0.5 ในขณะที่ R-Net จะตั้งไว้ประมาณ 0.7

3. O-Net

Side Note:

ในเปเปอร์ไม่ได้บอกไว้ไว้ว่าย่อมาจากอะไร แต่คิดว่าย่อมาจาก Output Net

O-Net จะเป็น Neural Network ที่มีความ Complex มากที่สุด โดย O-Net จะใช้ Output ของ R-Net เพื่อหา Bounding Box และ Face Probability อีกที โดยมีขั้นตอนคล้ายกับใน R-Net แต่พิเศษกว่าตรงที่ใน O-Net จะทำการหา Face Alignment ของแต่ละหน้าที่พบด้วย ซึ่ง Face Alignment นั้นประกอบไปด้วยตำแหน่งจำนวน 5 ตำแหน่ง ได้แก่ ตาสองข้าง, จมูก, และขอบซ้ายขวาของริมฝีปาก

รูปที่ 6

รูปที่ 6

ถ้าใครสังเกตุดีๆ อาจจะเห็นว่าใน Output layer ของ R-Net กับ O-Net นั้นเป็น Fully Connected Layer แต่ว่าของ P-Net ดันเป็น Fully Convolutional Neural Network ซะงั้น ที่ต้องเป็นแบบนี้ก็เพราะว่าเราต้องการให้ P-Net นั้นสามารถรับ Input เป็นภาพขนาดเท่าไหร่ก็ได้ในตอน Inference นั่นเอง แต่ในตอนเทรนมันจะรับภาพขนาด 12x12 เท่านั้นดังที่แสดงในรูปที่ 2 นั่นเอง

นอกจากนั้นแล้ว จะเห็นว่ามีเพียง O-Net เท่านั้นที่จะหา Face Alignment ให้ แต่ทำไมในทุกโมเดลในรูปที่ 2 มี Face Localization เป็นส่วนหนึ่งของ Output หมดเลยล่ะ?

เพราะว่าจริง ๆ แล้วตอนที่เทรนโมเดลนั้น นอกจากจะเทรน Bounding Box แล้วเรายังเทรนแบบ Multi-Task Learning โดยให้หา Face Localization ในทุกโมเดล เนื่องจากผู้เขียนเปเปอร์เค้าเชื่อว่าการเรียนแบบ Multitasking จะมีประสิทธิภาพมากกว่า แต่ในตอน Inference เราจะใช้เฉพาะ Face Localization แค่จาก O-Net เท่านั้น

Other Interesting Tricks in MTCNN

CNN Design Tip

อีก 1 ทริคที่น่าสนใจที่สอดแทรกไว้ในเปเปอร์นี้คือการ design ตัว CNN architecture โดยที่ในเปเปอร์นี้ผู้เขียนเค้านึกได้ว่าจริง ๆ การทำ face detection มันเป็นแค่ binary-classification เท่านั้นเอง เพราะฉะนั้นแล้วไม่จำเป็นต้องต้องใช้ filter จำนวนมากมายหรอก (ปกติแล้วใน CNN ที่เราต้องมีหลาย filter ก็เพื่อรองรับความหลากหลายของ shape, size, rotation ของวัตถุในภาพที่เราจะตรวจจับ) แต่สิ่งที่เราควรจะเพิ่มก็คือความสามารถในการแยกแยะหน้าคนกับ background ดังนั้นผู้เขียนเปเปอร์จึงได้ลดจำนวน filter ของ CNN layer ลงจากงานอื่น และเพิ่มความลึกของ neural network แทนนั่นเอง ซึ่งเค้าได้กล่าวว่าการทำเช่นนี้มีส่วนทำให้โมเดลเค้าแม่นยำกว่าและประมวลได้เร็วกว่างานอื่น

Online Hard Sample

ทริคสำคัญที่ส่งให้เปเปอร์นี้ก้าวไปเป็น state-of-the-art ได้คือคือการเลือกเทรน network ด้วย hard sample หรือก็คือเทรนด้วย sample ที่ network ยังเรียนรู้ได้ไม่ค่อยดีเป็นหลัก โดยที่หลังจากการทำ forward pass ในแต่ละ batch นั้น เทคนิคนี้จะทำการเรียงลำดับ sample ด้วย error ที่เกิดขึ้นจากแต่ละ sample และเลือกเฉพาะ sample ที่มี error มากที่สุด 70% แรกเท่านั้นมาคำนวณ gradient เพื่ออัพเดทตัว weight และ bias ของ networks ซึ่งการทำเช่นนี้จะช่วยทำให้ network เราเรียนรู้ได้เร็วขึ้นเนื่องจากเราบังคับให้มันสนใจแต่สิ่งที่ยังทำได้ไม่ค่อยดี นอกจากนี้ยังป้องกันการเกิด overfitting ได้เพราะว่า เมื่อ sample ไหนเรียนรู้ได้ดีแล้ว เราจะไม่นำมาให้ network เราเรียนรู้อีก

สรุป

​​MTCNN ใช้ประโยชน์จากเอกลักษณ์ของ Neural Network ที่แต่ละส่วนของ network ทำหน้าที่เฉพาะ และนำมาประยุกต์ให้เข้ากับ Face Detection เพื่อให้ได้โมเดลที่มีประสิทธิภาพและมีความซับซ้อนของโมเดลในระดับที่เหมาะสมกับความต้องการใช้งาน ซึ่งผลลัพธ์ที่ได้คือโมเดลที่มีความแม่นยำในระดับ State of the Art สำหรับงาน Face Detection เลยทีเดียว

สำหรับบทความนี้ก็คงจะขอจบไว้เพียงเท่านี้ หวังว่าจะเป็นประโยชน์สำหรับผู้อ่านไม่มากก็น้อยครับผม สำหรับผู้อ่านที่ต้องการทราบถึงความเร็วและความแม่นยำของ MTCNN นั้น สามารถตามไปอ่านกันต่อที่บทความนี้ได้เลยครับ