Lab 5: Multi-Layer Perceptron (MLP)

วัตถุประสงค์การเรียนรู้

  1. เข้าใจหลักการทำงานของ Multi-Layer Perceptron (MLP)
  2. เข้าใจกระบวนการ Forward Propagation และ Backpropagation
  3. สามารถเลือก Activation Function ที่เหมาะสมกับปัญหา
  4. สามารถใช้ scikit-learn ในการสร้างและฝึก MLP Model
  5. สามารถปรับแต่ง Hyperparameters เพื่อเพิ่มประสิทธิภาพของโมเดล

ทฤษฎีเบื้องต้น

Perceptron

Perceptron เป็นหน่วยพื้นฐานของ Neural Network โดยรับ input หลายตัว คูณด้วย weights รวมกัน แล้วส่งผ่าน Activation Function

สูตร Perceptron:

z = i = 1 n w i x i + b a = σ ( z )

โดยที่:

Multi-Layer Perceptron (MLP)

MLP ประกอบด้วย Perceptron หลายตัวเรียงกันเป็นชั้น (layers):

  1. Input Layer - รับข้อมูล features
  2. Hidden Layer(s) - ประมวลผลข้อมูล (อาจมีหลายชั้น)
  3. Output Layer - ส่งออกผลลัพธ์การทำนาย

Activation Functions

1. Sigmoid

σ ( z ) = 1 1 + e - z

2. Hyperbolic Tangent (tanh)

tanh ( z ) = e z - e - z e z + e - z

3. ReLU (Rectified Linear Unit)

ReLU ( z ) = max ( 0 , z )

4. Softmax (สำหรับ Multi-class Classification)

softmax ( z i ) = e z i j = 1 K e z j

Forward Propagation

กระบวนการส่งข้อมูลจาก Input Layer ไปยัง Output Layer ผ่าน Hidden Layers

สำหรับ Layer l:

z [ l ] = W [ l ] a [ l - 1 ] + b [ l ] a [ l ] = g [ l ] ( z [ l ] )

โดยที่:


Loss Functions

Cross-Entropy Loss (สำหรับ Classification)

Binary Cross-Entropy:

L = - 1 m i = 1 m [ y ( i ) log ( y ^ ( i ) ) + ( 1 - y ( i ) ) log ( 1 - y ^ ( i ) ) ]

Categorical Cross-Entropy:

L = - 1 m i = 1 m k = 1 K y k ( i ) log ( y ^ k ( i ) )

Backpropagation

กระบวนการคำนวณ gradient ของ loss function เทียบกับ weights และ biases โดยใช้ Chain Rule

Gradient ของ Output Layer:

δ [ L ] = L z [ L ] = a [ L ] - y

Gradient ของ Hidden Layer l:

δ [ l ] = ( W [ l + 1 ] ) T δ [ l + 1 ] g ( z [ l ] )

การอัปเดต Weights และ Biases:

W [ l ] := W [ l ] - η L W [ l ] b [ l ] := b [ l ] - η L b [ l ]

โดยที่ η คือ Learning Rate


คำสั่ง

ให้นักศึกษาเขียนโปรแกรมภาษา Python เพื่อทำนายสภาพอากาศว่าฝนจะตกหรือไม่ โดยใช้ Multi-Layer Perceptron จากข้อมูลที่กำหนดให้

สิ่งที่ต้องทำ

  1. อ่านข้อมูล Training Set จากไฟล์ weather_data.csv

  2. เตรียมข้อมูล (Data Preprocessing):

  3. สร้างและฝึก MLP Model:

  4. ประเมินประสิทธิภาพ:

  5. ทดสอบกับ Test Cases ที่กำหนดให้


ข้อกำหนด

Features (ตัวแปรอิสระ)

Feature ค่าที่เป็นไปได้ คำอธิบาย
เมฆ (Cloud) มาก, ปานกลาง, น้อย ปริมาณเมฆบนท้องฟ้า
อากาศ (Temperature) ร้อน, อบอุ่น, เย็น อุณหภูมิของอากาศ
ความชื้น (Humidity) มาก, ปานกลาง, น้อย ระดับความชื้นในอากาศ

