- เป็นการทดลองที่ดันความแม่นยำของการจำแนกตัวเลขลายมือ MNIST ไปได้ถึงประมาณ 78% โดยใช้เพียง การบีบอัด GZIP และ k-nearest neighbors (k-NN) แสดงให้เห็นว่าสามารถใช้การบีบอัดเป็นเครื่องมือจำแนกแบบไร้โมเดลได้
- คำนวณ Normalized Compression Distance (NCD) จากการดูว่าความยาวเปลี่ยนไปมากแค่ไหนเมื่อบีบอัดตัวอย่างภาพสองภาพรวมกัน แล้วใช้ค่านี้เป็นตัวชี้วัดความคล้ายคลึงระหว่างภาพ
- แต่ละตัวอย่างทดสอบจะถูกเปรียบเทียบกับตัวอย่างฝึก 100 ตัวอย่าง และใช้เสียงข้างมากของ เพื่อนบ้าน k=5 ที่ใกล้ที่สุดเป็นค่าทำนาย
- เนื่องจากต้นทุนการคำนวณ จึงวัดความแม่นยำจาก เพียงบางส่วนของภาพทดสอบ ไม่ใช่ทั้งชุด และหากใช้ทั้งชุด การประเมินอาจแม่นยำยิ่งขึ้น
- ตัวอย่างสาธารณะที่เผยแพร่ยังมี ข้อผิดพลาดจากการรีแฟกเตอร์ ที่สร้างแคชความยาวที่บีบอัดแล้วแต่ไม่ได้นำไปใช้ในการคำนวณ NCD จริง จึงควรลบแคชออกหรือสะท้อนให้
compute_ncdใช้งานแคชดังกล่าว
จำแนก MNIST ด้วย GZIP + k-NN
- การทดลองนี้จำแนกชุดข้อมูลตัวเลขลายมือ MNIST ด้วยการผสาน GZIP + k-NN
- ตัวอย่างโค้ดสั้นใช้ความยาวของผลลัพธ์จาก
gzip.compress(z.tobytes())เป็นความยาวหลังการบีบอัด จากนั้นคำนวณ NCD แล้วเลือกค่าป้ายกำกับที่พบบ่อยที่สุดจากเพื่อนบ้านที่ใกล้ที่สุด 5 ตัว - ตัวอย่างที่รันได้มีอยู่ใน Jupyter Notebook
- เป้าหมายไม่ใช่การทำความแม่นยำสูงสุด แต่เป็นการตรวจสอบไอเดียอย่างง่ายว่า การบีบอัดสามารถนำมาใช้เป็น เครื่องมือจำแนกแบบไร้โมเดล ได้
- โค้ดไม่ถึง 10 บรรทัดไม่ใช่แก่นสำคัญของการทดลองนัก แต่ใกล้เคียงกับองค์ประกอบแบบ code golf เพื่อความสนุกมากกว่า
การคำนวณความคล้ายคลึงและขั้นตอนการจำแนก
- NCD วัด ความคล้ายคลึง โดยทำการนอร์มัลไลซ์ว่าต้นทุนในการบีบอัดจุดข้อมูลสองจุดร่วมกันแตกต่างจากการบีบอัดแยกกันมากเพียงใด
- ความยาวที่บีบอัดคำนวณได้ในรูปแบบต่อไปนี้
Cx1 = len(gzip.compress(x1.tobytes()))Cx2 = len(gzip.compress(x2.tobytes()))Cx1x2 = len(gzip.compress((x1 + x2).tobytes()))
- สูตร NCD มีรูปแบบเป็น
(Cx1x2 - min(Cx1, Cx2)) / max(Cx1, Cx2) - การจำแนกจะคำนวณระยะห่างระหว่างภาพทดสอบแต่ละภาพกับภาพฝึก จัดเรียงจากใกล้ไปไกล แล้วใช้การโหวตเสียงข้างมากของ 5 ตัวที่ใกล้ที่สุด
- ในการทดลองนี้ใช้ตัวอย่างฝึก 100 ตัวอย่างเป็นฐานในการเปรียบเทียบ และเนื่องจากต้นทุนการคำนวณ ชุดทดสอบก็ใช้เพียงบางส่วนเช่นกัน
แนวคิดอ้างอิงและข้อควรระวังในโค้ด
- แนวทางนี้ได้แรงบันดาลใจจากบทความ text generation from data compression และงานวิจัย parameter free text classification
- หลังจากเขียนบทความแล้ว ผู้เขียนยังพบโพสต์ MNIST by ZIP ของ Andreas Kirsch จากปี 2019 ซึ่งใช้แนวทางคล้ายกัน
- โค้ดตัวอย่างสร้าง แคชความยาวหลังการบีบอัด ของตัวอย่างฝึกไว้ แต่ในลูปจริงกลับไม่ได้ใช้ค่าแคชดังกล่าว
- ทั้งเวอร์ชันปกติและเวอร์ชันที่ทำให้อ่านยากต่างก็สร้าง
compressed_lengthsหรือclsแต่ไม่ได้นำความยาวที่แคชไว้มาคำนวณ NCD - หากลบแคชออกแล้วใช้
training_setโดยตรง หรือปรับให้compute_ncdใช้ค่าแคช ก็จะทำให้เจตนาของโค้ดสอดคล้องกับการติดตั้งใช้งานจริง
- ทั้งเวอร์ชันปกติและเวอร์ชันที่ทำให้อ่านยากต่างก็สร้าง
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ลองเปลี่ยนฟังก์ชันระยะทางในโค้ดเป็นมาตรวัดที่เรียบง่ายกว่าแล้วพบว่า ในการจำแนก MNIST ระยะทาง GZIP มีความแม่นยำต่ำกว่าและใช้การคำนวณมากกว่ามาก
ระยะทาง Gzip: ประมาณ 3 นาที, ความแม่นยำ 78% / ระยะทาง Euclidean: ประมาณ 0.5 วินาที, 93% / ระยะทาง Jaccard: ประมาณ 0.7 วินาที, 94% / Dice dissimilarity: ประมาณ 0.8 วินาที, 94%
Jaccard และ Dice วัดหลังจากทำให้ภาพเป็นไบนารีแล้ว
ผมไม่คุ้นกับอัลกอริทึม GZIP นัก แต่ก็น่าสนใจที่ผลออกมาต่ำขนาดนี้ และสงสัยว่าถ้าใช้อัลกอริทึมบีบอัดที่เน้นภาพเป็นหลักจะดีกว่านี้ไหม
ตัวบทความเองสร้างสรรค์ และโค้ดกับคำอธิบายก็ดี แต่ผมคิดว่า baseline ข้างต้นช่วยเพิ่มบริบทให้คะแนนของ gzip
NMI skimage: ประมาณ 30 วินาที, ความแม่นยำ 95% / NMI numba: ประมาณ 0.6 วินาที, ความแม่นยำ 95%
ใช้โค้ด
numbaที่ ChatGPT ให้มาเพื่อคำนวณ 2x2 joint count, entropy และ normalized mutual informationส่วนตัวสนใจการเทรน CIFAR10 แบบเร็ว ๆ เลยคิดว่าแนวทางแบบนี้อาจมีประโยชน์พอสมควรในโดเมนอื่นด้วย
https://github.com/benjamin-recht/mnist_1_pt_2/tree/main
ลองใส่ zstandard ด้วย พบว่า Zstd(level=3) ได้ความแม่นยำ 88% ในประมาณ 3.5 วินาที เร็วกว่า gzip มาก
ตอนคำนวณ
Cx1x2ถ้าใช้(x1-x2)*2แทนx1+x2zstd จะขึ้นไปถึงความแม่นยำ 93%ถ้าไม่บวกสองอาร์เรย์ แต่เอามาซ้อนกันบนล่าง ประสิทธิภาพจะพังหมดเหลือต่ำกว่า 20% แต่น่าสนใจที่วิธีนั้นดูเหมือนจะใช้ได้ดีในการจำแนกสตริง
ถ้าเทียบกับเทคนิคอื่น Linear SVC ได้ 92%, SVC เคอร์เนล RBF ได้ 96.4%, SVC เคอร์เนลพหุนามได้ 94.5%, logistic regression ได้ 89%, naive Bayes ได้ราว 81%
ที่มา: https://dmkothari.github.io/Machine-Learning-Projects/SVM_wi...
ดูจากบทความออนไลน์แล้ว แค่ใช้ K-NN อย่างเดียว ก็น่าจะได้ผลดีกว่ามาก จนเหมือนผู้เขียนทำให้เรื่องยากขึ้นด้วยการใช้ gzip
ผมชอบเริ่มจากโมเดลง่าย ๆ แล้วค่อยเพิ่มความซับซ้อนทีหลัง แต่ก็มักได้ยินคนพูดว่า “logistic regression ใช้ไม่ได้” แม้กับปัญหาที่จริง ๆ แล้วมันทำงานได้ดี
ถ้าถามว่าคิดว่า baseline performance บน MNIST น่าจะอยู่ประมาณไหน หลายคนมักเดาว่า 20~30%
แม้แต่คนที่ทำแมชชีนเลิร์นนิงก็มักประเมินต่ำไปว่า ผลตอบแทนที่ลดลง จะมาถึงเร็วแค่ไหนเมื่อเพิ่มความซับซ้อนของโมเดลมาก ๆ
จากประสบการณ์ ถ้าโมเดลง่าย ๆ ทำผลงานได้ไม่ดี ก็มักยากที่จะได้ผลงานยอดเยี่ยมจากโมเดลที่ซับซ้อนกว่า
แม้แต่งานวิจัยต้นฉบับที่แนะนำชุดข้อมูล MNIST ก็ทำความแม่นยำได้ราว 98% และโครงข่ายประสาทยุคนี้ไปถึงความแม่นยำ 99.87% แล้ว
https://paperswithcode.com/sota/image-classification-on-mnis...
การบีบอัดมีไว้เพื่อทำให้ปัญหาเดิมยากขึ้น และในความเป็นจริงมันก็ยังทำงานแบบนั้นอยู่
โมเดลอื่น ๆ มักมีแนวโน้มจะเติม noise ลงไปที่ใดที่หนึ่ง เลยสงสัยว่าถ้าใส่ feature engineering ก่อน gzip จะเป็นอย่างไร
เช่น อาจใช้ Gaussian blur และ convolution ก่อน แล้วค่อยใช้ deep learning สำหรับ feature selection
โค้ดอาจจะสวยและสั้น แต่ ความแม่นยำ 78% บน MNIST ถือว่าแย่มาก
แม้แต่โมเดล dummy ที่ทำด้วย TensorFlow ก็แตะความแม่นยำ 90% ได้ง่าย ๆ และโมเดลที่ดีที่สุดอยู่ที่ 99.87%
Benchmark: https://paperswithcode.com/sota/image-classification-on-mnis...
ส่วนที่น่าสนใจคือสามารถใช้ การบีบอัด เพื่อการจำแนกได้โดยไม่ต้องเทรนโมเดล
นั่นทำให้ถามต่อได้ว่า มาตรวัดเชิงทฤษฎีสารสนเทศแบบอื่นที่ถูกกว่าและมีการสูญเสียข้อมูล จะใช้ได้ไหม
To Compress or Not to Compress- Self-Supervised Learning and Information Theory: A Review
[https://arxiv.org/abs/2304.09355\)" class="ud link">https://arxiv.org/abs/2304.09355\](https://arxiv.org/abs/2304.09355\)*
สิ่งที่น่าสนใจไม่ใช่ว่า GZip จะไปถึงประสิทธิภาพระดับ state-of-the-art หรือไม่ แต่คือ ข้อเท็จจริงที่ว่ามันจำแนกได้พอใช้
คล้ายกับสิ่งที่น่าทึ่งไม่ใช่ว่าหมีเล่น Mozart ได้สมบูรณ์แบบหรือไม่ แต่คือมันเล่นเปียโนได้เลยต่างหาก
ถึงอย่างนั้นก็ยังดีกว่า baseline ถึง 8 เท่า และแสดงให้เห็นว่า การบีบอัดสามารถ เรียนรู้ representation ได้
หากเปลี่ยน
compute_ncdเป็นระยะทางแบบยูคลิด ความแม่นยำในการทดสอบจะ เพิ่มขึ้น 15 จุดเปอร์เซ็นต์ และปริมาณการคำนวณก็ลดลงมากด้วยแค่เปลี่ยนเป็นแบบ
distances = [(np.sqrt(np.sum(np.square(x1-x))), label) for x, _, label in compressed_lengths]ก็พอหนังสือที่พูดถึงความเชื่อมโยงเชิงลึกระหว่างทฤษฎีสารสนเทศ การบีบอัด และอัลกอริทึมการเรียนรู้ เล่มที่ดีที่สุดสำหรับผมคือ MacKay
สำหรับคนที่ได้รับการศึกษามาอย่างเป็นระบบ เรื่องนี้อาจเป็นความรู้ทั่วไป แต่ในฐานะคนที่เรียนแมชชีนเลิร์นนิงสายปฏิบัติด้วยตัวเอง พอเห็นว่าหัวข้อนี้เชื่อมโยงไปถึงสาขาอย่างฟิสิกส์อนุภาคและจักรวาลวิทยา ก็รู้สึกเหมือนมีช่วงเวลา “อ๋อ!” ที่แรงมาก
ฝากไว้ด้วยความหวังว่าจะมีแม้สักคนได้พบความเข้าใจแบบเดียวกัน
ตอนรู้ว่า การบีบอัด Lempel-Ziv ดั้งเดิม ซึ่งเป็นหนึ่งในรากฐานของ gzip ไม่ได้มาจากความพยายามแค่จะลดขนาดเท่านั้น แต่เกิดจากการศึกษา “ความซับซ้อนของลำดับจำกัด” นี่ค่อนข้างน่าประทับใจ
https://ieeexplore.ieee.org/document/1055501
ถ้าพูดอย่างเป็นธรรม แค่เอา MNIST ผ่าน UMAP ก็แยกได้เกือบสมบูรณ์แล้ว
ทุกวันนี้ถ้าจะทำผลงานบน MNIST ให้แย่คงต้องพยายามพอสมควร
https://github.com/lmcinnes/umap_paper_notebooks/blob/master...
ตอนนี้น่าจะถึงเวลาปลดระวางชุดข้อมูลนี้แล้ว และผมคิดว่าชุดข้อมูลอย่าง QuickDraw มีเหตุผลกว่ามาก
มันคงไม่ใช่ความสำเร็จใหญ่โตในตัวเอง แต่การได้เห็นว่ามันทำงานได้ก็ยังน่าสนใจ
กลับถึงบ้านแล้วจะเพิ่มในบทความว่า การแก้ MNIST นั้นค่อนข้างง่าย
ถึงอย่างนั้น อัลกอริทึมที่เรียบง่ายและสมเหตุสมผลส่วนใหญ่ก็ไปถึงความแม่นยำ 97% ได้ จึงยังมีคุณค่าในฐานะเครื่องมือการสอนหรือ ชุดข้อมูล Hello world
ต่อให้สร้างเครื่องมือเองตั้งแต่ต้นก็ยังอยู่ในขนาดงานการบ้าน และเป็นโจทย์ที่มีประโยชน์ซึ่งใคร ๆ ก็เข้าใจได้ อย่าง “การรู้จำตัวเลขบนไปรษณีย์”
ถ้าเข้าใจการบีบอัด แนวทางนี้ก็เป็นไอเดียที่เรียบง่ายมาก จนสามารถเขียนได้ตั้งแต่วันแรกที่ MNIST เปิดเผย และก็น่าจะยังได้ความแม่นยำ 78%
ตรงนี้แหละที่รู้สึกค่อนข้างน่าทึ่ง
รีโพซิทอรีก็ไม่ได้นิยาม UMAP ไว้ แต่ถ้าเชื่อ ChatGPT แล้ว UMAP ย่อมาจาก Uniform Manifold Approximation and Projection เป็น เทคนิคการลดมิติและการทำภาพประกอบข้อมูล ที่ใช้ในแมชชีนเลิร์นนิงและการวิเคราะห์ข้อมูล
ผมรู้เรื่องสายนี้แค่ระดับงานอดิเรก แต่ข้อมูลที่ถูกบีบอัดอย่างหนักน่าจะมี เอนโทรปีสูง เหมือนข้อมูลที่เข้ารหัสหรือเปล่า
ถ้าหาแพตเทิร์นในข้อมูลที่บีบอัดแล้วรู้ตัวเลขต้นฉบับได้ ก็น่าจะเอาแพตเทิร์นนั้นไปใช้กับการบีบอัดที่ดีกว่าได้ไม่ใช่หรือ
แนวคิดคือ “7 7” ควรถูกบีบอัดได้ดีกว่า “7 3” และภาพแรสเตอร์ของ “7 7” ก็น่าจะถูกบีบอัดได้ดีกว่า “7 3” เช่นกัน
ความบีบอัดไม่ได้เป็นคุณลักษณะของการดำเนินการเข้ารหัสที่มีประสิทธิภาพ
ดูส่วนการบีบอัดในเอกสาร Kolmogorov complexity: https://en.wikipedia.org/wiki/Kolmogorov_complexity#Compress...
แนวคิดหนึ่งในเรื่องการบีบอัดที่ผมชอบคือ หลักช่องนกพิราบ ซึ่งบอกว่าในอัลกอริทึมการบีบอัดทุกแบบ จะต้องมีเอาต์พุตบางตัวที่ใหญ่กว่าอินพุตเสมอ
เพย์โหลดเข้ารหัสที่ออกแบบมาดีก็ลองบีบอัดได้ แต่โดยเฉลี่ยเอาต์พุตจะใหญ่กว่าอินพุต ทำให้การบีบอัดไม่มีประโยชน์ เราจึงเรียกว่า “บีบอัดไม่ได้”
https://en.wikipedia.org/wiki/Pigeonhole_principle#Uses_and_...
เหมือนเคยมีกรณีเมื่อหลายปีก่อนที่ใช้ ขนาด ของภาพ MNIST เป็น “เมตาฟีเจอร์” แต่ตอนนี้หาไม่เจอทันที
เท่าที่จำได้ แค่ฟีเจอร์เดียวนี้โดยไม่ต้องดูภาพเลยก็ได้ความแม่นยำคร่าว ๆ แถว 90%
หมายถึงขนาดที่บีบอัดด้วย gzip หรือเปล่า? ถ้าดูแค่ว่าภาพ MNIST มืดแค่ไหน หรือก็คือสัดส่วนพิกเซลสีเข้ม จะได้ความแม่นยำประมาณ 20% ซึ่งดีกว่าการเดาสุ่มสองเท่า แต่ยังห่างไกลจาก 90% มาก
ผมคิดว่าผู้เขียนเปเปอร์นั้นอาจทำพลาดจนผลลัพธ์พุ่งขึ้นไปอยู่แถวบนของเบนช์มาร์ก
หลังเหตุการณ์นั้นผมมองว่าทฤษฎีไม่ค่อยสอดคล้องกัน แต่ถึงอย่างไร ความแม่นยำ 78% ด้วย GZIP อย่างเดียวก็น่าประทับใจ
ไม่ว่าปัญหานี้จะเหมาะกับทริกการบีบอัดหรือไม่ คนที่ทดลองอยู่ควรเลิกใช้
gzipแล้วใช้zlibดีกว่าถ้าเปลี่ยนบรรทัดแรกจาก
gzip.compressเป็นzlib.compressจะได้ประสิทธิภาพการจำแนกเหมือนเดิม แต่เร็วขึ้น 3 เท่า