วันเสาร์ที่ 28 เมษายน พ.ศ. 2561

8) การเขียนเครื่องมือการแยกแยะด้วยต้นไม้ตัดสินใจจากโจทย์จริง การเรียนรู้ของคอมพิวเตอร์ แมชชีนเลิร์นนิ่ง ตอนที่ 8

8) การเขียนเครื่องมือการแยกแยะด้วยต้นไม้ตัดสินใจจากโจทย์จริง 
การเรียนรู้ของคอมพิวเตอร์ แมชชีนเลิร์นนิ่ง ตอนที่ 8


ในบทเรียนที่แล้ว เราได้ทำการแยกแยะรูปภาพ ด้วยเทนเซอร์โฟลว สำหรับศิลปิน กันไปแล้ว และในบทเรียนนี้เราจะมาเรียนรู้วิธีการเขียนโค้ดโปรแกรมด้วย TF.Learn กัน
ปัญหาเริ่มแรกที่จะกล่าวถึงในบทเรียนนี้ก็คือ การแยกแยะตัวอักษรแต่ละตัวที่เขียนโดยมนุษย์ จาก เซ็ตข้อมูล MNIST และเขียนคลาสสิฟายเออร์แบบง่ายๆ เหมือนเราเริ่มเขียนโค้ดโปรแกรมสวัสดีชาวโลกสำหรับคอมพิวเตอร์วิชั่น (การมองเห็นของคอมพิวเตอร์) ด้วยปัจจุบัน MINIST เป็นปัญหาการจัดกลุ่มหรือแยกแยะแบบคลาสผสมหรือ มัลติคลาส สมมติให้รูปภาพของตัวเลขแต่ละตัว คืองานที่เราต้องการทำการจัดกลุ่มแยกแยะ หรือทำนายว่าตัวเลขนั้นคือตัวเลขอะไร เราจะเริ่มต้นด้วยการเขียนโปรแกรม ด้วย IPython notebook (Jupyter Notebook) ในบทเรียนนี้ ตัวอย่างโค้ดโปรแกรม และเพื่อให้ง่ายต่อการเริ่มต้น ด้วยการกำหนดสภาพแวดล้อมการทำงาน เราจะมาดูวิธีการติดตั้ง โดยสังเขปกันก่อน
เท็นเซอร์โฟลวใช้ดอกเกอร์ (Docker) ซึ่งเป็นเรื่องแรกที่เราต้องเรียนรู้
เราจะเริ่มต้นด้วยวิธีการดาวน์โหลด เซ็ตข้อมูล (Dataset) และแสดงผลภาพ จากนั้นจะทำการสอนคลาสสิฟายเออร์และประเมินผลว่าคลาสสิฟายเออร์ของเรามีความแม่นยำเพียงไร เพื่อใช้ในการทำนายรูปภาพใหม่ๆ ที่คอมพิวเตอร์ยังไม่เคยพบเห็นมาก่อน และสุดท้ายจะแสดงให้เห็นถึงน้ำหนักของการเรียนรู้ของคลาสสิฟายเออร์หรือเครื่องมือแยกแยะข้อมูลของเราว่ามีความฉลาดมากน้อยเพียงไร ภายใต้กรอบที่กำหนด
  1. ติดตั้ง (Installation)
  2. ดาวน์โหลดเซ็ตข้อมูล (Download dataset)
  3. แสดงผลภาพ (Visualize images)
  4. สอนคลาสสิฟายเออร์เพื่อทำการแยกแยะข้อมูล (Train a classifier)
  5. ประเมินผลความแม่นยำของคลาสสิฟายเออร์ (Evaluate)
  6. แสดงให้เห็นถึงความฉลาดในการทำนาย (Visualize weights)

1. ติดตั้ง (Installation) เริ่มต้นด้วยการติดตั้งเท็นเซอร์โฟลว (Installing TensorFlow) สำหรับการติดตั้งบน Installing TensorFlow on Windows ให้ทำตามขั้นตอนที่กำหนด เมื่อติดตั้งเรียบร้อยแล้ว
ติดตั้ง Docker สำหรับวินโดว์ เวอร์ชั่น และสำหรับเวอร์ชั่นอื่น