Class (ตัวแปรตาม)

Class คำอธิบาย
ฝนไม่ตก ไม่มีฝนตก
ฝนตกเล็กน้อย มีฝนตกเบาๆ หรือฝนปรอย
ฝนตกหนัก มีฝนตกหนักมาก

ข้อกำหนดทางเทคนิค

  1. ภาษา: Python 3.x
  2. อนุญาตใช้ Library:
  3. ต้องแสดง:
  4. ปัดทศนิยม 6 ตำแหน่ง

ชุดข้อมูล Training Set (50 รายการ)

id,cloud,temperature,humidity,rain
1,มาก,เย็น,มาก,ฝนตกหนัก
2,มาก,อบอุ่น,มาก,ฝนตกหนัก
3,ปานกลาง,อบอุ่น,ปานกลาง,ฝนตกเล็กน้อย
4,น้อย,ร้อน,น้อย,ฝนไม่ตก
5,น้อย,ร้อน,ปานกลาง,ฝนไม่ตก
6,มาก,เย็น,ปานกลาง,ฝนตกเล็กน้อย
7,ปานกลาง,ร้อน,มาก,ฝนตกเล็กน้อย
8,น้อย,อบอุ่น,น้อย,ฝนไม่ตก
9,มาก,อบอุ่น,ปานกลาง,ฝนตกเล็กน้อย
10,ปานกลาง,เย็น,มาก,ฝนตกหนัก
11,น้อย,เย็น,น้อย,ฝนไม่ตก
12,มาก,ร้อน,มาก,ฝนตกหนัก
13,ปานกลาง,อบอุ่น,น้อย,ฝนไม่ตก
14,มาก,เย็น,มาก,ฝนตกหนัก
15,น้อย,ร้อน,น้อย,ฝนไม่ตก
16,ปานกลาง,เย็น,ปานกลาง,ฝนตกเล็กน้อย
17,มาก,อบอุ่น,มาก,ฝนตกหนัก
18,น้อย,อบอุ่น,ปานกลาง,ฝนไม่ตก
19,ปานกลาง,ร้อน,ปานกลาง,ฝนตกเล็กน้อย
20,มาก,เย็น,ปานกลาง,ฝนตกเล็กน้อย
21,น้อย,ร้อน,มาก,ฝนตกเล็กน้อย
22,มาก,อบอุ่น,ปานกลาง,ฝนตกเล็กน้อย
23,ปานกลาง,เย็น,มาก,ฝนตกหนัก
24,น้อย,เย็น,ปานกลาง,ฝนไม่ตก
25,มาก,ร้อน,ปานกลาง,ฝนตกเล็กน้อย
26,ปานกลาง,อบอุ่น,มาก,ฝนตกเล็กน้อย
27,น้อย,อบอุ่น,น้อย,ฝนไม่ตก
28,มาก,เย็น,มาก,ฝนตกหนัก
29,ปานกลาง,ร้อน,น้อย,ฝนไม่ตก
30,มาก,อบอุ่น,มาก,ฝนตกหนัก
31,น้อย,เย็น,มาก,ฝนตกเล็กน้อย
32,ปานกลาง,เย็น,ปานกลาง,ฝนตกเล็กน้อย
33,มาก,ร้อน,มาก,ฝนตกหนัก
34,น้อย,ร้อน,ปานกลาง,ฝนไม่ตก
35,ปานกลาง,อบอุ่น,ปานกลาง,ฝนตกเล็กน้อย
36,มาก,เย็น,ปานกลาง,ฝนตกเล็กน้อย
37,น้อย,อบอุ่น,มาก,ฝนตกเล็กน้อย
38,มาก,อบอุ่น,น้อย,ฝนไม่ตก
39,ปานกลาง,เย็น,มาก,ฝนตกหนัก
40,น้อย,ร้อน,น้อย,ฝนไม่ตก
41,มาก,เย็น,มาก,ฝนตกหนัก
42,ปานกลาง,ร้อน,ปานกลาง,ฝนตกเล็กน้อย
43,น้อย,อบอุ่น,ปานกลาง,ฝนไม่ตก
44,มาก,อบอุ่น,มาก,ฝนตกหนัก
45,ปานกลาง,เย็น,น้อย,ฝนไม่ตก
46,น้อย,เย็น,ปานกลาง,ฝนตกเล็กน้อย
47,มาก,ร้อน,ปานกลาง,ฝนตกเล็กน้อย
48,ปานกลาง,อบอุ่น,มาก,ฝนตกเล็กน้อย
49,น้อย,ร้อน,มาก,ฝนตกเล็กน้อย
50,มาก,เย็น,มาก,ฝนตกหนัก

