My state of research และ research statement ณ 2017
ช่วง 1–3 เดือนที่ผ่านมาผมได้มีโอกาสสัมภาษณ์เด็กที่สมัครเรียนต่อ และตรวจข้อเสนอวิทยานิพนธ์เด็ก ป.เอก ซึ่งหนึ่งในหัวข้อที่โผล่มาบ่อยๆ คือ “Research statement” ซึ่งบนเว็บบอกว่าเป็นการสรุปผลงานวิจัยที่ผ่านมาและสิ่งที่จะทำต่อในอนาคต ซึ่งอ่านๆ แล้วรู้สึกว่ามานั่งนึกหน่อยก็ดีว่าตัวเองทำอะไรมาแล้วบ้าง และจะทำอะไรดี
โดยส่วนตัวแล้วผมตีความว่า research statement ควรอธิบายความเชื่อส่วนตัวเกี่ยวกับงานวิจัยที่กำลังทำ งานที่ทำมาแล้วแต่ไม่ค่อยเกี่ยวมันไม่น่าเอามาใส่เท่าไร แต่ไหนๆ จะนั่งทบทวนแระขอใส่ซักหน่อย เอาเป็นส่วน state of research ก่อน ค่อยมาดู research statement ละกัน
3D model inference using Evolutionary Strategy ฝึกงาน ป.เอก
ทำที่ ENSTA กับ อ. Jean Louchet ถึงขั้นต้อง google ชื่อเลย นานแล้ว 555
จำได้ว่าตอนฝึกงานมันอยู่ปารีสแถวๆ ตะวันตกเฉียงใต้ ตอนนี้เหมือนจะย้ายที่แล้ว
ถ้าจำไม่ผิด โจทย์คือเราสมมติว่ากล้ามเนื้อนั้นสามารถแทนได้ด้วยสปริงกับมวล ซึ่งมีตัวแปรคือความแข็งของสปริง กับมวล เมื่อเราตั้งค่าให้สปริงกับมวลทั้งหมดแล้ว เราก็สามารถขยับแบบจำลองนี้ได้ ซึ่งเราสามารถบันทึกจุดปลายของสปริงแต่ละอันได้ เช่นถ้าเราเอาสปริงแบบนี้มาต่อเป็นคน เมื่อเราขยับก็จะได้ตำแหน่งของข้อต่อต่างๆ มาเป็นลำดับตามเวลา
สมมติว่าเรามีจุด 3 มิติของข้อต่อเหล่านี้ (อาจจะได้มาจากแบบจำลองอีกอัน หรือจากตำแหน่งข้อต่อจริงของคนก็ได้) โจทย์คือทำอย่างไรจะเลือกค่าของสปริงกับมวลทั้งหลายให้เหมาะสมเพื่อให้จุด 3 มิติ ที่ได้นั้นสอดคล้องกับค่าที่ได้มาในตอนต้น
อาจารย์เขาสนใจการใช้ Evolutionary Strategy (ES) เพื่อหาค่าเหล่านี้
ES เป็นเทคนิคการทำ optimization โดยใช้ idea ของ natural selection อีกแบบหนึ่งที่เน้นที่ตัวแปรแบบจำนวนจริงและ mutation เป็นหลัก ต่างจาก Genetic Algorithm (GA) ที่ทำงานกับตัวแปร discrete และใช้ทั้ง cross-over กับ mutation และต่างจาก Genetic Programming (GP) ที่โครโมโซม encode ทั้งค่าตัวแปรและฟังก์ชัน
ใน ES เราก็เริ่มจากการ generate โครโมโซมที่ encode คำตอบที่เป็นไปได้กลุ่มหนึ่ง จากนั้นก็เลือกเอาเฉพาะโครโมโซมที่ดีๆ มาเพื่อทำ mutation สร้างโครโมโซมมาทดแทนตัวที่แย่ๆ
ที่น่าสนกว่า GA คือเมื่อเราเลือกโครโมโซมที่ดีๆ ได้แล้ว เราสามารถเอาโครโมโซมพวกนี้มาปรับแบบจำลองที่ใช้ในการสุ่มได้ด้วย สมมติว่าเราสุ่มแบบ Gaussian เราก็สามารถนำโครโมโซมที่ดีมาปรับ covariance matrix ได้
ดังนั้นในรอบหลังๆ เราจะได้การสุ่มในทิศทางที่มีความน่าจะเป็นว่าจะได้ของดีมากขึ้น
นอกจากนี้ผมว่าเรายังวามารถเอาแบบจำลองการสุ่มที่ปรับนี้ไปใช้เป็น prior สำหรับเทคนิคพวก Bayesian ได้อีกต่างหาก ไม่รู้มีใครทำหรือยัง
สิ่งที่น่าสนใจได้เรียนจากงานนี้นอกจาก ES แล้วคือ concept ของ epistasis ซึ่งในทางชีวะมันคือการขึ้นต่อกันของยีนต่างๆ ในโครโมโซม ซึ่งมีคนเอามาเปรียบเทียบการขึ้นต่อกันของตัวแปรใน optimization
ถ้าปัญหา optimization ที่เราสนใจมี epistasis ต่ำ คือตัวแปรต่างๆ ไม่ขึ้นต่อกัน เทคนิคที่ควรใช้ก็คือพวก gradient
ถ้ามี epistasis เพิ่มขึ้น ก็ควรใช้ conjugate gradient ถ้าสูงขึ้นอีกก็อาจจะพวก GA, ES, GP ต่างๆ และถ้าสูงมากๆ ก็ taboo search หรือ random search
NN-HMM สำหรับการรู้จำลายมือเขียนแบบ online
อันนี้มาจากงาน ป.เอก ทำกับ อ. Patrick Gallinari และ Thierry Artières โดยทำต่อจากรุ่นพี่ที่แลป
online ในที่นี้หมายถึงใช้สัญญาณที่ได้จากปากกา electronics ต่างจาก offline ที่ใช้ bitmap
โจทย์ก็เป็น sequence modeling แบบหนึ่ง ที่ใช้ HMM เป็นหลักในการ decode+recognize แต่ที่แลปเราใช้ NN แบบ MLP ในการทายค่า feature vector ที่ตำแหน่งต่างๆ ในลำดับ เราสามารถแปลง squared error ที่ได้เป็น emission probability ได้
model ของอักษรแต่ละตัวเป็น left-right HMM
HMM ของคำก็สร้างจากการเอา HMM ของอักษรมาต่อกัน และ HMM ของประโยคก็สร้างจาก HMM ของคำ
วิธีนี้เหมือนกับการทำ speech recognition พอจบมาเลยคุยกับพวก speech รู้เรื่องอยู่ นอกจากนี้ยังทำให้เข้าใจการแบ่ง acoustic/language model ใน speech ด้วย
ประโยชน์อีกอย่างคือผมเอาวิธีการ decode แบบเดียวกันมาใช้ทำ approximate search ที่ใช้คำนวณ edit distance ระหว่าง input string กับ string ใน dictionary ที่จัดเก็บในรูป Trie
- T. Artières, P. Gallinari, L. Hifeng, S. Marukatat, B. Dorrizi, “From character to sentences: a hybrid neuro-Markovian for on-line handwritten recognition”, chapter in Hybrid Methods in Pattern Recognition eds. H. Bunke and A. Kandel, 2002
Segmental HMM สำหรับการรู้จำสัญลักษณ์
เป็นอีกส่วนของงาน ป.เอก ที่เริ่มมาจาก idea ของ Thierry
แนวความคิดหลักคือใช้ Segmental HMM ในการสร้างแบบจำลองของอักษรหรือสัญลักษณ์ ตอนที่ทำนั้นผมสนใจแต่ตัว model เพราะคณิตศาสตร์ของมันสวยดี มาคิดย้อนดูท่าทาง Thierry จะสนใจความสามารถของ model ที่ train ได้ด้วยตัวอย่างน้อยๆ มากกว่า
ถ้าเอาง่ายๆ แต่ละ state ของ HMM มัน model สัญญาณที่เป็นเส้นตรงหรือเส้นโค้งขนาคคงที่ และ model นี้ไม่เปลี่ยนไม่ว่าเราจะอยู่ใน state นี้นานเท่าไร สำหรับเส้นตรงมันก็ใช้ได้อยู่แต่สำหรับเส้นโค้งถ้าเราอยู่ใน state นี้นานขึ้น model ที่มีก็อาจจะออกห่างจากค่าจริงไปมากก็ได้ วิธีที่จะทำให้ model นี้ดีขึ้น คือการสร้าง model เส้นที่ขึ้นกับระยะเวลาที่เราอยู่ใน state นั้นๆ
model คณิตศาสตร์ที่ได้นั้นก็เป็นตระกูล Markov แต่แต่ละ state output ของที่เป็น segment แทนที่จะเป็น observation โดดๆ การ decode+recognize ก็ยังใช้ Viterbi algorithm คล้ายกับ HMM ปกติ แต่ต้องเพิ่มการ search มาอีก 1 แกนสำหรับระยะเวลาที่เราอยู่ในแต่ละ state ที่แลปเลยเรียกกันว่า Viterbi3D
แกนที่เพิ่มมาทำให้การ decode นั้นนานขึ้นเลยเอาไปใช้กับ model คำหรือประโยคไม่ไหว เลยเอาแค่สัญลักษณ์โดดๆ พอ
หลังจากนั้นผมก็ไปเพิ่มพวก spatial information อีกเล็กน้อยให้มันครบๆ
- T. Artières, S. Marukatat and P. Gallinari “Online Handwritten Shape Recognition using Segmental Hidden Markov Model”, in IEEE Transactions on Pattern Analysis and Machine Intelligence, 2007
Sign Random Projection
อันนี้เป็นงานที่เนคเทคแระ เป็นบทสรุปส่วนตัวอันนึง
เรื่องของเรื่องที่ที่แลปทำงานด้าน image ก็มีคนทำงานพวก image search อยู่เรื่อยๆ หลักๆ คือเปลี่ยนฐานข้อมูลรูป ไม่ก็ feature หรือวิธีเปรียบเทียบ
เนื่องจากไม่อยากทำอะไรซ้ำกับคนอื่นเลยลองหาโจทย์อื่นคล้ายๆ กันดู ก็เจอว่างานพวก relevance feedback (การเอา feedback จาก user มา refine search) นี่ยังไม่มีคนทำเท่าไร พอดีตอนนั้นผมสนใจ semi-supervised learning อยู่และรู้สึกว่ามันน่าจะใช้กับงานนี้ได้เลย เลยลองมาทำดู
ปรากฏว่าคอขวดของวิธีที่ทำไปอยู่ที่ก่ีหารูปที่คล้ายกัน (nearest neighbor search) ที่กินเวลานาน เลยลองหาดูวิธีเพิ่มความเร็วในการ search ดู
ของที่เจอน่าสนมาก คือโดยปกติถ้าจะเพิ่มความเร็วเราก็มักจะมองที่การจัดเรียงข้อมูลก่อน เช่นในรูป binary search tree หรือ quad-tree หรือ tree ที่ advance ขึ้นไป แต่มีคนไปทดลองแล้วพบว่าใน dimension สูงๆ tree พวกนี้ใช้หา 1-NN ได้เร็วจริง แต่ k-NN ยังช้าอยู่ เพราะเพื่อนบ้านที่ใกล้อาจไม่ได้อยู่ที่ leaf node เดียวกันหมด ดังนั้นเลยมี overhead ที่ต้องเช็ค node ข้างเคียงด้วย
วิธีที่เร็วกว่านั้นคือการทำ Hashing
Hashing คือการแปลงข้อมูลให้เป็น code อะไรบางอย่าง ถ้าในการเก็บข้อมูลเราก็อยากให้ code ที่ได้นี้ unique แต่ในการหาเพื่อนบ้านนี้เราอนุญาตให้ซ้ำกันได้ ขอแค่ให้ code ที่ซ้ำกันนั้นมาจากจุดที่เป็นเพื่อนบ้านกัน
หนึ่งใน Hashing ที่ผมสนใจตอนแรกนั้นคือ Spectral Hashing หลักๆ เพราะอ่านรู้เรื่องและ implement ได้ 555
หลังจากค้นเพิ่มก็พบว่ามีอีกวิธีที่ง่ายขึ้นไปอีกและให้ผลดีคือ sign random projection หลักๆ คือสร้าง projection matrix จากการสุ่มแบบเกาส์ และผลจากการทำ projection ของเวคเตอร์ลงบนแกนหนึ่งๆ นั้นเราจะดูแค่ขั้ว (sign) ของมันว่าเป็นบวกหรือลบ นี่แปลว่าเรากำลังแปลงข้อมูลจาก feature vector เดิมให้อยู่ในรูป binary string นั่นเอง
ข้อดีหลักๆ ของ code ที่อยู่ในรูป binary string นั่นคือในการเปรียบเทียบ code เราใช้ Hamming distance ที่คำนวณได้ผ่าน bitwise operations ซึ่งเร็วกว่า Euclidean distance ใน space เดิมมากกกกก
นอกจากนี้ถ้าเราคิดต่ออีกนิดจะพบว่า 8-bit string นั้นมีค่าได้เพียง 256 ค่าเท่านั้น นั่นแปลว่า Hamming distance ที่เราสนใจนั้นสามารถคำนวณไว้ล่วงหน้าได้ และใช้ที่เก็บแค่ array ขนาด 256x256 เท่านั้นเอง
การคำนวณ Hamming distance ระหว่าง code ที่ยาวเกิน 8 bit ก็ทำได้โดยการไป look-up ค่าจากตารางนี้แล้วนำมาบวกกันเท่านั้นเอง เพียงเท่านี้เราก็สามารถค้นคืนเพื่อนบ้านได้เร็วมากแล้ว
ข้อควรระวังคือ Hamming distance เป็นจำนวนเต็ม ซึ่งซ้ำกันได้เยอะ การ sort โดย quick-sort นั้นจะช้ามากกกก วิธีทำให้เร็วคือไม่ต้อง sort จริงๆ แต่เก็บค่าใส่ histogram แทน (ลองคิดต่อเอง เป็นแบบฝึกหัดที่ดี)
ของสนุกที่เกิดขึ้นคือจริงๆ แล้วค่า Hamming distance ที่ได้นี้สามารถนำมาประมาณค่ามุมระหว่าง feature vector ใน space เดิมได้
ดังนั้นเรารู้ว่าถ้าเราต้องการประมาณค่า Euclidean distance จริงๆ เราก็ควรเก็บขนาดของเวคเตอร์ต้นฉบับไว้ด้วย ซึ่งทำให้เราไม่ต้องเก็บ feature vector เดิมไว้เพื่อการทำ re-ordering
นอกจากนี้ที่น่าสนอีกอย่างคือเราสามารถเอา binary code พวกนี้มาสร้าง classifier ง่ายๆ ที่ให้ผลเหมือนกับ linear classifier ด้วยความน่าจะเป็นสูงในกรณีที่ของเขตระหว่างทั้งสอง class นั้นเป็นเส้นตรงจริง
น่าเสียดายที่พอทดสอบกับข้อมูลยากๆ หน่อยผลไม่ค่อยดีเท่าไร ต้องเอา Boosting มาช่วยซึ่งทำให้ช้ามากกก ทำให้รู้สึกว่ายังจบไม่สวยเท่าไร ไว้ว่างๆ อาจงัดมาทำต่อ
- S. Marukatat and I. Methasate “Fast nearest neighbor retrieval using randomized binary codes and approximate Euclidean distance”, in Pattern Recognition Letters, 2013
- S. Marukatat “Classification with Sign Random Projection” in PRICAI conference 2014
Approximate eigen-decomposition of kernel matrix
บทสรุปอีกอันสำหรับโจทย์ที่ว่างๆ ก็เอามาคิด
ในตอนทำ ป.เอก นั้นผมใช้ NN กับ HMM เป็นหลักซึ่งตอนนั้น SVM เริ่มจะดังแล้ว พอมาทำงานที่เนคเทคผมเลยสนใจพวก SVM และ kernel machine ต่างๆ เป็นพิเศษ
หนึ่งในปัญหาของเทคนิคพวกนี้คือเราไม่รู้ว่า mapping function ของ kernel นั้นเป็นอย่างไร เรารู้เพียงว่า ถ้าเรา map ข้อมูล 2 ตัวผ่านฟังก์ชันนี้แล้วเอามา dot กัน ผลที่ได้นั้นเท่ากับการคำนวณค่าจาก kernel ระหว่างข้อมูลทั้งสองใน space ตั้งต้น เราเรียก space ใหม่ที่เกิดจาก mapping function นี้ว่า RKHS
ผลจากการที่เราไม่รู้จัก mapping function ทำให้เราไม่สามารถทำงานในเจ้า RKHS ได้โดยตรง เช่นเราทำ PCA ที่ใช้ covariance matrix ไม่ได้ ต้องทำ kernel PCA (KPCA) ที่ใช้ kernel matrix แทน
ปัญหาคือ kernel matrix ที่เกิดขึ้นนั้นมีขนาดเท่ากับ nxn เมื่อ n เป็นจำนวนตัวอย่างที่มี มันทำให้เราทำงานลำบากบนข้อมูลใหญ่ๆ
หนึ่งในวิธีการลดการคำนวณคือการพยายามประมาณเจ้า mapping function ของ kernel ขึ้นมา เช่นการทำ empirical kernel map (EKM) ที่หลักๆ เป็นการแปลงข้อมูล x ให้อยู่ในมิติ n ที่แต่ละ coordinate i ก็คือค่า k(x,x_i) เมื่อ k คือ kernel function, x_i คือตัวอย่างที่ i
EKM นี้มักจะใช้คู่กับการทำ whitening กลายๆ เพื่อปรับให้ dot product ใหม่มีค่าตรงกับค่า kernel เดิม และมักจะใช้ในขั้นตอน post-processing ของ SVM เพื่อลดความซับซ้อนใน runtime สำหรับ KPCA นั้นเราไม่ใช้ EKM เพราะการทำ whitening นั้นก็ต้องทำ eigen-decomposition เช่นเดียวกับ KPCA ดังนั้นมันไม่ได้ช่วยให้ทำได้เร็วขึ้น
ช่วง 4–5 ปีก่อนนี้มั๊งที่เริ่มมีคนเสนอวิธี approximate แต่มันใช้ได้แค่กับ kernel บางชนิดเท่านั้น ผมเองก็รับเด็กฝึกงานมาช่วยทดสอบเทคนิคนี้อยู่
ช่วงที่ตรวจรายงานเด็กนั้นฉุกคิดได้ว่า EKM ที่ไม่ได้ผ่าน whitening นั้นเมื่อนำไปคำนวณ dot product อาจไม่ได้ค่า kernel ก็จริงอยู่ แต่ถ้าเราเอาเวคเตอร์ที่ได้นี้มาคำนวณ covariance matrix ผลที่ได้นั้นเท่ากับกำลังสองของ kernel matrix อันนี้น่าสนใจมากเพราะเป็นประเด็นที่คนมองข้ามกัน
ปัญหาคือเมตริกซ์ใหม่นั้นยังขนาดเท่าเดิม ดังนั้นดูเผินๆ แล้วเหมือนกับเราไม่ได้ลดการคำนวณลงแต่อย่างไร แต่การที่เราทำ EKM นั้นผลที่ได้คือเวคเตอร์ที่เรารู้ค่า coordinate ดังนั้นเราน่าจะสามารถลดการคำนวณได้ เช่นจากการทำ random projection แบบงานก่อนนี้
ทั้งนี้จะทำ random projection ดุ่ยๆ ก็ดูกระไรอยู่ ผมก็อยากได้การันตีบางอย่างว่าค่าที่ได้มันจะต่างจากค่าจริงเท่าไร โชคดีที่พบว่าการทำ random projection นี้ไม่ได้ทำให้ค่า dot product เปลี่ยนไปเท่าไร ซึ่งคุณสมบัตินี้สามารถนำไปใช้ในการ approximate eigen-decomposition ของ covariance matrix ได้
จริงๆ แล้วแนวความคิดหลักของ approximate eigen-decomposition ของ covariance matrix นี้ย้อนไปสมัยแรกๆ ที่ผมเริ่มงานที่เนคเทค
ช่วงนั้นผมสนใจพวก face recognition อยู่ ซึ่งตอนนั้นเทคนิคมาตรฐานก็คือ Eigenface ที่อิง PCA หรือ Fisherface ที่อิง LDA นอกจากนี้ก็มีพวก projection แบบอื่นๆ อีกมากมาย
ข้อสังเกตที่ได้จากตอนนั้นคือ Eigenface ที่ได้จากฐานข้อมูลภาพที่ scale หรือขนาดต่างกันนั้นมีลักษณะคล้ายกันมาก จากข้อสังเกตนี้นำไปสู่แนวความคิดที่ว่า eigenvector ของ covariance matrix มันให้ค่าถ่วงน้ำหนักของ feature ต่างๆ ดังนั้นเจ้า eigenvector ของ dot matrix (หรือ kernel matrix) ก็น่าจะให้ค่าถ่วงน้ำหนักของตัวอย่างต่างๆ
และค่าถ่วงน้ำหนักของตัวอย่างต่างๆ นี้น่าจะสามารถเอามาเปรียบเทียบข้าม scale ได้
หลังจากไปค้นๆ ดูหนังสือคณิตศาสตร์ต่างๆ ก็ได้ข้อสรุปว่ามันสามารถทำได้ถ้าค่า dot product ใน scale เดิมและ scale ใหม่ไม่ต่างกันมากนัก
ผลลัพธ์ที่ได้นี้จึงสามารถนำไปใช้กับกรณี covariance matrix ของ EKM ได้นั่นเอง
- S. Marukatat “Kernel matrix decomposition via empirical kernel map” in Pattern Recognition Letters, 2016
Local intensity distribution equalization
โจทย์ที่คิดตอนแรกน่าจะมาจากการทำ binarization คือการแบ่งค่า grayscale ของภาพจาก 256 ค่า ออกเป็นแค่ 2 ระดับคือ 0 กับ 255 ซึ่งโดยปกติ 0 คือสีของอักษรและ 255 คือสีของฉากหลังในการทำ OCR
เรารู้ว่า binarization มีปัญหากับรูปที่แสงไม่คงที่ วิธีแก้คือทำ local binarization นั่นคือ binarization ที่ใช้ค่าสถิติอย่างพวก mean และ sd จาก window local รอบๆ แต่ละจุดภาพ ปัญหาคือการคำนวณนี้มันนาน เลยทำได้กับ window เล็กๆ คำถามคือทำไงให้เร็วขึ้น?
คำตอบที่ผมคิดได้คืออาศัย Integral Image (II) ที่ใช้ใน OpenCV face detection
Integral Image นั่นใช้ในการคำนวณผลบวกของค่า intensity ใน area ย่อยในภาพอย่างเร็ว ในเมื่อเราคำนวณผลรวมได้เราก็คำนวณค่า mean local ได้เร็วเช่นกัน
ถ้าคิดต่ออีกนิดจะได้ว่าเราสามารถเขียน variance ในรูปของผลบวกได้เช่นกัน ดังนั้นการทำ adaptive binarization จึงทำได้เร็วขึ้นเยอะ
จากการที่ผมคำนวณ variance ด้วยวิธีนี้ได้เร็วด้วย II ผมเลยสงสัยว่าเรายังสามารถใช้ II คำนวณอย่างอื่นได้อีกหรือไม่ ปรากฏว่าเราสามารถเขียนการคำนวณฮีสโตแกรมในรูปของ II ได้เช่นกัน ดังนั้นเราจึงสามารถทำ Adaptive Histogram Equalization (AHE) ได้ด้วยวิธีนี้
โดยปกติแล้วเราทำ AHE ตรงๆ ไม่ได้เพราะติดที่การคำนวณฮีสโตแกรม local นี่แหละ ตอนแรกคิดว่าน่าสนแล้ว แต่พอ submit งานไปมี reviewer ที่บอกว่ายังไม่เยอะพอ เลยมานั่งคิดต่อ
Histogram Equalization (HE) คือการปรับค่าสี grayscale ของรูปโดยการนำฮีสโตแกรมของ intensity มา “ยืด” ให้มัน cover ทั่วทั้ง 256 ค่า อันนี้คือวิธีคิดแบบ image processing
ถ้าคิดแบบสถิติสิ่งที่ HE ทำคือการ map ค่าผ่าน Cumulative Distribution Function (CDF) ซึ่งในกรณีของ HE นั้น CDF คำนวณจากฮีสโตแกรม แต่ในเมื่อเราคำนวณ mean กับ sd local ได้ เราก็น่าจะสามารถใช้ CDF แบบอื่นได้เช่นกัน
แนวความคิดนี้นำมาสู่การทำ equalization โดยใช้ model อื่นคือ Gaussian, Laplacian และ Mixture Model แทนฮีสโตแกรมธรรมดา
ของที่น่าสนคือในการปรับตัวแปรของ Mixture Model ด้วย EM algorithm ค่าผลรวมที่ใช้นั้นก็สามารถคำนวณด้วย II ได้อีก เรียกได้ว่าใช้จนคุ้มเลย
ถ้าไม่โดน reject มาตอนแรกคงไม่ได้ทำ model แปลกๆ พวกนี้ 555
- S. Marukatat “Image enhancement using local intensity distribution equalization” in EURASIP journal on Image and Video Processing, 2015
งานหลักๆ ที่ทำไปก็ประมาณนี้ งานที่เหลือค่อนข้างจับฉ่าย มาคิดต่อดีกว่าว่าต่อไปจะทำอะไรดี
โดยส่วนตัวแล้วผมตีความว่า research statement ควรอธิบายความเชื่อส่วนตัวเกี่ยวกับงานวิจัยที่กำลังทำ งานที่ทำมาแล้วแต่ไม่ค่อยเกี่ยวมันไม่น่าเอามาใส่เท่าไร แต่ไหนๆ จะนั่งทบทวนแระขอใส่ซักหน่อย เอาเป็นส่วน state of research ก่อน ค่อยมาดู research statement ละกัน
ในช่วง 2 ปีมานี้งานที่ผมศึกษามากสุดก็คงเป็นพวก Deep Learning
โจทย์ที่กำลังทำอยู่ตอนนี้เกี่ยวกับ Generative NN ที่ใช้สร้างภาพแบบใน Generative Adversarial Networks (GAN)
ควรทราบว่าในช่วงประมาณ 1–2 ปีที่ผ่านมานี้งานหนึ่งที่มีคนสนใจมากคือ GAN นี่แหละ มีกระทั่งคนที่บอกว่ามันเป็นแนวความคิดที่น่าสนใจสุดในรอบ 10 ปีนี้เลย
GAN ประกอบด้วย NN 2 อัน อันแรกเรียกว่า Generator มีหน้าที่สร้างภาพ (หรือข้อมูลอื่นที่เราสนใจ) จากข้อมูลนำเข้าที่เป็น noise และ NN อันที่สองคือ Discriminator ที่มีหน้าที่ตัดสินใจว่าภาพที่เราใส่ให้นั้นมาจากฐานข้อมูลภาพจริงหรือมาจาก output ของ Generator กันแน่
การ train Discriminator ก็ทำตามปกติ แต่สำหรับ Generator นั้นเราจะพยายามสอนให้มันหลอก Discriminator ให้สำเร็จ
ถ้าให้ D(x) เป็นฟังก์ชันที่ Discriminator implement เมื่อ x เป็น ภาพ input ของมัน
ให้ z เป็น random noise และ G(z) เป็น output ของ Generator
Discriminator นั้นพยายาม maximize P(Real|x) และ P(Fake|G(z))
ส่วน Generator ก็พยายาม maximize P(Real|G(z)) นั่นเอง
แนวความคิดดูง่ายๆ แต่เอาเข้าจริงที่ผมลอง implement เอง ดูแล้วผลยังไม่ค่อยดีเลย ลองดู code คนอื่นบนเว็บก็คล้ายๆ กับที่ทำ จะต่างกันตรงเขาทำ CNN ใหญ่ๆ กันทั้งนั้นเลย ผมไม่คิดว่าเราต้องใช้ CNN ที่ใหญ่ขนาดนั้น
สิ่งที่ผมไม่ชอบใน GAN คือ ข้อมูลที่เราเอามาปรับ Generator นั้นมาจาก Discriminator ที่พอหมดงานนี้ก็ไม่ได้มีประโยชน์อะไร เหมือนกับว่าเราสร้างครูขึ้นมาคนหนึ่งพร้อมๆ กับเด็ก พอเด็กเรียนจบแล้วครูก็หมดประโยชน์ มันดูน่าเสียดาย ถ้าเราสามารถดึงอะไรซักอย่างมาใช้ในการ train Generator อันถัดไปได้คงดี
นอกจากนี้การที่เราเริ่ม backprop จาก node เพียง node เดียวของ Discriminator ย้อนกลับมาจนถึง Generator นั้นดูจะไม่ค่อย efficient เท่าไร ผมว่าผมทำได้ดีกว่านี้ แนวความคิดหลักที่สำคัญอยู่ที่การคำนวณ gradient
ผลจาก preliminary test ก็ดีกว่าจริง แต่ยัง claim ได้ไม่เต็มปากเพราะยังทำให้ GAN เวิร์กได้ไม่ดีเท่าไร ตอนนี้เลยปรับต่อไป
อีกอย่างที่ไม่ชอบใน GAN (อันสุดท้ายละกัน ท่าจะเยอะขึ้นเรื่อยๆ) คือมุมมองที่ว่า input เป็น noise (ซึ่งเดี๋ยวนี้เริ่มเปลี่ยนแระ) คือผมว่า input ของ Generator มันน่าจะพิจารณาเหมือนเป็น latent variable ที่ใช้ generate รูปได้ ดังนั้นมันน่าจะ encode ข้อมูลที่มีความหมายอยู่ จริงอยู่ว่าความหมายที่ว่านี้จะมากหรือน้อยคงขึ้นกับ Generator ที่ใช้ด้วย ผมเชื่อว่าถ้า Generator มัน complex มาก ความหมายที่เหลือใน latent variable เหล่านี้คงน้อย แย่สุดคงกลายเป็น noise จริงๆ แต่ถ้า Generator มีความสามารถจำกัด ความหมายแฝงใน latent variable เหล่านี้น่าจะเยอะอยู่ จนเราน่าจะสามารถเอาไปทำงานอื่นต่อได้ นี่เป็นอีกเหตุผลหนึ่งที่ผมไม่อยากได้ Generator ใหญ่ๆ แต่ทั้งหลายทั้งปวงที่เล่าในย่อหน้านี้ยังเป็นเพียงการคาดเดา คงต้องเล่นกับมันอีกพักก่อนจะตกผลึก หรือไม่ก็ตกตะกอนให้เททิ้งไป 555
จริงๆ ยังมีโจทย์อื่นที่เก็บไว้คิดต่ออีกเวลาว่างๆ หลักๆ ก็เกี่ยวกับ internal representation ของ CNN นี่แหละ ว่าเราจะ train ไงดี แล้วมันเอาไปใช้อะไรได้บ้าง แต่เริ่มยาวไปแล้วพอแค่นี้ดีกว่า