หลังจากติดตั้งและลงทะเบียน Docker เรียบร้อยแล้วให้ติดตั้ง Docker Toolbox สำหรับเวอร์ชั่นวินโดวส์ 10 คลิก

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


หลังจากโปรแกรมทำงานจะพบหน้าเทอร์มินอล มีรูปวาฬ ดังตัวอย่าง พร้อมปรากฏ IP Address 192.160.99.100 อยู่บรรทัดถัดมาจากวาฬ ทั้งนี้ IP Address อาจแตกต่างกันไปตามแต่ละบริบทของคอมพิวเตอร์แต่ละเครื่อง ให้ทำการสำเนาไว้เพื่อใช้งานในภายหลัง
ขั้นตอนถัดไปให้ทำการเปิด Docker container ด้วย TensorFlow image ซึ่ง image ถูกวางไว้ที่ Docker hub


$ docker run -it -p 8888:8888 tensorflow/tensorflow









จากรูปที่กำหนดให้จะเห็นได้ว่า เป็นเรื่องยากที่คอมพิวเตอร์จะตีความและเข้าใจ
เนื่องจากภาพนี้มีความละเอียดต่ำ เพียง 28 * 28 พิกเซลในระบบสีขาวดำเทา
นอกจากนี้ยังถูกแบ่งออกเป็นส่วนๆ เท่าๆ กัน
นั่นหมายความว่ารูปแต่ละรูปคือตัวเลขจำนวนหนึ่งตัว


ไม่ต้องการทำวิศวกรรมฟีทเจอร์ (No feature engineering)
  • ใช้เพียงข้อมูลดิบในรูปแบบพิกเซลเท่านั้น
  • คลาสสิฟายเออร์ทำหน้าที่แยกแยะจัดกลุ่ม
หากมาพิจารณาฟีทเจอร์ที่นำมาใช้ในการแยกแยะจัดกลุ่มข้อมูลแล้ว
เมื่อเราต้องการทำแมชชีนเลิร์นนิ่งกับรูปภาพ เราจะใช้ข้อมูลดิบในรูปแบบพิกเซล เป็นฟีทเจอร์
เนื่องจากเป็นฟีทเจอร์ที่สามารถถูกแยกแยะได้ดีในกรณีของรูปภาพ ในขณะที่ถ้าเป็นฟีทเจอร์ของพื้นผิว และรูปทรง จะแยกแยะได้ยาก

ดังนั้น รูปภาพที่มีขนาด 28 * 28 พิกเซลนั้น จะมีจำนวนพิกเซลรวมถึง 784 พิกเซล นั้นหมายความว่าเราจะมีฟีทเจอร์เพื่อใช้เป็นเงื่อนไขในการแยกแยะจัดกลุ่มถึง 784 ฟีทเจอร์
นอกจากนี้ ในกรณีเราใช้รูปภาพที่มีการนำเสนอแบบแบนราบ
นั่นหมายความว่าเราต้องทำการแปลงรูปภาพในระบบอะเรย์ 2 มิติ ให้อยู่ในรูปแบบอะเรย์ 1 มิติ โดยไม่ให้อยู่ในแนวนอน แต่ให้อยู่ในลักษณะคอลัมน์เท่านั้น


จากโค้ดโปรแกรม In [6]
img.reshape((28,28)) จึงเป็นคำสั่งในการเปลี่ยนแปลงรูปทรงของอะเรย์จาก 2 มิติ ไปเป็น 1 มิติ

ขั้นตอนถัดไป คือการเริ่มต้นการแยกแยะจัดกลุ่มข้อมูล
โดยในกรณีนี้เราจะใช้การแยกแยะแบบเชิงเส้น (linear classifier)
ซึ่งมีพารามิเตอร์จำนวน 2 พารามิเตอร์

classifier = learn.LinearClassifier(feature_columns = feature_columns, n_classes = 10)
ในพารามิเตอร์แรก (สีเหลือง) เพื่อบอกให้คลาสสิฟายเออร์ทราบเกี่ยวกับ ฟีทเจอร์ที่ใช้เป็นเงื่อนไขในการแยกแยะ ส่วนพารามิเตอร์ที่สอง (สีแดง) หมายถึงจำนวนของคลาสหรือกลุ่มที่เรามี ในที่นี้เป็น 10 หมายถึง ตัวเลข 10 แบบนั่นเอง

