PyTorch for Regression
PyTorch เป็น Framework สำหรับทำ Deep Learning Neural Network โมเดลซึ่งเหมาะสำหรับงานที่มีความซับซ้อนไปจนถึงงานด้าน Generative AI ที่ทันสมัย โดยปกติแล้วโมเดลจำพวก DNN นี้ต้องการชุดข้อมูลขนาดใหญ่ จำเป็นต้องมีข้อมูลจำนวนมากเพื่อใช้ในการเรียนรู้ ดังนั้นกับงาน Regression ที่งานไม่ได้มีความซับซ้อนมากนักและมีข้อมูลที่ไม่ได้เยอะมากพอจึงมักใช้ Machine Learning มาจัดการแทนเนื่องจากเทรนได้ไวกว่า ให้ผลลัพธ์ที่ค่อนข้างแม่นยำกับโจทย์และปัญหามากกว่าอีกทั้งยังสามารถอธิบายได้ด้วยสมการคณิตศาสตร์ว่าค่าที่ทำนายได้มาอย่างไรอีกด้วย แต่ในบทความนี้จะขอเสนออีกมุมหนึ่งคือการทำ Deep Learning สำหรับ Regression ว่าต้องทำอย่างไร เผื่อในกรณีที่เรามีข้อมูลจำนวนมากและต้องการให้โมเดลมีความสามารถที่กว้างขวางรองรับได้หลายค่ามากขึ้น
Setup Environment
เพื่อความสะดวกในการสาธิตและการทำตาม ผู้เขียนจะทดลองใน Google Colab
เตรียมข้อมูลสำหรับใช้กับ PyTorch
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic2.png)
เริ่มจากติดตั้ง Library เพิ่ม 1 ตัวคือ datasets ตัวนี้จะช่วยให้เราจัดการกับชุดข้อมูลง่ายขึ้นไม่ว่าข้อมูลจะมาในรูปแบบใดก็ตาม
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic3.png)
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic4.png)
สำหรับชุดข้อมูลในที่นี้เราจะใช้ชุดข้อมูลตัวอย่างที่ Colab มีไว้ให้ลองเล่นอยู่แล้ว โดยจะเกี่ยวกับราคากลางของบ้านโดยวิเคราะห์จากฟีเจอร์ต่าง ๆ ได้แก่ Longitude, Latitude, Housing_median_age, total_rooms, total_bedrooms, population, households, median_income
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic5.png)
โหลดข้อมูลเข้า Format ของ Dataset ซึ่งจะเข้าถึงข้อมูลได้ในลักษณะเดียวกับ Dictionary ใน Python (ข้อดีของ Datasets คือใช้จัดการกับข้อมูลที่มีขนาดใหญ่มาก ๆ ได้ไม่ว่าจะเป็นฟีเจอร์ของข้อมูลภาพ
ฟีเจอร์ของเสียง หรืออื่น ๆ)
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic6.png)
ส่งชุดข้อมูลเข้า DataLoader ของ PyTorch โดยกำหนด Batch Size อยู่ที่ 64 ขั้นตอนนี้คือการทำให้ชุดข้อมูลถูกโหลดทีละ 64 rows ไม่ได้ถูกโหลดทั้งหมดทีเดียวในขณะที่เทรน
สร้างโมเดล Regression อย่างง่าย
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic7.png)
เริ่มจากเลือก device ที่ต้องการจะใช้งาน โดยถ้ามีการ์ดจอที่ใช้งานได้
device จะเป็น cuda แต่ถ้าไม่มีก็จะเป็น cpu
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic8.png)
โมเดลจะประกอบด้วย Linear Layers ทั้งหมด 4 ชั้นและมี ReLU Activation Function คั่น
- Linear ชั้นแรกทำหน้าที่รับ Input โดยมีขนาดตามฟีเจอร์ของข้อมูลเราคือ 8 และส่ง Output ออกคือ 24
- ReLU (Rectified Linear Unit) ช่วยแก้ไขเรื่อง Non-Linear และการที่ Gradient สูญหาย
- Linear ชั้นที่สองรับ Input 24 (จากชั้นแรก) และส่ง Output 12 การทำเช่นนี้เพื่อให้ DNN มีการเรียนรู้เพิ่มมากขึ้น
- Linear ชั้นที่สามรับ Input 12 และส่ง Output 6
- และ Linear ชั้นสุดท้ายรับ Input 6 และส่ง Output 1 หรือก็คือ 1 ค่าที่เราต้องการให้โมเดลทำนายผล
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic9.png)
สั่งสร้างโมเดลและส่งไปไว้บน GPU
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic10.png)
เรียกใช้งาน Loss Function ที่ต้องการใช้ ซึ่งในที่นี้คือ MSE (Mean Square Error) และเรียกใช้ Optimizer เป็น Adam สำหรับปรับค่า Learning Rate ในการเทรนโมเดลและใช้ Scheduler สำหรับควบคุมการขยับของ Learning
การเทรนโมเดลด้วย PyTorch
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic11.png)
การเทรนโมเดลด้วยจะเริ่มจากขั้นตอนดังนี้
- กำหนดจำนวน Epoch ที่ต้องการเทรนทั้งหมด
- กำหนด Path ที่ต้องการเก็บบันทึกโมเดลที่เทรนแล้ว
- กำหนดค่า Best MSE เพื่อไว้ติดตามโมเดลที่ดีที่สุด โดยเริ่มต้นให้กำหนดเป็นค่าว่าง
- history สำหรับเก็บผลค่า Loss ขณะวัดผลเผื่อต้องการพล็อตดู
- lrs สำหรับเก็บค่า Learning Rate เพื่อดูว่ามันปรับตัวอย่างไรบ้าง
- Features เลือกชื่อของคอลัมน์ที่จะใช้เป็น Features ในการเทรน
- Target เลือกชื่อของคอลัมน์ที่จะใช้เป็นค่าเป้าหมาย
- สร้างลูป ลูปแรกคือกำหนดให้วนตามจำนวน Epoch ที่กำหนด
- สั่ง model.train() และสร้างลูปที่ 2 คือลูปสำหรับเทรนกำหนดให้วนในชุดข้อมูลเทรนโดยจะเข้าถึงข้อมูลตามที่เรากำหนดไว้ใน DataLoader จากนั้นเข้าถึงฟีเจอร์และค่าเป้าหมายแล้วส่งให้โมเดลทำการทำนายผลแล้วจึงคำนวณค่า Loss ด้วย Loss Function
- สั่ง Optimizer อัปเดทค่าตาม Weights ที่คำนวณได้
- Scheduler.step() เพื่อสั่งอัปเดทค่าการขยับ Learning Rate เมื่อจบ 1 Epoch
- สร้างเงื่อนไขสำหรับบันทึก Model, Optimizer, Loss, Epoch เพื่อเก็บเป็น Checkpoint ไว้เรียกใช้งานภายหลังหรือใช้ในการเทรนต่อ โดยเงื่อนไขการบันทึกคือบันทึกเมื่อ Loss มีค่าน้อยลง (ผลลัพธ์ดีขึ้นเท่านั้น) ไม่จำเป็นต้องบันทึกทุกครั้งเสมอไป
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic12.png)
การวัดผลโมเดลจะทำเมื่อเทรนจบทุก ๆ 1 Epoch โดยใช้คำสั่ง model.eval() และตามด้วยลูปดังนี้
- สร้างลูปที่เข้าถึงข้อมูล Test Dataloader
- เข้าถึง Features และ Target
- ส่ง Features ให้โมเดลทำนายค่า
- วัดผลด้วย Loss Function
- เก็บค่าในแต่ละ Batch ที่คำนวณได้ไว้ในตัวแปรเพื่อให้ค่าครบทั้งชุดข้อมูล
- history.append สำหรับเก็บค่า MSE ที่ได้ตอนทำ Validation
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic13.png)
การโหลด Checkpoint ทำได้โดย
- ประกาศสร้างโมเดลดังในขั้นตอนสร้างโมเดลข้างต้น
- ใช้คำสั่ง torch.load(PATH TO CHECKPOINT) เพื่อโหลด Weights ของโมเดล, Optimizer, และอื่น ๆ ที่บันทึกไว้
- การโหลด Weights ใส่โมเดลใช้ model.load_state_dict() และผ่านค่า Weights ใน Checkpoint เข้าไป
- Optimizer ก็ทำเช่นเดียวกันกับโมเดล
- Scheduler สามารถลองปรับเปลี่ยนเป็นอย่างอื่นดูได้ โดยเรียกใช้หลังจากโหลด Weights ใส่ Optimizer แล้ว
ตัวอย่างการทำนายผล
![](https://www.sub-brain.com/wp-content/uploads/2023/07/AInb-Post-10-Pic14.png)
จะเห็นว่าค่าที่ทำนายได้กับค่าเฉลยยังห่างกันอยู่มาก (Loss ยังสูง) ซึ่งแสดงให้เห็นว่าโมเดลจำเป็นต้องมีข้อมูลมากขึ้น หรืออาจต้องเทรนมากขึ้น มีโครงสร้างที่เหมาะสมกับข้อมูลมากขึ้น ไปจนถึงการจัดเตรียมข้อมูล