ฝึกสอน Python อย่างสมบูรณ์เพื่อสร้างระบบ AI การเรียนรู้ภายใต้การดูแลสำหรับการแบ่งส่วนเชิงความหมายของข้อมูลพอยต์คลาวด์ 3D LiDAR ที่ไม่มีโครงสร้าง

การมีทักษะและความรู้ในการโจมตีทุกแง่มุมของการประมวลผลพอยต์คลาวด์ช่วยเปิดประตูสู่แนวคิดและการพัฒนามากมาย 🤖 มันเป็นเหมือนกล่องเครื่องมือสำหรับความคิดสร้างสรรค์ในการวิจัย 3 มิติ และความคล่องตัวในการพัฒนา และที่แกนกลาง มีพื้นที่ปัญญาประดิษฐ์อันน่าทึ่งซึ่งมุ่งเป้าไปที่การทำความเข้าใจฉาก 3 มิติ 🏡

มีความเกี่ยวข้องอย่างยิ่งเนื่องจากมีความสำคัญสำหรับการใช้งานหลายอย่าง เช่น รถยนต์ที่ขับเคลื่อนด้วยตนเอง หุ่นยนต์อัตโนมัติ การทำแผนที่ 3 มิติ ความเป็นจริงเสมือน และ Metaverse และถ้าคุณเป็นคนที่คลั่งไคล้ระบบอัตโนมัติเหมือนฉัน มันยากที่จะต้านทานสิ่งล่อใจที่จะมีเส้นทางใหม่เพื่อรับมือกับความท้าทายเหล่านี้!

บทช่วยสอนนี้มีจุดมุ่งหมายเพื่อให้คุณได้รับสิ่งที่ฉันคิดว่าเป็นพื้นฐานสำคัญในการทำเช่นนั้น: ความรู้และทักษะการเขียนโค้ดสำหรับการพัฒนาระบบการแบ่งส่วนความหมายบนคลาวด์แบบ 3D Point

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

ผมขอนำเสนอหลักสูตรเชิงปฏิบัติ 201 ที่ชัดเจนและเจาะลึกซึ่งเน้นไปที่การเรียนรู้ของเครื่อง 3 มิติ ในบทช่วยสอนนี้ ฉันจะอธิบายอย่างเจาะจงว่า 3D Machine Learning คืออะไร และวิธีที่เราสามารถใช้ประโยชน์จากโค้ด Python ที่มีประสิทธิภาพเพื่อสร้างการคาดการณ์เชิงความหมายสำหรับพอยต์คลาวด์ 3D ที่ไม่มีโครงสร้าง

Table of Contents
3D Scene Perception
✔️ 3D Sensors
✔️ 3D Scene Understanding
✔️ Classification
Semantics Addition Methods for 3D data
✔️ 3D Object Detection
✔️ 3D Semantic Segmentation
✔️ 3D Instance Segmentation
3D Predictions with Supervised learning
3D Python Workflow
✔️ Step 1: Definition and Data Curation
✔️ Step 2. Environment Set-up
✔️ Step 3. 3D Feature Engineering
✔️ Step 4. 3D Machine Learning
✔️ Step 5. Performance Analysis
Conclusion

ให้เราดำดิ่งลงไป! 🤿

การรับรู้ฉาก 3 มิติ: คำนำ AI

การจดจำวัตถุ 3 มิติใน LiDAR (ซึ่งย่อมาจาก Light Detection and Ranging) ถือเป็นความท้าทายอย่างมาก เนื่องจากลักษณะที่ซับซ้อนของข้อมูลที่จับภาพ 3 มิติ คลาวด์พอยต์ดิบที่ได้รับจากเทคนิคการสแกน 3 มิตินั้นไม่มีโครงสร้าง ไม่มีการปรับแต่ง ไม่มีลำดับ และมีแนวโน้มที่จะสุ่มตัวอย่างไม่สม่ำเสมอ ทำให้งานการทำความเข้าใจฉาก 3 มิติมีความท้าทาย แล้วเราควรทำอย่างไร? เป็นไปได้ไหม? ฮ่าๆ นั่นคือสิ่งที่เราชอบ! ความท้าทายที่แท้จริง!😉

👀 เซ็นเซอร์ 3 มิติ

ให้เราเริ่มต้นด้วยการป้อนข้อมูลเข้าสู่ระบบของเรา เซ็นเซอร์ 3 มิติ (LiDAR, Photogrammetry, SAR, RADAR และกล้องตรวจจับความลึก) จะอธิบายฉากผ่านจุด 3 มิติจำนวนมากในอวกาศเป็นหลัก สิ่งเหล่านี้สามารถโฮสต์ข้อมูลที่เป็นประโยชน์และเปิดใช้งานระบบการเรียนรู้ของเครื่องที่ใช้อินพุตเหล่านี้ (เช่น รถยนต์และหุ่นยนต์อัตโนมัติ) เพื่อดำเนินการในโลกแห่งความเป็นจริงและสร้างประสบการณ์ Metaverse ที่ได้รับการปรับปรุง โอเค เรามีข้อมูลพื้นฐานจากข้อมูลทางประสาทสัมผัส แล้วจะทำอย่างไรต่อไป?

🏕️ ความเข้าใจเกี่ยวกับฉาก 3 มิติ

คุณเดาได้ว่า: ความเข้าใจฉาก โดยอธิบายกระบวนการที่รับรู้ วิเคราะห์ และอธิบายการตีความฉาก 3 มิติอย่างละเอียดที่สังเกตได้ผ่านเซ็นเซอร์เหล่านี้ตั้งแต่หนึ่งตัวขึ้นไป (ฉากนั้นอาจเป็นแบบไดนามิกก็ได้!) สรุปแล้ว ขั้นตอนนี้ประกอบด้วยการจับคู่ข้อมูลสัญญาณจากเซ็นเซอร์ที่สังเกตฉากกับ "แบบจำลอง" ที่เราใช้เพื่อทำความเข้าใจฉากเป็นหลัก ขึ้นอยู่กับความมหัศจรรย์ของความนุ่มนวล 🧙‍♂️ โมเดลจะอนุญาตให้มี "การทำความเข้าใจฉาก" ที่เกี่ยวข้อง ในมุมมองระดับต่ำ เทคนิคต่างๆ จะถูกแยกและเพิ่มความหมายจากข้อมูลอินพุตที่แสดงลักษณะของฉาก เทคนิคเหล่านี้มีชื่อหรือไม่?