หากเราลองเป็นผู้ทำหน้าที่แยกแยะ ด้วยการเพิ่มหลักฐานหรือตัวอย่างที่เป็นรูปภาพให้กับตัวเลขแต่ละตัว
ด้านบนหมายถึงอินพุทโหนด หรือส่วนนำเข้าข้อมูล แทนด้วย Xes และส่วนเอ้าท์พุทโหนด หรือส่วนแสดงผลลัพท์ อยู่ด้านล่างแทนด้วย Ys
เรามีหนึ่งอินพุทโหนดสำหรับแต่ละฟีทเจอร์ หรือพิกเซลในรูปภาพ และหนึ่งเอ้าพุทโหนดสำหรับเลขแต่ละตัว ที่รูปภาพต้องนำเสนอ
ดังนั้นเมื่อนเรามี 784 อินพุท และ 10 เอ้าท์พุท
เราสามาถรถแสดงแผนภาพเพื่ออธิบายได้ดังนี้

แต่ละเส้น จะมีค่าน้ำหนัก (Each edge has a weight)

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


และแน่นอน พิกเซลเหล่านั้นจะถูกคุณด้วยค่าน้ำหนักของเส้นแต่ละเส้น และเอ้าพุทโหนดจะทำหน้าที่รวบรวมผลการคูณของแต่ละพิกเซล หรือเรียกว่าการรวบรวมหลักฐานเพื่อบอกให้ได้ว่า รูปภาพนั้นเป็นตัวเลขอะไร
ยิ่งหลักฐานมีเป็นจำนวนมาก เช่น เหมือนกับเลขแปดเป็นจำนวนมาก ก็จะทำนายว่ารูปภาพนั้นเป็นเลขแปด
evidence yi=jWi, j xj  
และเพื่อการคำนวณจำนวนหลักฐานที่เรามี เราจะทำการรวมค่าทั้งหมดของ ค่าความเข้าของพิกเซล แล้วคุณด้วยค่าน้ำหนัก
ด้วยวิธีนี้ทำให้เราสามารถทำนายรูปภาพแต่ละรูปได้โดยแสดงผลลัพท์ทางเอ้าท์พุทโหนด จากหลักฐานที่มี

การปรับแต่งค่าน้ำหนัก ด้วยความลาดเอียง (gradient descent)
  • เริ่มต้นด้วยการสุ่มค่าน้ำหนัก
  • จากนั้นค่อยๆ ปรับแต่งจนได้ค่าที่ดีที่สุด
จากที่ได้อธิบายวิธีการแยกแยะจัดกลุ่มตัวเลข จะเห็นว่าส่วนที่สำคัญที่สุดคือ ค่าน้ำหนัก และการกำหนดค่าน้ำหนักได้อย่างเหมาะสม ส่งผลต่อความแม่นยำถูกต้องในการแยกแยะข้อมูล
เราจะเริ่มต้นการปรับแต่งค่าน้ำหนักด้วยการสุ่มค่าน้ำหนักขึ้นมาก่อน จากนั้น ค่อยๆ ปรับแต่งค่าน้ำหนักนั้นให้ได้ค่าที่ดีที่สุด ซึ่งทั้งหมดนี้เป็นหน้าที่ของเมทธอด fit

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


ด้วยการใช้เมทธอดในการประเมินผล จะเห็นได้ว่าความสามารถในการแยกแยะจัดกลุ่มข้อมูลของโมเดลที่เราพัฒนาขึ้นด้วยการสอน เมื่อทดลองกับข้อมูลทดสอบแล้ว ได้ผลลัพท์เป็น 0.9141 หรือความถูกต้องแม่นยำที่ 91.41% ซึ่งหากเราตั้งเป้าหมายไว้ที่ 90% หมายความว่าโมเดลนี้สามารถใช้งานได้เนื่องจากความสามารถในการทำนายสูงกว่าที่ได้ตั้งเป้าหมายไว้ แต่หากเราตั้งเป้าหมายไว้ 95% โมเดลนี้อาจยังไม่สามารถนำไปใช้งานได้ต้องทำการปรับแต่งให้ได้ความถูกต้องแม่นยำในการทำนายมากกว่านี้ หรือเกินกว่า 95% นั่นเอง
ตัวอย่าง ของการแยกแยะ
ตัวอย่างของการแยกแยะที่ถูกต้อง

