ก่อนงาน BugDay Bangkok 2009

กำลังจะไปงานนี้ครับ ถ้าไม่ติดอะไร

ลองดูกำหนดการของงานครับ น่าสนใจมาก ใครที่สนใจงานทางด้าน Software Engineering โดยเฉพาะ Testing ก็น่าจะมางานนี้นะครับ

การจัดการปัญหา Memory Leak ใน OpenCV (C/C++)

ความรู้ใหม่ได้มาจากเว็บของ AI Shack ผมนำบางส่วนมาแปลเป็นไทยมาลงไว้กันลืม และเผื่อจะเป็นประโยชน์ต่อหลายๆ คนครับ โดยงานผมจะเกี่ยวข้องการกับวิเคราะห์รูปภาพดังนั้นส่วนที่เอามาคือ เฉพาะส่วน Memory leak ของการประกาศตัวแปร IplImage

ถ้าโค้ดของเรามีดังนี้

IplImage* img = cvCreateImage( ... );  // ประกาศตัวแปร img และได้จองหน่วยความจำไว้
img = xfunction( ... );  // ส่งค่า IplImage* กลับ
…
cvReleaseImage( &img );  // ลบหน่วยความจำตัวใหม่ที่เกิดจาก xfunction

แบบนี้แสดงว่าเกิด Memory leak ที่ xfunction ครับ คือตอนแรกเราจองหน่วยความจำให้กับตัวแปร img และต่อมาได้เรียกฟังก์ชั่น xfunction ซึ่งฟังก์ชั่นนี้ จะจองหน่วยความจำไว้อีกที่หนึ่งสำหรับค่าที่จะส่งกลับ ทำให้ตัวแปร img ไปชี้ที่หน่วยความจำใหม่ และหน่วยความจำเก่าที่ได้จองไว้ตอนแรกยังคงอยู่ (ถ้าใช้ภาษา Java คิดว่าไม่น่าจะมีปัญหาตรงนี้ครับ)

วิธีแก้ก็ง่ายมากครับ แค่แทนที่จะใช้ cvCreateImage() เราก็เปลี่ยนให้ชี้ไปที่ NULL แทน ดังนี้ครับ

IplImage* img = NULL;
img = xfunction( ... );
…
cvReleaseImage( &img );

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

อ่านรายละเอียดทั้งหมดได้ที่: OpenCV Memory Management in C/C++

การวัดประสิทธิภาพของโมเดล (Two-class prediction)

การที่เราสร้างโมเดลๆ หนึ่งขึ้นมาทำนายผลนั้น เราจะต้องมีการวัดประสิทธิภาพของโมเดลนั้นด้วย เรื่องการวัดผลนี้ค่อนข้างสำคัญมาก ในงานวิจัยที่เราจะต้องนำเสนอสิ่งที่เราคิดค้นออกมาว่าดีแค่ไหน ในบล็อกนี้จะขอพูดถึงการวัดผลโดยใช้ปัญหาที่เรียกว่า two-class prediction (binary classification) ซึ่งเป็นการวัดประสิทธิภาพที่งานวิจัยส่วนใหญ่นิยมใช้กัน

ในปัญหานี้เราจะบอกว่าผลลัพธ์ที่ได้ว่าเป็นคลาส Positive หรือ Negative ซึ่งผลลัพธ์ที่ได้สามารถมีได้ 4 แบบ คือ

  1. True Positive (TP) หมายความว่า เราได้ผลลัพธ์จากการทำนายคือ p และค่าจริงๆ ก็คือ p ด้วย
  2. False Positive (FP) หมายความว่า เราได้ผลลัพธ์จากการทำนายคือ p แต่ว่าค่าจริงๆ แล้วคือ n
  3. True Negative (TN) หมายความว่า เราได้ผลลัพธ์จากการทำนายคือ n และค่าจริงๆ ก็คือ n ด้วย
  4. False Negative (FN) หมายความว่า เราได้ผลลัพธ์จากการทำนายคือ n แต่ว่าค่าจริงๆ แล้วคือ p

จะเห็นได้ว่า TN จะกลับกันกับ TP และ FN จะกลับกันกับ FP ตามลำดับ

หลายๆ คนจะค่อนข้างสับสนเวลาที่คำนวณค่าจริงๆ ก็จะอธิบายจากความเข้าใจของผมนะครับ และคิดว่าน่าจะเข้าใจง่ายที่สุดแล้ว (เครดิต: @b39ppr) ยกตัวอย่าง เช่น เวลาที่เราต้องการจะทำนายว่า พฤติกรรมของคนๆ นี้ผิดปกติหรือไม่? หรืออีกนัยหนึ่งคือ เราต้องการที่จะตรวจจับพฤติกรรมที่ผิดปกติของคนๆ หนึ่ง

ในที่นี้จะได้ว่า พฤติกรรมที่ผิดปกติคือคลาส Positive ส่วนพฤติกรรมปกติคือคลาส Negative จะได้ว่า

  • TP คือ ระบบเราตรวจจับได้ว่าคนๆ นี้ผิดปกติ และ คนๆ นี้ได้มีพฤติกรรมผิดปกติจริงๆ
  • FP คือ ระบบเราตรวจจับได้ว่าคนๆ นี้ผิดปกติ แต่ว่า จริงๆ แล้ว เค้าไม่ได้ทำอะไรผิดเลย
  • TN คือ ระบบเราไม่ได้ตรวจจับอะไรเลย และ คนๆ นี้ก็ไม่ได้ทำผิด
  • FN คือ ระบบเราไม่ได้ตรวจจับอะไรเลย แต่ว่า คนๆ นี้ จริงๆ แล้วเค้ามีพฤติกรรมที่ผิดปกติ!

พอนึกออกรึเปล่าครับ? ผมจะขอยกตัวอย่างอีกสักตัวอย่าง เช่น เราเขียนโมเดลระบบตรวจจับสแปมเมล ถ้าเจอสแปมเมลให้ลบทิ้งเลย (ระบบออกแนวโหดหน่อย)

ในที่นี้จะได้ว่า เมลที่เป็นสแปมคือคลาส Positive ส่วนเมลปกติคือคลาส Negative

  • TP คือ ระบบทำนายว่าเมลนี้เป็นสแปม และ มันก็เป็นสแปมจริงๆ
  • FP คือ ระบบทำนายว่าเมลนี้เป็นสแปม แต่ว่า จริงๆ แล้วเมลนี้เป็นเมลปกติ เช่น ข่าวสารทั่วไป เมลเกี่ยวกับงานต่างๆ
  • TN คือ ระบบทำนายว่าเมลนี้เป็นเมลปกติ และ เมลนี้ก็ปกติจริงๆ
  • FN คือ ระบบทำนายว่าเมลนี้เป็นเมลปกติ แต่ว่า จริงๆ แล้วมันเป็นสแปม!

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

มีสรุปเพิ่มเติมจากคุณ pat หรือคุณ @b39ppr นั่นเอง ดังนี้ครับ (มีคำถามให้คิดเล่นตอนท้าย)

การอ่าน (T,F)(P,N) แบบไม่งง

  • ดูตัวหลังก่อน ว่า P หรือ N
    ถ้า P คือ model ของเรา predict ว่ามันเป็น positive (เป็นคนร้าย, เป็น spam)
  • ต่อไปดูตัวหน้า ว่า T หรือ F
    ถ้า T คือ ที่ model ของเรา predict ไปนั้น ถูกต้องแล้ว ถ้า F คือ predict ผิด

ตัวอย่าง: ระบบตรวจหา spam mail

  1. ตรวจหาอะไรก็ให้สิ่งนั้นเป็น positive
    จะตรวจหา spam เมื่อคิดว่าเจอ spam ก็คือเจอกรณี positive
  2. จะคำนวณ FP ทำอย่างไร?
    ตอบ สำหรับ FP นั้น
    2.1 ตัวหลังเป็น P ให้นับจำนวน mail ที่เรา predict ว่าเป็น “positive” (เป็น spam)
    2.2 ตัวหน้าเป็น F ให้ดูว่าที่ predict ว่าเป็น spam ไปนั้น มีอันไหน “ผิด” บ้าง