🦘/🐈‍⬛ การจำแนกประเภท

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

วิธีการบวกความหมายแบบคลาสสิกสำหรับข้อมูล 3 มิติ

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

ให้ฉันอธิบายเพิ่มเติมอีกเล็กน้อยเกี่ยวกับเทคนิคแต่ละอย่าง

📦 การตรวจจับวัตถุ 3 มิติ

ส่วนแรกจะรวมเทคนิคการตรวจจับวัตถุ 3 มิติ เป็นองค์ประกอบสำคัญสำหรับการใช้งานจำนวนมาก โดยพื้นฐานแล้ว จะช่วยให้ระบบสามารถจับภาพขนาด ทิศทาง และตำแหน่งของวัตถุในโลกได้ ด้วยเหตุนี้ เราจึงสามารถใช้การตรวจจับ 3 มิติเหล่านี้ในสถานการณ์จริงได้ เช่น แอปพลิเคชัน Augmented Reality รถยนต์ไร้คนขับ หรือหุ่นยนต์ที่รับรู้โลกผ่านสัญญาณเชิงพื้นที่/ภาพที่จำกัด ลูกบาศก์ 3 มิติที่สวยงามที่มีวัตถุต่างกัน แต่หากเราต้องการปรับรูปทรงของวัตถุอย่างละเอียดล่ะ?

🏘️ การแบ่งส่วนความหมาย 3 มิติ

นี่คือจุดที่เราจะโจมตีปัญหาด้วยเทคนิค Semantic Segmentation นี่เป็นหนึ่งในงานที่ท้าทายที่สุดในการกำหนดป้ายกำกับความหมายให้กับทุกหน่วยฐาน (เช่น ทุกจุดใน point cloud) ที่เป็นของวัตถุที่สนใจ โดยพื้นฐานแล้ว การแบ่งส่วนความหมาย 3 มิติมีจุดมุ่งหมายเพื่อแยกแยะวัตถุที่อยู่ในฉากได้ดีขึ้น การตรวจจับกล่องขอบเขต 3 มิติบนสเตรอยด์หากคุณต้องการ ดังนั้นจึงหมายถึงการมีข้อมูลความหมายต่อจุด เราสามารถไปลึกที่นั่นได้ แต่ยังคงมีข้อจำกัดอยู่: เราไม่สามารถจัดการวัตถุที่แตกต่างกันตามหมวดหมู่ (คลาส) ที่เราโจมตีได้โดยตรง เรามีเทคนิคเรื่องนี้ด้วยหรือเปล่า?

🏠 การแบ่งส่วนอินสแตนซ์ 3 มิติ

ใช่! และเรียกว่าการแบ่งส่วนอินสแตนซ์ 3 มิติ มีการใช้งานที่กว้างขึ้น ตั้งแต่การรับรู้ 3 มิติในระบบอัตโนมัติไปจนถึงการสร้าง 3 มิติใหม่ในการทำแผนที่และการจับคู่ทางดิจิทัล ตัวอย่างเช่น เราอาจจินตนาการถึงหุ่นยนต์สินค้าคงคลังที่ระบุเก้าอี้ สามารถนับจำนวนเก้าอี้ได้ จากนั้นจึงเคลื่อนย้ายเก้าอี้โดยจับที่ขาที่สี่ การบรรลุเป้าหมายนี้จำเป็นต้องแยกแยะป้ายกำกับความหมายที่แตกต่างกัน รวมถึงอินสแตนซ์ที่แตกต่างกันด้วยป้ายกำกับความหมายเดียวกัน ฉันจะถือว่าการแบ่งส่วนอินสแตนซ์เป็นขั้นตอนการแบ่งส่วนความหมายบน Mega-Steroïds 😁

เมื่อคุณมีความเข้าใจพื้นฐานและอนุกรมวิธานของวิธีการปัจจุบันสำหรับผลลัพธ์ที่แตกต่างกันแล้ว คำถามก็ยังคงอยู่: เราควรปฏิบัติตามกลยุทธ์ใดเพื่อฉีดการทำนายเชิงความหมาย 🤔

การคาดการณ์ 3 มิติพร้อมการเรียนรู้แบบมีผู้สอน

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



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



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

แต่เราจะประเมินได้อย่างไรว่าโมเดลที่ผ่านการฝึกอบรมนั้นทำงานได้ดีเพียงใด การวิเคราะห์ด้วยภาพเพียงพอหรือไม่ (นี่เป็นคำถามจริงหรือเปล่า 🙃)

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

และตอนนี้ทฤษฎี (แสง) ก็จบลงแล้ว! ให้เราดำดิ่งลงสู่การใช้โค้ด Python อย่างสนุกสนานในห้าขั้นตอน🤲! ฉันแนะนำให้มีชามที่ยอดเยี่ยม 🫐

1. คำจำกัดความเวิร์กโฟลว์การเรียนรู้ของเครื่อง 3D

การจัดหาชุดข้อมูล Cloud LiDAR Point ทางอากาศ

คุณรู้อยู่แล้ว? ขั้นตอนแรกที่เราทำคือดำดิ่งสู่เว็บและแหล่งข้อมูล 3 มิติสนุกๆ! คราวนี้ ฉันอยากจะเจาะลึกภาษาฝรั่งเศส (ขออภัยที่เป็นคนเสแสร้ง 😆) เพื่อค้นหาชุดข้อมูล LiDAR แช่เย็น: สถาบันภูมิศาสตร์แห่งชาติ (IGN) ของฝรั่งเศส ด้วยแคมเปญ LiDAR HD ฝรั่งเศสเริ่มการรวบรวม OpenData ซึ่งคุณจะได้รับ point cloud 3 มิติที่คมชัดของบางภูมิภาคของฝรั่งเศส! และด้านบน บางรายการมีป้ายกำกับที่ทำให้ง่ายต่อการเริ่มต้นใหม่ ดังที่คุณจะพบในลิงก์ด้านล่าง



แต่เพื่อให้บทช่วยสอนตรงไปตรงมา ฉันไปที่พอร์ทัลด้านบน เลือกข้อมูลที่ครอบคลุมส่วนหนึ่งของเมือง Louhans (71) ลบข้อมูลการอ้างอิงทางภูมิศาสตร์ คำนวณคุณลักษณะพิเศษบางอย่าง (ซึ่งฉันจะอธิบายในบทช่วยสอนอื่น 😜) จากนั้น ทำให้สามารถใช้งานได้ใน Open Data Drive Folder ของฉัน ข้อมูลที่คุณสนใจคือ 3DML_urban_point_cloud.xyz และ 3DML_validation.xyz คุณสามารถข้ามไปที่ "สารสกัด Flyvast WebGL" ได้หากต้องการดูภาพออนไลน์

กลยุทธ์วงโดยรวม

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

🤓 หมายเหตุ: กลยุทธ์นี้คัดลอกมาจากเอกสารฉบับหนึ่งที่ให้ไว้ในหลักสูตรออนไลน์ที่ฉันจัดขึ้นที่ 3D Geodata Academy บทช่วยสอนนี้จะครอบคลุมขั้นตอนที่ 4 ถึง 8 + 10 + 11 ขั้นตอนอื่นๆ ที่ครอบคลุมในเชิงลึกในหลักสูตร หรือโดยการทำตามบทช่วยสอนอย่างใดอย่างหนึ่งผ่าน ลิงก์สนับสนุน นี้

2. การตั้งค่าบริบท 3D python ของเรา

ในบทช่วยสอน point cloud แบบลงมือปฏิบัติจริงนี้ ฉันมุ่งเน้นไปที่การใช้งานไลบรารีที่มีประสิทธิภาพและน้อยที่สุด เพื่อประโยชน์ของการเรียนรู้ Python เราจะทำทุกอย่างด้วยไลบรารีเพียงสองไลบรารีเท่านั้น: Pandas และ ScikitLearn แล้วเราจะทำสิ่งมหัศจรรย์ 😁. โค้ดห้าบรรทัดเพื่อเริ่มสคริปต์ของคุณ:

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import MinMaxScaler

🤓 หมายเหตุ: อย่างที่คุณเห็น ฉันนำเข้าฟังก์ชันและโมดูลจากไลบรารีในรูปแบบต่างๆ สำหรับแพนด้า ฉันใช้ import module ซึ่งต้องการการดูแลคำสั่ง import น้อยกว่า อย่างไรก็ตาม เมื่อคุณต้องการควบคุมมากขึ้นว่ารายการใดในโมดูลที่สามารถเข้าถึงได้ ฉันขอแนะนำให้ใช้ from module import foo ซึ่งจะทำให้พิมพ์น้อยลงเพื่อใช้ foo

ดี! จากนั้น ฉันขอเสนอให้เราแสดงเส้นทางของเราโดยแยก data_folder ที่มีชุดข้อมูลของเราออกจากชื่อ dataset เพื่อสลับได้อย่างง่ายดายทันที:

data_folder=”../DATA/”
dataset="3DML_urban_point_cloud.xyz"

ตอนนี้ เราสามารถโหลดชุดข้อมูลในตัวแปร pcd ได้อย่างรวดเร็วโดยใช้ Pandas และเนื่องจากไฟล์ต้นฉบับไม่สะอาดและมีค่า NaN เราจะใช้วิธี dropna inplace ที่มีประโยชน์มากเพื่อให้แน่ใจว่าเราเริ่มต้นด้วย dataframe ที่กรองแล้วโดยมีเพียงแถวที่สมบูรณ์เท่านั้น อย่างไรก็ตาม นี่หมายความว่าเราจะทำคะแนนลดลงระหว่างทาง (<1% ของบันทึก) แต่คราวนี้เราโอเคกับเรื่องนั้น

pcd=pd.read_csv(data_folder+dataset,delimiter=' ')
pcd.dropna(inplace=True)

🤓 หมายเหตุ: อาร์กิวเมนต์ inplace ที่ตั้งค่าเป็น True อนุญาตให้แทนที่วัตถุ python ได้โดยตรง แทนที่จะสร้างสำเนา dataframe

3. การเลือกและการเตรียมคุณสมบัติ (ขั้นตอนที่ 4)

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

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

เพื่อเริ่มต้นบนพื้นฐานที่มั่นคง เราจะจัดระเบียบคุณลักษณะของเราระหว่างป้ายกำกับต่างๆ เช่น สิ่งที่เราจะพยายามคาดการณ์ และคุณลักษณะต่างๆ เช่น สิ่งที่เราจะใช้ในการคาดการณ์ ด้วย Pandas เราสามารถทำได้ง่ายๆ โดยใช้โค้ดสองบรรทัด:

labels=pcd['Classification']
features=pcd[['X','Y','Z','R','G','B']]

โครงสร้างดาต้าเฟรมนี้ช่วยให้สามารถสลับไปใช้ชุดคุณสมบัติที่เกี่ยวข้องได้อย่างรวดเร็วโดยไม่ต้องใช้ดัชนีตัวเลข ดังนั้นอย่าลังเลที่จะกลับมาที่ขั้นตอนนี้และเปลี่ยนชุดเวกเตอร์ features

การเลือกคุณสมบัติ

การเลือกคุณสมบัติเป็นวิธีการลดตัวแปรอินพุตที่ป้อนให้กับโมเดลของคุณโดยใช้เฉพาะตัวแปรที่เกี่ยวข้องมากที่สุดและกำจัดสัญญาณรบกวนในข้อมูล เป็นกระบวนการในการเลือกคุณสมบัติที่เกี่ยวข้องกับโมเดล Machine Learning ของคุณ โดยพิจารณาจากประเภทของปัญหาที่คุณพยายามแก้ไข หากดำเนินการโดยอัตโนมัติ จะอยู่ภายใต้กระบวนการ AutoMLในการทำให้งานการนำการเรียนรู้ของเครื่องไปใช้กับปัญหาในโลกแห่งความเป็นจริงเป็นแบบอัตโนมัติ

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

เพื่อความเรียบง่าย เราจะปรับการเลือกเวกเตอร์คุณลักษณะปัจจุบันของเราด้วยตนเองผ่านทิศทางที่ได้รับการดูแล: เราจะทำการทดลองและปรับเปลี่ยนหากผลลัพธ์ไม่ดีพอ พร้อม? 🙂

การเตรียมคุณสมบัติ

เมื่อเวกเตอร์คุณสมบัติเริ่มต้นของเราพร้อมแล้ว เราก็สามารถเร่งประมวลผลได้เลย! 💨 หรือเราทำได้? ระวัง! ขึ้นอยู่กับ Machine Learning Model ที่เราใช้ เราอาจพบกับเรื่องเซอร์ไพรส์! จริงๆ แล้ว ให้เราใช้สถานการณ์ง่ายๆ

ลองจินตนาการว่าเวกเตอร์คุณลักษณะที่เราเลือกไว้มีดังต่อไปนี้:

features=pcd[['X','Y']]

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

ฉันหันไปใช้แนวคิดเรื่องการปรับขนาดคุณลักษณะและการทำให้เป็นมาตรฐาน มันเป็นส่วนสำคัญของขั้นตอนการประมวลผลข้อมูลล่วงหน้า แต่ฉันได้เห็นผู้เริ่มต้นหลายคนมองข้ามมัน (ไปสู่ความเสียหายต่อโมเดลการเรียนรู้ของเครื่อง) เราจะไม่ทำผิดพลาด! 💪

เนื่องจากเราอยู่ในบริบทที่มีพื้นที่หนาแน่น วิธีที่ดีในการหลีกเลี่ยงปัญหาลักษณะทั่วไปคือการลดสิ่งที่เราเรียกว่าการทำให้เป็นมาตรฐาน Min-Max สำหรับสิ่งนี้ เราจะใช้ฟังก์ชัน MinMaxScaler:

from sklearn.preprocessing import MinMaxScaler
features_scaled = MinMaxScaler().fit_transform(features)

💡 คำแนะนำ: MinMaxScaler() แปลงคุณลักษณะต่างๆ โดยการปรับขนาดและแปลแต่ละคุณลักษณะให้อยู่ในช่วงที่กำหนด เช่น ระหว่างศูนย์ถึงหนึ่ง หากข้อมูลของคุณมีการกระจายตามปกติ คุณสามารถใช้ StandardScaler ได้

การตั้งค่าการฝึกอบรมการเรียนรู้ของเครื่อง 3D

โอเค เรามีเวกเตอร์ labels และเวกเตอร์ features ที่เหมาะสม ตอนนี้เราต้องเตรียมการสำหรับระยะการฝึก ในการเริ่มต้น เราจะแบ่งเวกเตอร์ทั้งสอง — ในขณะที่ยังคงรักษาการจับคู่ดัชนีที่เหมาะสมระหว่างป้ายกำกับและฟีเจอร์ — เพื่อใช้ส่วนหนึ่งสำหรับการฝึกโมเดลการเรียนรู้ของเครื่อง และอีกส่วนหนึ่งสำหรับการดูประสิทธิภาพเท่านั้น เราใช้ 60% ของข้อมูลสำหรับการฝึกอบรม และ 40% สำหรับการดูประสิทธิภาพ ซึ่งทั้งสองอย่างนำมาจากการแจกแจงแบบเดียวกันโดยการสุ่ม มันถูกสร้างขึ้นโดยใช้ฟังก์ชัน train_test_split จาก scikitlearn:

X_train, X_test, y_train, y_test = train_test_split(features_scaled, labels, test_size=0.4)

🤓 หมายเหตุ: เราใช้รูปแบบการตั้งชื่อเมื่อต้องจัดการกับข้อมูลสำหรับงาน Machine Learning X หมายถึงคุณลักษณะ (หรือข้อมูล) ที่ป้อนให้กับโมเดล และ y หมายถึงป้ายกำกับ แต่ละอันจะถูกแบ่งออกเป็น _train หรือ _test ขึ้นอยู่กับขั้นสุดท้าย

จากนั้นเราสร้างวัตถุลักษณนามผ่าน:

rf_classifier = RandomForestClassifier()

🤓หมายเหตุ: ตัวแยกประเภทด้านบนคือตัวแยกประเภทฟอเรสต์สุ่ม ในประโยคเดียว ข้อมูลนี้เหมาะกับตัวแยกประเภทแผนผังการตัดสินใจหลายรายการในตัวอย่างย่อยต่างๆ ของคุณสมบัติ และใช้การหาค่าเฉลี่ยเพื่อปรับปรุงความแม่นยำในการทำนายและควบคุมการพอดีมากเกินไป สิ่งที่น่าสนใจ😁.

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

rf_classifier.fit(X_train, y_train)

และสุดท้ายก็ voila! เรามีโมเดลที่ผ่านการฝึกอบรมแล้ว! ใช่ มันง่ายมาก! ดังนั้นจึงเป็นเรื่องง่ายที่จะใช้ทางลัด 😉

สำหรับระยะการคาดการณ์ ไม่ว่าคุณจะมีป้ายกำกับหรือไม่ก็ตาม คุณต้องดำเนินการดังต่อไปนี้:

rf_predictions = rf_classifier.predict(X_test)

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

fig, axs = plt.subplots(1, 3, figsize=(20,5))
axs[0].scatter(X_test['X'], X_test['Y'], c =y_test, s=0.05)
axs[0].set_title('3D Point Cloud Ground Truth')
axs[1].scatter(X_test['X'], X_test['Y'], c = rf_predictions, s=0.05)
axs[1].set_title('3D Point Cloud Predictions')
axs[2].scatter(X_test['X'], X_test['Y'], c = y_test-rf_predictions, cmap = plt.cm.rainbow, s=0.5*(y_test-rf_predictions))
axs[2].set_title('Differences')

และหากคุณต้องการตรวจสอบหน่วยเมตริก เราสามารถพิมพ์รายงานการจำแนกประเภทพร้อมตัวเลขจำนวนมากได้โดยใช้ฟังก์ชัน classification_report ของ scikit-learn:

print(classification_report(y_test, rf_predictions))

แต่เราไม่ควรเข้าใจว่าแต่ละตัวชี้วัดหมายถึงอะไร? 🤔

4. การปรับแต่งการเรียนรู้ของเครื่อง 3D (ขั้นตอนที่ 5)

การแสดงและตัวชี้วัด

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

  • True Positive (TP): การสังเกตเป็นบวกและคาดว่าจะเป็นบวก
  • ผลลบลวง (FN): การสังเกตเป็นบวกแต่คาดการณ์เป็นลบ
  • True Negative (TN): การสังเกตเป็นลบและคาดว่าจะเป็นลบ
  • ผลบวกลวง (FP): การสังเกตเป็นลบแต่คาดการณ์ว่าเป็นบวก

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

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

การเลือกรุ่น

ถึงเวลาเลือกโมเดลการเรียนรู้ของเครื่อง 3 มิติที่เฉพาะเจาะจง สำหรับบทช่วยสอนนี้ ฉันจำกัดตัวเลือกไว้เพียงสามโมเดลการเรียนรู้ของเครื่อง: Random Forests, K-Nearest Neighbours และ Multi-Layer Perceptron ที่อยู่ในหมวดหมู่ Deep Learning หากต้องการใช้งาน ก่อนอื่นเราจะนำเข้าฟังก์ชันที่จำเป็นดังต่อไปนี้:

from sklearn.neighbors import RandomForestClassifier
rf_classifier = RandomForestClassifier()
from sklearn.neighbors import KNeighborsClassifier
knn_classifier = KNeighborsClassifier()
from sklearn.neural_network import MLPClassifier
mlp_classifier = MLPClassifier(solver='lbfgs', alpha=1e-5,hidden_layer_sizes=(15, 2), random_state=1)

จากนั้นคุณเพียงแค่ต้องแทนที่ XXXClassifier() ในบล็อกโค้ดต่อไปนี้ด้วยสแต็กอัลกอริทึมที่ต้องการ:

XXX_classifier = XXXClassifier()
XXX_classifier.fit(X_train, y_train)
XXX_predictions = XXXclassifier.predict(X_test)
print(classification_report(y_test, XXX_predictions, target_names=['ground','vegetation','buildings']))

🤓หมายเหตุ: เพื่อความง่าย ฉันส่งรายการคลาสต้นไม้ที่สอดคล้องกับพื้นดิน พืชพรรณ และสิ่งปลูกสร้างที่มีอยู่ในชุดข้อมูลของเราไปที่ classification_report

และตอนนี้ เข้าสู่ขั้นตอนการทดสอบโดยใช้ตัวแยกประเภทสามตัวด้านบนพร้อมพารามิเตอร์ต่อไปนี้:

Train / Test Data: 60%/40% 
Number of Point in the test set: 1 351 791 / 3 379 477 pts
Features selected: ['X','Y','Z','R','G','B'] - With Normalization

ป่าสุ่ม

เราเริ่มต้นด้วยป่าสุ่ม การเสกต้นไม้วิเศษบางประเภทผ่านอัลกอริธึมทั้งมวลที่รวมแผนผังการตัดสินใจหลายแบบเข้าด้วยกันเพื่อให้ผลลัพธ์สุดท้ายแก่เรา: ความแม่นยำโดยรวมที่ 98% โดยอิงตามการสนับสนุนที่ 1.3 million points มันถูกย่อยสลายเพิ่มเติมดังนี้:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.99 ║     1.00 ║       1.00 ║  690670 ║
║ vegetation ║         0.97 ║     0.98 ║       0.98 ║  428324 ║
║ buildings  ║         0.97 ║     0.94 ║       0.96 ║  232797 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

🤓หมายเหตุ: ไม่มีอะไรจะพูดมากที่นี่ แทนที่จะให้ผลลัพธ์ที่น่าประทับใจ จุดภาคพื้นดินได้รับการจำแนกเกือบสมบูรณ์แบบ: การเรียกคืน 1.00 หมายความว่าพบจุดทั้งหมดที่อยู่บนพื้น และความแม่นยำ 0.99 หมายความว่ายังมีการปรับปรุงเล็กน้อยเพื่อให้แน่ใจว่าไม่มีผลบวกลวง Auqlitqtivem ze เห็นว่าข้อผิดพลาดกระจายไปทุกที่ ซึ่งอาจเป็นปัญหาได้หากต้องแก้ไขด้วยตนเอง

K-NN

ตัวแยกประเภท K-Nearest Neighbours ใช้ความใกล้ชิดเพื่อคาดการณ์เกี่ยวกับการจัดกลุ่มจุดข้อมูลแต่ละจุด เราได้รับความแม่นยำทั่วโลก 91% โดยแบ่งย่อยเพิ่มเติมดังนี้:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.92 ║     0.90 ║       0.91 ║  690670 ║
║ vegetation ║         0.88 ║     0.91 ║       0.90 ║  428324 ║
║ buildings  ║         0.92 ║     0.92 ║       0.92 ║  232797 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

🤓 หมายเหตุ: ผลลัพธ์ที่ได้จะต่ำกว่า Random Forests ซึ่งคาดว่าจะเกิดขึ้นเนื่องจากเราอยู่ภายใต้สัญญาณรบกวนในพื้นที่มากกว่าในพื้นที่เวกเตอร์ในปัจจุบัน เรามีความสมดุลของความแม่นยำ/การเรียกคืนที่เป็นเนื้อเดียวกันในทุกคลาส ซึ่งเป็นสัญญาณที่ดีที่ว่าเราหลีกเลี่ยงปัญหาที่มากเกินไป อย่างน้อยก็ในการแจกแจงปัจจุบัน 😁.

การเรียนรู้เชิงลึก 3 มิติด้วย Perceptron หลายชั้น

Multi-Layer Perceptron (MLP) เป็นอัลกอริธึมโครงข่ายประสาทเทียมที่เรียนรู้ความสัมพันธ์ของข้อมูลเชิงเส้นและไม่เป็นเชิงเส้น MLP จำเป็นต้องมีการปรับแต่งไฮเปอร์พารามิเตอร์หลายตัว เช่น จำนวนเซลล์ประสาทที่ซ่อนอยู่ เลเยอร์ และการวนซ้ำ ทำให้ยากต่อการดึงประสิทธิภาพสูงออกจากกล่อง ตัวอย่างเช่น เมื่อตั้งค่าไฮเปอร์พารามิเตอร์ เรามีความแม่นยำโดยรวมที่ 64% แยกย่อยเพิ่มเติมดังนี้:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.63 ║     0.76 ║       0.69 ║  690670 ║
║ vegetation ║         0.69 ║     0.74 ║       0.71 ║  428324 ║
║ buildings  ║         0.50 ║     0.13 ║       0.20 ║  232797 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

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

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

5. ประสิทธิภาพการเรียนรู้ของเครื่อง 3D: สู่ลักษณะทั่วไป

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

ชุดข้อมูลการตรวจสอบ

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

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

ด้านล่างนี้คือหมายเหตุชี้แจงเพิ่มเติมบางส่วน:

  • ชุดข้อมูลทดสอบอาจมีบทบาทในการจัดเตรียมโมเดลในรูปแบบอื่นๆ เช่น การเลือกคุณลักษณะ
  • โมเดลสุดท้ายอาจเหมาะสมกับการรวมชุดข้อมูลการฝึกอบรมและการตรวจสอบความถูกต้อง แต่เราตัดสินใจว่าจะไม่ทำ

ข้อมูลการตรวจสอบที่เลือกมาจากเมืองมาโนสก์ (04) ซึ่งนำเสนอบริบทของเมืองที่แตกต่างกัน โดยมีภูมิประเทศที่แตกต่างกันและบริบทเมืองที่แตกต่างกันอย่างมาก ดังตัวอย่างด้านล่าง ด้วยวิธีนี้เราเพิ่มความท้าทายในการรับมือกับลักษณะทั่วไป 😆

คุณสามารถดาวน์โหลดชุดข้อมูล 3DML_validation.xyz ได้จาก "Open Data Drive Folder" ของฉัน หากยังไม่ได้ดำเนินการ ตามที่อธิบายไว้ด้านล่าง คุณยังจะพบป้ายกำกับสำหรับศึกษาหน่วยวัดและประโยชน์ที่อาจเกิดขึ้นจากการทำซ้ำต่างๆ ที่ฉันทำ

การปรับปรุงผลลัพธ์การวางนัยทั่วไป

เป้าหมายของเราคือการตรวจสอบผลลัพธ์ของชุดข้อมูลการตรวจสอบความถูกต้อง และดูว่าเราได้ข้ามความเป็นไปได้บางอย่างหรือไม่

ขั้นแรก เรานำเข้าข้อมูลการตรวจสอบความถูกต้องในสคริปต์ของเราด้วยโค้ดสามบรรทัดต่อไปนี้:

val_dataset="3DML_validation.xyz"
val_pcd=pd.read_csv(data_folder+dataset,delimiter=' ')
val_pcd.dropna(inplace=True)

จากนั้น เราเตรียมเวกเตอร์คุณลักษณะให้มีคุณสมบัติเหมือนกับเวกเตอร์ที่ใช้ในการฝึกโมเดล: ไม่น้อย ไม่มากไปกว่านี้ เรายังทำให้เวกเตอร์ฟีเจอร์ของเราเป็นมาตรฐานให้อยู่ในสภาพเดียวกับข้อมูลการฝึกของเรา

val_labels=val_pcd['Classification']
val_features=val_pcd[['X','Y','Z','R','G','B']]
val_features_scaled = MinMaxScaler().fit_transform(val_features)

จากนั้นเราจะใช้โมเดลที่ได้รับการฝึกอบรมแล้วกับข้อมูลการตรวจสอบ และเราจะพิมพ์ผลลัพธ์:

val_predictions = rf_classifier.predict(val_features_scaled)
print(classification_report(val_labels, val_predictions, target_names=['ground','vegetation','buildings']))

นั่นทำให้เรามีความแม่นยำขั้นสุดท้ายที่ 54% สำหรับ 3.1 million คะแนน (เทียบกับ 98% สำหรับข้อมูลการทดสอบที่มี 1.3 million คะแนน) ที่มีอยู่ในชุดข้อมูลการตรวจสอบความถูกต้อง มันถูกย่อยสลายดังนี้:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.65 ║     0.16 ║       0.25 ║ 1188768 ║
║ vegetation ║         0.59 ║     0.85 ║       0.70 ║ 1315231 ║
║ buildings  ║         0.43 ║     0.67 ║       0.53 ║  613317 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

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

features=pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']]
val_features=val_pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']]

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

features_scaled = MinMaxScaler().fit_transform(features)
X_train, X_test, y_train, y_test = train_test_split(features_scaled, labels, test_size=0.3)
rf_classifier = RandomForestClassifier(n_estimators = 10)
rf_classifier.fit(X_train, y_train)
rf_predictions = rf_classifier.predict(X_test)
print(classification_report(y_test, rf_predictions, target_names=['ground','vegetation','buildings']))
val_features_scaled = MinMaxScaler().fit_transform(val_features)
val_rf_predictions = rf_classifier.predict(val_features_scaled)
print(classification_report(val_labels, val_rf_predictions, target_names=['ground','vegetation','buildings']))

ให้เราศึกษาผลลัพธ์ ขณะนี้เรามีความแม่นยำ 97% ในข้อมูลการทดสอบ โดยแบ่งย่อยเพิ่มเติมดังนี้:

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.97 ║     0.98 ║       0.98 ║  518973 ║
║ vegetation ║         0.97 ║     0.98 ║       0.97 ║  319808 ║
║ buildings  ║         0.95 ║     0.91 ║       0.93 ║  175063 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

การเพิ่มฟีเจอร์ทำให้ประสิทธิภาพลดลงเล็กน้อยเมื่อเทียบกับการใช้เฉพาะชุดฐาน X, Y, Z, R, G, B ซึ่งแสดงว่าเราได้เพิ่มสัญญาณรบกวนบางอย่าง แต่มันก็คุ้มค่าเพื่อประโยชน์โดยรวม! ขณะนี้เรามีความแม่นยำทั่วโลกที่ 85% ในชุดการตรวจสอบ ดังนั้นเพิ่มขึ้น 31% จากการเลือกคุณสมบัติเท่านั้น! มันมีขนาดใหญ่มาก และอย่างที่คุณสังเกตเห็น อาคารเป็นส่วนสำคัญที่ส่งผลเสียต่อการแสดง โดยหลักๆ แล้วอธิบายได้จากข้อเท็จจริงที่ว่ามันแตกต่างจากชุดทดสอบอย่างมาก และชุดคุณลักษณะไม่สามารถเป็นตัวแทนได้อย่างแท้จริงในบริบทที่ไม่เกี่ยวข้องกัน

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.89 ║     0.81 ║       0.85 ║ 1188768 ║
║ vegetation ║         0.92 ║     0.92 ║       0.92 ║ 1315231 ║
║ buildings  ║         0.68 ║     0.80 ║       0.73 ║  613317 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

นี่เป็นสิ่งที่ดีมาก! ตอนนี้เรามีโมเดลที่มีประสิทธิภาพเหนือกว่าส่วนใหญ่ที่คุณสามารถหาได้ แม้กระทั่งการใช้สถาปัตยกรรมการเรียนรู้เชิงลึก!

สมมติว่าเราต้องการขยายขนาดให้มากกว่านี้ ในกรณีนั้น อาจเป็นเรื่องน่าสนใจที่จะแทรกข้อมูลบางส่วนจากการแจกแจงการตรวจสอบความถูกต้องเพื่อตรวจสอบว่านั่นคือสิ่งที่จำเป็นในแบบจำลองหรือไม่ โดยที่การตรวจสอบความถูกต้องของเราจะสูญเสียสัดส่วนและกลายเป็นส่วนหนึ่งของชุดการทดสอบ เราใช้ 10% ของชุดข้อมูลการตรวจสอบและ 60% ของชุดข้อมูลเริ่มต้นในการฝึก Random Forest Model จากนั้นเราใช้มันและตรวจสอบผลลัพธ์ของข้อมูลการทดสอบที่เหลืออีก 40% และข้อมูลการตรวจสอบความถูกต้อง 90%:

val_labels=val_pcd['Classification']
val_features=val_pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']]
val_features_sampled, val_features_test, val_labels_sampled, val_labels_test = train_test_split(val_features, val_labels, test_size=0.9)
val_features_scaled_sample = MinMaxScaler().fit_transform(val_features_test)
labels=pd.concat([pcd['Classification'],val_labels_sampled])
features=pd.concat([pcd[['Z','R','G','B','omnivariance_2','normal_cr_2','NumberOfReturns','planarity_2','omnivariance_1','verticality_1']],val_features_sampled])
features_scaled = MinMaxScaler().fit_transform(features)
X_train, X_test, y_train, y_test = train_test_split(features_scaled, labels, test_size=0.4)
rf_classifier = RandomForestClassifier(n_estimators = 10)
rf_classifier.fit(X_train, y_train)
rf_predictions = rf_classifier.predict(X_test)
print(classification_report(y_test, rf_predictions, target_names=['ground','vegetation','buildings']))
val_rf_predictions_90 = rf_classifier.predict(val_features_scaled_sample)
print(classification_report(val_labels_test, val_rf_predictions_90, target_names=['ground','vegetation','buildings']))

และด้วยความยินดีเป็นอย่างยิ่ง เราพบว่าหน่วยวัดของเราเพิ่มขึ้นอย่างน้อย 5% ในขณะที่สูญเสียเพียง 1% ในชุดทดสอบ ดังนั้น จึงมีเสียงรบกวนจากฟีเจอร์น้อยที่สุดดังที่แสดงด้านล่าง:

40% Test Predicitions - Accuracy = 0.96    1476484

╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.97 ║     0.98 ║       0.97 ║  737270 ║
║ vegetation ║         0.97 ║     0.97 ║       0.97 ║  481408 ║
║ buildings  ║         0.94 ║     0.90 ║       0.95 ║  257806 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝
90% Validation Predicitions - Accuracy = 0.90    2805585
╔════════════╦══════════════╦══════════╦════════════╦═════════╗
║  classes   ║    precision ║   recall ║   f1-score ║ support ║
╠════════════╬══════════════╬══════════╬════════════╬═════════╣
║ ground     ║         0.88 ║     0.92 ║       0.90 ║  237194 ║
║ vegetation ║         0.93 ║     0.94 ║       0.94 ║  263364 ║
║ buildings  ║         0.87 ║     0.79 ║       0.83 ║  122906 ║
╚════════════╩══════════════╩══════════╩════════════╩═════════╝