และตัวอย่างของการแยกแยะที่ผิดพลาด


ในลำดับถัดไปจะแสดงให้เห็นถึงภาพของค่าน้ำหนักที่คลาสสิฟายเออร์ได้เรียนรู้


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

เลขหนึ่งอาจถูกเขียนด้วยมุมเอียงที่แตกต่างกัน แต่หากสังเกตุให้ดีจะพบว่า พิกเซลที่อยู่ตรงกลาง
จะมีลักษณะเหมือนกันในทุกรูป

ดังนั้นพิกเซลที่อยู่บริเวณตรงกลางจะมีค่าน้ำหนักมาก
เมื่อภาพที่เรากำลังพิจารณา มีหลักฐานว่า พิกเซลบริเวณกึ่งกลางมีลักษณะเช่นนี้ ก็จะมีค่าน้ำหนักมากว่าเป็นรูปภาพของเลขหนึ่ง

เมื่อเราลองมาพิจาณารูปภาพของเลขศูนย์ดูบ้าง
พบว่า ตรงกึ่งกลางรูปนั้นไม่มีพิกเซลอยู่
แม้ว่าจะมีวิธีการเขียนเลขศูนย์ที่หลากหลาย แต่หากตรงกึ่งกลางของรูปภาพ มีลักษณะเช่นนี้ ก็เป็นหลักฐานยืนยันว่ารูปภาพดังกล่าวควรเป็นเลขศูนย์ ดังนั้นบริเวณกึ่งกลางของรูปภาพ จึงมีค่าน้ำหนักเป็นลบ

การแสดงผลภาพค่าน้ำหนัก
จากภาพแสดงผลค่าน้ำหนัก เราสามารถมองเห็นขอบของตัวเลขจากค่าน้ำหนักได้ด้วยสีแดง
ดังนั้นเราก็จะสามารถเห็นภาพตัวเลขได้ เนื่องจากเราเริ่มต้นด้วย พิกเซลจำนวน 784 พิกเซล และเรียนรู้ด้วยค่าน้ำหนักเป็น 10 ในแต่ละตัวเลข
เราจึงสามารถเปลี่ยนรูปร่างของค่าน้ำหนักกลับไปสู่อะแรย์ 2 มิติได้
ขอบคุณสำหรับการเรียนรู้ในครั้งนี้ แน่นอนเรายังมีเนื้อหาอื่นๆ ที่เกี่ยวข้องอีก สามารถศึกษาเพิ่มเติมได้จากส่วน ลิงค์อ้างอิง

ในการเรียนรู้เรื่องถัดไป
  • การทำดีพเลิร์นนิ่งด้วย TF.Learn
  • เพิ่มเติมความรู้เรื่อง การแยกแยะจัดกลุ่มเชิงเส้น (Linear Classifiers)
  • ทำการทดลองดีพเลิร์นนิ่ง ที่ได้เกริ่นนำในบทเรียนนี้


อ้างอิง
Jupyter Notebook: https://goo.gl/NNlMNu
Docker images: https://goo.gl/8fmqVW
MNIST tutorial: https://goo.gl/GQ3t7n
Visualizing MNIST: http://goo.gl/ROcwpR (this blog is outstanding)
More notebooks: https://goo.gl/GgLIh7
More about linear classifiers: https://goo.gl/u2f2NE
Much more about linear classifiers: http://goo.gl/au1PdG (this course is outstanding, highly recommended)
More TF.Learn examples: https://goo.gl/szki63

โดย ผศ. ณัฏฐ์ โอธนาทรัพย์
สาขาวิชาวิศวกรรมคอมพิวเตอร์ คณะวิศวกรรมศาสตร์ มหาวิทยาลัยเอเชียอาคเนย์
By Asst., Prof. Nuth OTANASAP
Department of Computer Engineering, Faculty of Engineering,

Southeast Asia University, Bangkok 10160 THA

7) การแบ่งกลุ่มลายมือตัวอักษรด้วย TF.Learn การเรียนรู้ของคอมพิวเตอร์ แมชชีนเลิร์นนิ่ง ตอนที่ 7

7) การแบ่งกลุ่มลายมือตัวอักษรด้วย TF.Learn

การเรียนรู้ของคอมพิวเตอร์ แมชชีนเลิร์นนิ่ง ตอนที่ 7



ในบทเรียนที่แล้ว เราได้ทำการแยกแยะรูปภาพ ด้วยเทนเซอร์โฟลว สำหรับศิลปิน กันไปแล้ว และในบทเรียนนี้เราจะมาเรียนรู้วิธีการเขียนโค้ดโปรแกรมด้วย TF.Learn กัน
ปัญหาเริ่มแรกที่จะกล่าวถึงในบทเรียนนี้ก็คือ การแยกแยะตัวอักษรแต่ละตัวที่เขียนโดยมนุษย์ จาก เซ็ตข้อมูล MNIST และเขียนคลาสสิฟายเออร์แบบง่ายๆ เหมือนเราเริ่มเขียนโค้ดโปรแกรมสวัสดีชาวโลกสำหรับคอมพิวเตอร์วิชั่น (การมองเห็นของคอมพิวเตอร์) ด้วยปัจจุบัน MINIST เป็นปัญหาการจัดกลุ่มหรือแยกแยะแบบคลาสผสมหรือ มัลติคลาส สมมติให้รูปภาพของตัวเลขแต่ละตัว คืองานที่เราต้องการทำการจัดกลุ่มแยกแยะ หรือทำนายว่าตัวเลขนั้นคือตัวเลขอะไร เราจะเริ่มต้นด้วยการเขียนโปรแกรม ด้วย IPython notebook (Jupyter Notebook) ในบทเรียนนี้ ตัวอย่างโค้ดโปรแกรม และเพื่อให้ง่ายต่อการเริ่มต้น ด้วยการกำหนดสภาพแวดล้อมการทำงาน เราจะมาดูวิธีการติดตั้ง โดยสังเขปกันก่อน
เท็นเซอร์โฟลวใช้ดอกเกอร์ (Docker) ซึ่งเป็นเรื่องแรกที่เราต้องเรียนรู้
เราจะเริ่มต้นด้วยวิธีการดาวน์โหลด เซ็ตข้อมูล (Dataset) และแสดงผลภาพ จากนั้นจะทำการสอนคลาสสิฟายเออร์และประเมินผลว่าคลาสสิฟายเออร์ของเรามีความแม่นยำเพียงไร เพื่อใช้ในการทำนายรูปภาพใหม่ๆ ที่คอมพิวเตอร์ยังไม่เคยพบเห็นมาก่อน และสุดท้ายจะแสดงให้เห็นถึงน้ำหนักของการเรียนรู้ของคลาสสิฟายเออร์หรือเครื่องมือแยกแยะข้อมูลของเราว่ามีความฉลาดมากน้อยเพียงไร ภายใต้กรอบที่กำหนด
  1. ติดตั้ง (Installation)
  2. ดาวน์โหลดเซ็ตข้อมูล (Download dataset)
  3. แสดงผลภาพ (Visualize images)
  4. สอนคลาสสิฟายเออร์เพื่อทำการแยกแยะข้อมูล (Train a classifier)
  5. ประเมินผลความแม่นยำของคลาสสิฟายเออร์ (Evaluate)
  6. แสดงให้เห็นถึงความฉลาดในการทำนาย (Visualize weights)

1. ติดตั้ง (Installation) เริ่มต้นด้วยการติดตั้งเท็นเซอร์โฟลว (Installing TensorFlow) สำหรับการติดตั้งบน Installing TensorFlow on Windows ให้ทำตามขั้นตอนที่กำหนด เมื่อติดตั้งเรียบร้อยแล้ว
ติดตั้ง Docker สำหรับวินโดว์ เวอร์ชั่น และสำหรับเวอร์ชั่นอื่น