สรุปการกระจายของข้อมูล

Class จำนวน สัดส่วน
ฝนไม่ตก 15 30%
ฝนตกเล็กน้อย 20 40%
ฝนตกหนัก 15 30%

ตัวอย่าง Input และ Output

Test Case 1

Input:

เมฆ: มาก
อากาศ: เย็น
ความชื้น: มาก

Output:

===============================================
       MLP Weather Prediction
===============================================

Input Features:
  - เมฆ: มาก
  - อากาศ: เย็น
  - ความชื้น: มาก

-----------------------------------------------
Prediction Probabilities
-----------------------------------------------
P(ฝนไม่ตก)      = 0.012345
P(ฝนตกเล็กน้อย) = 0.087655
P(ฝนตกหนัก)     = 0.900000

MLP Prediction: ฝนตกหนัก
Confidence: 90.00%
===============================================

Test Case 2

Input:

เมฆ: น้อย
อากาศ: ร้อน
ความชื้น: น้อย

Output:

===============================================
       MLP Weather Prediction
===============================================

Input Features:
  - เมฆ: น้อย
  - อากาศ: ร้อน
  - ความชื้น: น้อย

-----------------------------------------------
Prediction Probabilities
-----------------------------------------------
P(ฝนไม่ตก)      = 0.923456
P(ฝนตกเล็กน้อย) = 0.054321
P(ฝนตกหนัก)     = 0.022223

MLP Prediction: ฝนไม่ตก
Confidence: 92.35%
===============================================

Test Case 3

Input:

เมฆ: ปานกลาง
อากาศ: อบอุ่น
ความชื้น: ปานกลาง

Output:

===============================================
       MLP Weather Prediction
===============================================

Input Features:
  - เมฆ: ปานกลาง
  - อากาศ: อบอุ่น
  - ความชื้น: ปานกลาง

-----------------------------------------------
Prediction Probabilities
-----------------------------------------------
P(ฝนไม่ตก)      = 0.156789
P(ฝนตกเล็กน้อย) = 0.698765
P(ฝนตกหนัก)     = 0.144446

MLP Prediction: ฝนตกเล็กน้อย
Confidence: 69.88%
===============================================

Test Case 4

Input:

เมฆ: มาก
อากาศ: ร้อน
ความชื้น: น้อย

Output:

===============================================
       MLP Weather Prediction
===============================================

Input Features:
  - เมฆ: มาก
  - อากาศ: ร้อน
  - ความชื้น: น้อย

-----------------------------------------------
Prediction Probabilities
-----------------------------------------------
P(ฝนไม่ตก)      = 0.412345
P(ฝนตกเล็กน้อย) = 0.398765
P(ฝนตกหนัก)     = 0.188890

MLP Prediction: ฝนไม่ตก
Confidence: 41.23%
===============================================

Test Case 5

Input:

เมฆ: น้อย
อากาศ: เย็น
ความชื้น: มาก

Output:

===============================================
       MLP Weather Prediction
===============================================

Input Features:
  - เมฆ: น้อย
  - อากาศ: เย็น
  - ความชื้น: มาก

-----------------------------------------------
Prediction Probabilities
-----------------------------------------------
P(ฝนไม่ตก)      = 0.187654
P(ฝนตกเล็กน้อย) = 0.523456
P(ฝนตกหนัก)     = 0.288890

MLP Prediction: ฝนตกเล็กน้อย
Confidence: 52.35%
===============================================

โครงสร้างโปรแกรมที่แนะนำ