สิ่งที่น่าสนใจโดยทั่วไปคือการตรวจสอบผลลัพธ์สุดท้ายด้วยโมเดลที่แตกต่างกันและพารามิเตอร์เดียวกัน จากนั้นจึงเข้าสู่ขั้นตอนสุดท้ายของการปรับไฮเปอร์พารามิเตอร์ แต่นั่นเป็นอีกครั้ง😉 คุณไม่เหนื่อยเหรอ? ฉันคิดว่าพลังงานสมองของเราต้องการการเติมพลัง ให้เราทิ้งส่วนที่เหลือไว้อีกครั้งและจบโครงการ 😁

การส่งออกชุดข้อมูลที่มีป้ายกำกับ

ชื่อบอกไว้ทั้งหมด: ถึงเวลาส่งออกผลลัพธ์เพื่อใช้ในแอปพลิเคชันอื่น ให้เราส่งออกเป็นไฟล์ Ascii โดยมีบรรทัดต่อไปนี้:

val_pcd['predictions']=val_rf_predictions
result_folder="../DATA/RESULTS/"
val_pcd[['X','Y','Z','R','G','B','predictions']].to_csv(result_folder+dataset.split(".")[0]+"_result_final.xyz", index=None, sep=';')

การส่งออกโมเดลการเรียนรู้ของเครื่อง 3 มิติ

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

import pickle
pickle.dump(rf_classifier, open(result_folder+"urban_classifier.poux", 'wb'))

และเมื่อคุณต้องการนำโมเดลกลับมาใช้ใหม่:

model_name="urban_classifier.poux"
loaded_model = pickle.load(open(result_folder+model_name, 'rb'))
predictions = loaded_model.predict(data_to_predict)
print(classification_report(y_test, loaded_predictions, target_names=['ground','vegetation','buildings']))

คุณสามารถเข้าถึงรหัสที่สมบูรณ์ได้โดยตรงในเบราว์เซอร์ของคุณด้วย สมุดบันทึก Google Colab นี้

บทสรุป

นั่นเป็นการเดินทางที่บ้าคลั่ง! หลักสูตร 201 ที่สมบูรณ์พร้อมบทช่วยสอนแบบลงมือปฏิบัติจริงเกี่ยวกับ 3D Machine Learning! 😁 คุณได้เรียนรู้มากมาย โดยเฉพาะวิธีการนำเข้า point cloud พร้อมฟีเจอร์ต่างๆ เลือก ฝึกฝน และปรับแต่งโมเดลการเรียนรู้ของเครื่อง 3 มิติที่ได้รับการดูแล และส่งออกเพื่อตรวจจับคลาสกลางแจ้งที่มีภาพรวมที่ยอดเยี่ยมไปยังชุดข้อมูล Aerial Point Cloud ขนาดใหญ่! ขอแสดงความยินดีอย่างยิ่ง! แต่นี่เป็นเพียงส่วนหนึ่งของสมการสำหรับการเรียนรู้ของเครื่อง 3 มิติ เพื่อขยายผลลัพธ์เส้นทางการเรียนรู้ บทความในอนาคตจะเจาะลึกเข้าไปในการแบ่งส่วนความหมายและอินสแตนซ์ [2–4] แอนิเมชัน และการเรียนรู้เชิงลึก [1] เราจะพิจารณาการจัดการข้อมูลคลาวด์จุดใหญ่ตามที่กำหนดไว้ในบทความด้านล่าง



การมีส่วนร่วมของฉันมุ่งหมายที่จะบีบอัดข้อมูลที่สามารถดำเนินการได้ เพื่อให้คุณสามารถเริ่มต้นจากศูนย์เพื่อสร้างระบบอัตโนมัติ 3 มิติสำหรับโครงการของคุณ คุณสามารถเริ่มต้นได้ตั้งแต่วันนี้โดยเข้าเรียนหลักสูตรที่ Geodata Academy

อ้างอิง

1. ปูซ์, เอฟ. และเจ.-เจ ปอนเซียโน (2020). Ontology การเรียนรู้ด้วยตนเองสำหรับการแบ่งส่วนอินสแตนซ์ของ 3d Indoor Point Cloud ISPRS นานาชาติ โค้ง. ของโพธิ์ & เรม XLIII-B2, 309–316; https://doi.org/10.5194/isprs-archives-XLIII-B2–2020–309–2020

2. พูซ์ เอฟ. และบิลเลน ร. (2019) การแบ่งส่วนความหมายของคลาวด์แบบพอยต์ 3 มิติที่ใช้ Voxel: เรขาคณิตและความสัมพันธ์แบบไม่มีผู้ดูแลเทียบกับวิธีการเรียนรู้เชิงลึก วารสารภูมิสารสนเทศนานาชาติ ISPRS 8(5), 213; https://doi.org/10.3390/ijgi8050213

3. Poux, F., Neuville, R., Nys, G.-A., & Billen, R. (2018) การสร้างแบบจำลองความหมายแบบคลาวด์ 3 มิติ: กรอบงานบูรณาการสำหรับพื้นที่ภายในอาคารและเฟอร์นิเจอร์ การสำรวจระยะไกล, 10(9), 1412. https://doi.org/10.3390/rs10091412

4. Poux, F., Neuville, R., Van Wersch, L., Nys, G.-A., & Billen, R. (2017) เมฆจุด 3 มิติในโบราณคดี: ความก้าวหน้าในการได้มา การประมวลผล และบูรณาการความรู้ที่นำไปใช้กับวัตถุกึ่งระนาบ ธรณีศาสตร์, 7(4), 96. https://doi.org/10.3390/GEOSCIENCES7040096