หลังจากติดตั้งและลงทะเบียน Docker เรียบร้อยแล้วให้ติดตั้ง Docker Toolbox สำหรับเวอร์ชั่นวินโดวส์ 10 คลิก

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


หลังจากโปรแกรมทำงานจะพบหน้าเทอร์มินอล มีรูปวาฬ ดังตัวอย่าง พร้อมปรากฏ IP Address 192.160.99.100 อยู่บรรทัดถัดมาจากวาฬ ทั้งนี้ IP Address อาจแตกต่างกันไปตามแต่ละบริบทของคอมพิวเตอร์แต่ละเครื่อง ให้ทำการสำเนาไว้เพื่อใช้งานในภายหลัง
ขั้นตอนถัดไปให้ทำการเปิด Docker container ด้วย TensorFlow image ซึ่ง image ถูกวางไว้ที่ Docker hub

$ docker run -it -p 8888:8888 tensorflow/tensorflow






จากรูปที่กำหนดให้จะเห็นได้ว่า เป็นเรื่องยากที่คอมพิวเตอร์จะตีความและเข้าใจ
เนื่องจากภาพนี้มีความละเอียดต่ำ เพียง 28 * 28 พิกเซลในระบบสีขาวดำเทา
นอกจากนี้ยังถูกแบ่งออกเป็นส่วนๆ เท่าๆ กัน
นั่นหมายความว่ารูปแต่ละรูปคือตัวเลขจำนวนหนึ่งตัว

ไม่ต้องการทำวิศวกรรมฟีทเจอร์ (No feature engineering)
  • ใช้เพียงข้อมูลดิบในรูปแบบพิกเซลเท่านั้น
  • คลาสสิฟายเออร์ทำหน้าที่แยกแยะจัดกลุ่ม
หากมาพิจารณาฟีทเจอร์ที่นำมาใช้ในการแยกแยะจัดกลุ่มข้อมูลแล้ว
เมื่อเราต้องการทำแมชชีนเลิร์นนิ่งกับรูปภาพ เราจะใช้ข้อมูลดิบในรูปแบบพิกเซล เป็นฟีทเจอร์
เนื่องจากเป็นฟีทเจอร์ที่สามารถถูกแยกแยะได้ดีในกรณีของรูปภาพ ในขณะที่ถ้าเป็นฟีทเจอร์ของพื้นผิว และรูปทรง จะแยกแยะได้ยาก

ดังนั้น รูปภาพที่มีขนาด 28 * 28 พิกเซลนั้น จะมีจำนวนพิกเซลรวมถึง 784 พิกเซล นั้นหมายความว่าเราจะมีฟีทเจอร์เพื่อใช้เป็นเงื่อนไขในการแยกแยะจัดกลุ่มถึง 784 ฟีทเจอร์
นอกจากนี้ ในกรณีเราใช้รูปภาพที่มีการนำเสนอแบบแบนราบ
นั่นหมายความว่าเราต้องทำการแปลงรูปภาพในระบบอะเรย์ 2 มิติ ให้อยู่ในรูปแบบอะเรย์ 1 มิติ โดยไม่ให้อยู่ในแนวนอน แต่ให้อยู่ในลักษณะคอลัมน์เท่านั้น


จากโค้ดโปรแกรม In [6]
img.reshape((28,28)) จึงเป็นคำสั่งในการเปลี่ยนแปลงรูปทรงของอะเรย์จาก 2 มิติ ไปเป็น 1 มิติ

ขั้นตอนถัดไป คือการเริ่มต้นการแยกแยะจัดกลุ่มข้อมูล
โดยในกรณีนี้เราจะใช้การแยกแยะแบบเชิงเส้น (linear classifier)
ซึ่งมีพารามิเตอร์จำนวน 2 พารามิเตอร์

classifier = learn.LinearClassifier(feature_columns = feature_columns, n_classes = 10)
ในพารามิเตอร์แรก (สีเหลือง) เพื่อบอกให้คลาสสิฟายเออร์ทราบเกี่ยวกับ ฟีทเจอร์ที่ใช้เป็นเงื่อนไขในการแยกแยะ ส่วนพารามิเตอร์ที่สอง (สีแดง) หมายถึงจำนวนของคลาสหรือกลุ่มที่เรามี ในที่นี้เป็น 10 หมายถึง ตัวเลข 10 แบบนั่นเอง

หากเราลองเป็นผู้ทำหน้าที่แยกแยะ ด้วยการเพิ่มหลักฐานหรือตัวอย่างที่เป็นรูปภาพให้กับตัวเลขแต่ละตัว
ด้านบนหมายถึงอินพุทโหนด หรือส่วนนำเข้าข้อมูล แทนด้วย Xes และส่วนเอ้าท์พุทโหนด หรือส่วนแสดงผลลัพท์ อยู่ด้านล่างแทนด้วย Ys
เรามีหนึ่งอินพุทโหนดสำหรับแต่ละฟีทเจอร์ หรือพิกเซลในรูปภาพ และหนึ่งเอ้าพุทโหนดสำหรับเลขแต่ละตัว ที่รูปภาพต้องนำเสนอ
ดังนั้นเมื่อนเรามี 784 อินพุท และ 10 เอ้าท์พุท
เราสามาถรถแสดงแผนภาพเพื่ออธิบายได้ดังนี้

แต่ละเส้น จะมีค่าน้ำหนัก (Each edge has a weight)

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

และแน่นอน พิกเซลเหล่านั้นจะถูกคุณด้วยค่าน้ำหนักของเส้นแต่ละเส้น และเอ้าพุทโหนดจะทำหน้าที่รวบรวมผลการคูณของแต่ละพิกเซล หรือเรียกว่าการรวบรวมหลักฐานเพื่อบอกให้ได้ว่า รูปภาพนั้นเป็นตัวเลขอะไร
ยิ่งหลักฐานมีเป็นจำนวนมาก เช่น เหมือนกับเลขแปดเป็นจำนวนมาก ก็จะทำนายว่ารูปภาพนั้นเป็นเลขแปด
evidence yi=jWi, j xj  
และเพื่อการคำนวณจำนวนหลักฐานที่เรามี เราจะทำการรวมค่าทั้งหมดของ ค่าความเข้าของพิกเซล แล้วคุณด้วยค่าน้ำหนัก
ด้วยวิธีนี้ทำให้เราสามารถทำนายรูปภาพแต่ละรูปได้โดยแสดงผลลัพท์ทางเอ้าท์พุทโหนด จากหลักฐานที่มี

การปรับแต่งค่าน้ำหนัก ด้วยความลาดเอียง (gradient descent)
  • เริ่มต้นด้วยการสุ่มค่าน้ำหนัก
  • จากนั้นค่อยๆ ปรับแต่งจนได้ค่าที่ดีที่สุด
จากที่ได้อธิบายวิธีการแยกแยะจัดกลุ่มตัวเลข จะเห็นว่าส่วนที่สำคัญที่สุดคือ ค่าน้ำหนัก และการกำหนดค่าน้ำหนักได้อย่างเหมาะสม ส่งผลต่อความแม่นยำถูกต้องในการแยกแยะข้อมูล
เราจะเริ่มต้นการปรับแต่งค่าน้ำหนักด้วยการสุ่มค่าน้ำหนักขึ้นมาก่อน จากนั้น ค่อยๆ ปรับแต่งค่าน้ำหนักนั้นให้ได้ค่าที่ดีที่สุด ซึ่งทั้งหมดนี้เป็นหน้าที่ของเมทธอด fit

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


ด้วยการใช้เมทธอดในการประเมินผล จะเห็นได้ว่าความสามารถในการแยกแยะจัดกลุ่มข้อมูลของโมเดลที่เราพัฒนาขึ้นด้วยการสอน เมื่อทดลองกับข้อมูลทดสอบแล้ว ได้ผลลัพท์เป็น 0.9141 หรือความถูกต้องแม่นยำที่ 91.41% ซึ่งหากเราตั้งเป้าหมายไว้ที่ 90% หมายความว่าโมเดลนี้สามารถใช้งานได้เนื่องจากความสามารถในการทำนายสูงกว่าที่ได้ตั้งเป้าหมายไว้ แต่หากเราตั้งเป้าหมายไว้ 95% โมเดลนี้อาจยังไม่สามารถนำไปใช้งานได้ต้องทำการปรับแต่งให้ได้ความถูกต้องแม่นยำในการทำนายมากกว่านี้ หรือเกินกว่า 95% นั่นเอง
ตัวอย่าง ของการแยกแยะ
ตัวอย่างของการแยกแยะที่ถูกต้อง