import pandas as pd
import numpy as np
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import matplotlib.pyplot as plt
import seaborn as sns

class WeatherMLP:
    def __init__(self, hidden_layers=(64, 32), activation='relu', 
                 max_iter=1000, learning_rate_init=0.001, random_state=42):
        """
        Initialize MLP classifier with hyperparameters
        
        Parameters:
        -----------
        hidden_layers : tuple
            จำนวน neurons ในแต่ละ hidden layer
        activation : str
            Activation function ('relu', 'tanh', 'logistic')
        max_iter : int
            จำนวน iterations สูงสุดในการ training
        learning_rate_init : float
            Learning rate เริ่มต้น
        random_state : int
            Random seed สำหรับ reproducibility
        """
        self.hidden_layers = hidden_layers
        self.activation = activation
        self.max_iter = max_iter
        self.learning_rate_init = learning_rate_init
        self.random_state = random_state
        
        self.model = None
        self.feature_encoder = None
        self.label_encoder = None
        self.feature_names = ['cloud', 'temperature', 'humidity']
        
    def _preprocess_features(self, data, fit=False):
        """
        แปลง categorical features เป็น numerical
        """
        # TODO: Implement One-Hot Encoding หรือ Label Encoding
        pass
    
    def _preprocess_labels(self, labels, fit=False):
        """
        แปลง class labels เป็น numerical
        """
        # TODO: Implement Label Encoding
        pass
    
    def fit(self, data):
        """
        Train the MLP model
        
        Parameters:
        -----------
        data : pandas.DataFrame
            Training data with columns: cloud, temperature, humidity, rain
        """
        # TODO: Implement training logic
        # 1. Preprocess features
        # 2. Preprocess labels
        # 3. Create and fit MLPClassifier
        pass
    
    def predict(self, features):
        """
        ทำนายผลลัพธ์สำหรับ features ที่กำหนด
        
        Parameters:
        -----------
        features : dict
            Dictionary of feature values
            
        Returns:
        --------
        tuple: (predicted_class, probabilities_dict)
        """
        # TODO: Implement prediction
        pass
    
    def predict_proba(self, features):
        """
        คืนค่าความน่าจะเป็นของแต่ละคลาส
        """
        # TODO: Implement probability prediction
        pass
    
    def evaluate(self, X_test, y_test):
        """
        ประเมินประสิทธิภาพของโมเดล
        """
        # TODO: Implement evaluation
        # 1. Calculate accuracy
        # 2. Generate confusion matrix
        # 3. Generate classification report
        pass
    
    def plot_loss_curve(self):
        """
        แสดง Training Loss Curve
        """
        # TODO: Plot loss curve from self.model.loss_curve_
        pass
    
    def plot_confusion_matrix(self, y_true, y_pred):
        """
        แสดง Confusion Matrix
        """
        # TODO: Plot confusion matrix using seaborn
        pass


def load_data(filename):
    """
    Load training data from CSV file
    """
    # TODO: Implement data loading
    pass


def display_prediction(features, prediction, probabilities):
    """
    แสดงผลการทำนายในรูปแบบที่กำหนด
    """
    print("=" * 47)
    print("       MLP Weather Prediction")
    print("=" * 47)
    print()
    print("Input Features:")
    print(f"  - เมฆ: {features['cloud']}")
    print(f"  - อากาศ: {features['temperature']}")
    print(f"  - ความชื้น: {features['humidity']}")
    print()
    print("-" * 47)
    print("Prediction Probabilities")
    print("-" * 47)
    
    for class_name, prob in probabilities.items():
        print(f"P({class_name:15}) = {prob:.6f}")
    
    confidence = max(probabilities.values()) * 100
    print()
    print(f"MLP Prediction: {prediction}")
    print(f"Confidence: {confidence:.2f}%")
    print("=" * 47)