เอ้า ลองคิดกันหน่อย:
มี email ใหม่ ส่งมาหาเราทั้งหมด 10 ฉบับ เข้ามาใน inbox 8 ส่วนอีก 2 เข้าไปอยู่ในกล่อง junk mail 8 mail ใน inbox นั้นมาจากคนรู้จักซะ 5 ที่เหลือเป็นเมล์ขายของ ไม่อยากได้ ส่วนในกล่อง junk mail ดันมีเมล์สำคัญจากเพื่อนอยู่ 1 ฉบับ ลองบอกค่า TP, FP, TN, FN ของระบบกรอง spam ตัวนี้มาหน่อย

หวังว่าจะมีประโยชน์นะครับ 🙂

ข้อมูลเพิ่มเติม: Receiver Operating Characteristic (ROC)

สูตรเงินออมอย่างง่าย

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

รายรับ - รายจ่าย = เงินออม

สูตรนี้ก็ตรงไปตรงมาใช่ไหมครับ? แต่ว่าสูตรนี้น่าจะเหมาะสำหรับคนที่มีความพอเพียงอย่างมาก มีรายจ่ายน้อยจริงๆ แต่จะไม่ค่อยเหมาะสำหรับคนส่วนใหญ่ (รวมไปถึงผมด้วย) สักเท่าไหร่ ซึ่งเราจะคิดกันว่าเราสามารถจ่ายเท่าไหร่ก็ได้ แค่ไม่ให้รายจ่ายมากกว่ารายรับแค่นั้น ทำให้ทุกๆ ช่วงสิ้นเดือนเราจะไม่ค่อยมีเงินเหลือกันสักเท่าไหร่ เป็นกันไหมครับ? ดังที่ @lecuppiecake เคยกล่าวไว้ว่า "สิ้นเดือนเมื่อไหร่ แม้แต่แกลบยังแพง" ตัวผมเองไม่เหมาะกับสูตรนี้อย่างแรง 🙁

แล้วสูตรไหนเหมาะ? ก็แค่ย้ายข้างสมการ จะได้อีกสูตรดังนี้

รายรับ - เงินออม = รายจ่าย

ดูแล้วผลลัพธ์เท่ากันใช่ไหมครับ? ถ้าตอบในเชิงคณิตศาสตร์ก็ใช่ครับ แต่ว่าในชีวิตจริงคำตอบคงต่างออกไป สมการข้างต้นนี้จะมีความหมายว่า พอเราได้รายรับ (เงินเดือน หรืออะไรก็ตาม) มาเมื่อไหร่ ให้หักเก็บไว้เป็นเงินออมทันที ประมาณ 10-20% ของรายรับ (แล้วแต่คนนะครับ เลขนี้ไม่ตายตัว) การทำเช่นนี้ให้ผลดีตามมาก็คือ

  1. เราสามารถคิดได้ว่า มีเท่าไหร่ก็ใช้เท่านั้น (คิดเหมือนตอนที่เราใช้สูตรแรก) โดยไม่ต้องกังวลว่าเรามีเงินออมหรือเปล่า (นั่นก็เพราะ เราได้หักส่วนของเงินออมออกไปแล้ว)
  2. เงินออมของเราจะเพิ่มขึ้นอย่างสม่ำเสมอ เราสามารถนำเงินจำนวนนี้ไปทำงานแทนเราได้ เช่น ฝากธนาคารเอาดอกเบี้ย หรือ ลงทุน
  3. ลดค่าใช้จ่ายที่ไม่จำเป็นออก โดยที่เราไม่รู้ตัว

จริงๆ แล้วยังมีข้อดีอีกมากมายครับ สำหรับการใช้สูตรที่ 2 นี้

เราสามารถเริ่มต้นการออมเมื่อไหร่ก็ได้ครับ แค่ "ออมก่อน มีสิทธิรวยกว่า" เท่านั้นเอง 😛

Mount USB drive on Ubuntu 9.10 (Karmic Koala)

I write the solution for a problem that USB drive cannot be mounted automatically on Ubuntu 9.10.

Firstly, install gnome-mount.

sudo apt-get install gnome-mount

Secondly, go to System > Preferences > Startup Applications. And add this command.

gnome-mount -p xxx (change xxx to the volume label)

Finally, log out the system and it should work then. However, the problem still occurs after unmount and unplug the USB drive. To fix it, log out the system and then plug in the USB drive again. It is not a very good solution by the way. 🙁

Also, find the bug report here.