และตัวอย่างของการแยกแยะที่ผิดพลาด


ในลำดับถัดไปจะแสดงให้เห็นถึงภาพของค่าน้ำหนักที่คลาสสิฟายเออร์ได้เรียนรู้


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

เลขหนึ่งอาจถูกเขียนด้วยมุมเอียงที่แตกต่างกัน แต่หากสังเกตุให้ดีจะพบว่า พิกเซลที่อยู่ตรงกลาง
จะมีลักษณะเหมือนกันในทุกรูป

ดังนั้นพิกเซลที่อยู่บริเวณตรงกลางจะมีค่าน้ำหนักมาก
เมื่อภาพที่เรากำลังพิจารณา มีหลักฐานว่า พิกเซลบริเวณกึ่งกลางมีลักษณะเช่นนี้ ก็จะมีค่าน้ำหนักมากว่าเป็นรูปภาพของเลขหนึ่ง

เมื่อเราลองมาพิจาณารูปภาพของเลขศูนย์ดูบ้าง
พบว่า ตรงกึ่งกลางรูปนั้นไม่มีพิกเซลอยู่
แม้ว่าจะมีวิธีการเขียนเลขศูนย์ที่หลากหลาย แต่หากตรงกึ่งกลางของรูปภาพ มีลักษณะเช่นนี้ ก็เป็นหลักฐานยืนยันว่ารูปภาพดังกล่าวควรเป็นเลขศูนย์ ดังนั้นบริเวณกึ่งกลางของรูปภาพ จึงมีค่าน้ำหนักเป็นลบ

การแสดงผลภาพค่าน้ำหนัก
จากภาพแสดงผลค่าน้ำหนัก เราสามารถมองเห็นขอบของตัวเลขจากค่าน้ำหนักได้ด้วยสีแดง
ดังนั้นเราก็จะสามารถเห็นภาพตัวเลขได้ เนื่องจากเราเริ่มต้นด้วย พิกเซลจำนวน 784 พิกเซล และเรียนรู้ด้วยค่าน้ำหนักเป็น 10 ในแต่ละตัวเลข
เราจึงสามารถเปลี่ยนรูปร่างของค่าน้ำหนักกลับไปสู่อะแรย์ 2 มิติได้
ขอบคุณสำหรับการเรียนรู้ในครั้งนี้ แน่นอนเรายังมีเนื้อหาอื่นๆ ที่เกี่ยวข้องอีก สามารถศึกษาเพิ่มเติมได้จากส่วน ลิงค์อ้างอิง

ในการเรียนรู้เรื่องถัดไป
  • การทำดีพเลิร์นนิ่งด้วย TF.Learn
  • เพิ่มเติมความรู้เรื่อง การแยกแยะจัดกลุ่มเชิงเส้น (Linear Classifiers)
  • ทำการทดลองดีพเลิร์นนิ่ง ที่ได้เกริ่นนำในบทเรียนนี้


อ้างอิง
Jupyter Notebook: https://goo.gl/NNlMNu
Docker images: https://goo.gl/8fmqVW
MNIST tutorial: https://goo.gl/GQ3t7n
Visualizing MNIST: http://goo.gl/ROcwpR (this blog is outstanding)
More notebooks: https://goo.gl/GgLIh7
More about linear classifiers: https://goo.gl/u2f2NE
Much more about linear classifiers: http://goo.gl/au1PdG (this course is outstanding, highly recommended)
More TF.Learn examples: https://goo.gl/szki63



โดย ผศ. ณัฏฐ์ โอธนาทรัพย์
สาขาวิชาวิศวกรรมคอมพิวเตอร์ คณะวิศวกรรมศาสตร์ มหาวิทยาลัยเอเชียอาคเนย์
By Asst., Prof. Nuth OTANASAP
Department of Computer Engineering, Faculty of Engineering,
Southeast Asia University, Bangkok 10160 THA