def main():
    # Load data
    data = load_data('weather_data.csv')
    
    # Create and train classifier
    mlp = WeatherMLP(
        hidden_layers=(64, 32),
        activation='relu',
        max_iter=1000,
        learning_rate_init=0.001,
        random_state=42
    )
    mlp.fit(data)
    
    # Display model architecture
    print("Model Architecture:")
    print(f"  - Hidden Layers: {mlp.hidden_layers}")
    print(f"  - Activation: {mlp.activation}")
    print()
    
    # Plot loss curve
    mlp.plot_loss_curve()
    
    # Test cases
    test_cases = [
        {'cloud': 'มาก', 'temperature': 'เย็น', 'humidity': 'มาก'},
        {'cloud': 'น้อย', 'temperature': 'ร้อน', 'humidity': 'น้อย'},
        {'cloud': 'ปานกลาง', 'temperature': 'อบอุ่น', 'humidity': 'ปานกลาง'},
        {'cloud': 'มาก', 'temperature': 'ร้อน', 'humidity': 'น้อย'},
        {'cloud': 'น้อย', 'temperature': 'เย็น', 'humidity': 'มาก'},
    ]
    
    # Make predictions
    print("\n" + "=" * 60)
    print("                TEST PREDICTIONS")
    print("=" * 60 + "\n")
    
    for i, test in enumerate(test_cases, 1):
        print(f"\n--- Test Case {i} ---")
        prediction, probabilities = mlp.predict(test)
        display_prediction(test, prediction, probabilities)
        print()


if __name__ == "__main__":
    main()

Hyperparameters ที่ควรทดลองปรับ

Parameter คำอธิบาย ค่าที่แนะนำให้ทดลอง
hidden_layer_sizes จำนวนและขนาดของ hidden layers (32,), (64, 32), (128, 64, 32)
activation Activation function 'relu', 'tanh', 'logistic'
solver Optimization algorithm 'adam', 'sgd', 'lbfgs'
learning_rate_init Learning rate เริ่มต้น 0.001, 0.01, 0.0001
max_iter จำนวน iterations สูงสุด 500, 1000, 2000
batch_size ขนาด mini-batch 'auto', 16, 32
alpha L2 regularization 0.0001, 0.001, 0.01
early_stopping หยุด training เมื่อ validation loss ไม่ลด True, False

แบบฝึกหัดเพิ่มเติม

ส่วนที่ 1: การทดลองปรับ Hyperparameters

  1. ทดลองเปลี่ยน จำนวน Hidden Layers และ จำนวน Neurons แล้วเปรียบเทียบผลลัพธ์
  2. ทดลองเปลี่ยน Activation Function ระหว่าง ReLU, tanh, และ sigmoid
  3. ทดลองเปลี่ยน Learning Rate และสังเกต Loss Curve

ส่วนที่ 2: การวิเคราะห์ผลลัพธ์

  1. สร้าง Confusion Matrix และวิเคราะห์ว่าโมเดลทำนายผิดพลาดในกรณีใดบ้าง
  2. คำนวณ Precision, Recall, F1-Score สำหรับแต่ละคลาส
  3. เปรียบเทียบผลลัพธ์กับ Naive Bayes จาก Lab 2

ส่วนที่ 3: การพัฒนาเพิ่มเติม

  1. ใช้ Cross-Validation เพื่อประเมินประสิทธิภาพที่แม่นยำยิ่งขึ้น
  2. ใช้ Grid Search หรือ Random Search เพื่อหา Hyperparameters ที่ดีที่สุด
  3. ทดลองใช้ Dropout หรือ Regularization เพื่อป้องกัน Overfitting

ภาคผนวก: สูตรคณิตศาสตร์เพิ่มเติม

Derivative ของ Activation Functions

Sigmoid:

d σ d z = σ ( z ) ( 1 - σ ( z ) )

Tanh:

d tanh d z = 1 - tanh 2 ( z )

ReLU:

d ReLU d z = { 1 if z > 0 0 if z 0

Gradient Descent Update Rule

θ := θ - η L ( θ )

Adam Optimizer

Moment Estimates:

m t = β 1 m t - 1 + ( 1 - β 1 ) g t v t = β 2 v t - 1 + ( 1 - β 2 ) g t 2

Bias-Corrected Estimates:

m ^ t = m t 1 - β 1 t v ^ t = v t 1 - β 2 t

Parameter Update:

θ := θ - η v ^ t + ε m ^ t

โดยที่: