Hồi quy Logistic và kỹ thuật xử lý đặc trưng đa chiều trong PyTorch

Hồi quy Logistic (Logistic Regression)

Mặc dù tên gọi có chứa từ "hồi quy", nhưng Logistic Regression thực chất được sử dụng cho các bài toán phân loại (classification). Trong các bài toán này, thay vì dự đoán một giá trị cụ thể, mô hình sẽ trả về xác suất xảy ra của một sự kiện, thường nằm trong khoảng [0, 1].

Hàm Logistic (Sigmoid)

Để ánh xạ đầu ra của một mô hình tuyến tính vào khoảng xác suất [0, 1], chúng ta sử dụng hàm Sigmoid (hay còn gọi là hàm Logistic):

$$\sigma(x) = \frac{1}{1 + e^{-x}}$$

Đặc điểm của hàm này là khi $x$ tiến tới vô cùng, giá trị tiến dần đến 1; khi $x$ tiến tới âm vô cùng, giá trị tiến dần đến 0. Tại $x=0$, giá trị trả về là 0.5. Đây là một hàm bão hòa, nghĩa là ở các vùng giá trị cực lớn hoặc cực tiểu, đạo hàm của nó sẽ tiến dần về 0.

Hàm mất mát Binary Cross Entropy

Trong bài toán phân loại nhị phân, chúng ta không sử dụng MSE (Mean Squared Error) mà sử dụng Binary Cross Entropy (BCE). Hàm này đo lường sự khác biệt giữa hai phân phối xác suất: giá trị dự đoán ($\hat{y}$) và nhãn thực tế ($y$). Khi dự đoán càng gần với nhãn, giá trị Loss sẽ càng nhỏ.

Triển khai mã nguồn với PyTorch

Dưới đây là ví dụ về việc xây dựng mô hình phân loại nhị phân đơn giản để dự đoán khả năng vượt qua kỳ thi dựa trên số giờ học:

import torch
import torch.nn as nn
import torch.optim as optim

# Chuẩn bị dữ liệu: [Số giờ học]
inputs = torch.Tensor([[1.0], [2.0], [3.0], [4.0]])
# Nhãn: 0 là trượt, 1 là đỗ
labels = torch.Tensor([[0], [0], [1], [1]])

class BinaryClassifier(nn.Module):
    def __init__(self):
        super(BinaryClassifier, self).__init__()
        # Một lớp tuyến tính đầu vào 1, đầu ra 1
        self.fc = nn.Linear(1, 1)

    def forward(self, x):
        # Áp dụng hàm Sigmoid để lấy xác suất
        probability = torch.sigmoid(self.fc(x))
        return probability

model = BinaryClassifier()

# Sử dụng BCELoss cho bài toán phân loại nhị phân
criterion = nn.BCELoss(reduction='sum')
optimizer = optim.SGD(model.parameters(), lr=0.01)

# Vòng lặp huấn luyện
for epoch in range(500):
    y_pred = model(inputs)
    loss = criterion(y_pred, labels)
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

# Kiểm thử với dữ liệu mới
test_input = torch.Tensor([[5.0]])
prediction = model(test_input)
print(f'Xác suất vượt qua kỳ thi với 5 giờ học: {prediction.item():.4f}')

Xử lý đầu vào đa chiều (Multi-dimensional Features)

Trong thực tế, một mẫu dữ liệu thường có nhiều đặc trưng (features) khác nhau. Ví dụ, để dự đoán kết quả học tập, ta không chỉ dựa vào số giờ học mà còn cả điểm chuyên cần, chỉ số IQ, v.v. Trong PyTorch, mỗi đặc trưng này tương ứng với một cột trong ma trận dữ liệu.

Phép toán ma trận

Khi làm việc với dữ liệu đa chiều, mô hình tuyến tính thực hiện phép nhân ma trận giữa đầu vào $X$ và trọng số $W$:

$$Y = X \cdot W + b$$

Nếu đầu vào có 8 đặc trưng, lớp nn.Linear(8, 1) sẽ ánh xạ không gian 8 chiều về 1 giá trị duy nhất (xác suất).

Xây dựng mạng thần kinh nhiều lớp

Thay vì giảm trực tiếp từ 8 chiều xuống 1 chiều, chúng ta có thể sử dụng các lớp trung gian (Hidden Layers) để mô hình học được các đặc trưng phức tạp hơn. Ví dụ: $8 \to 6 \to 4 \to 1$.

Việc sử dụng nhiều lớp giúp tăng khả năng biểu diễn của mô hình, nhưng cần lưu ý tránh hiện tượng Overfitting (quá khớp) - khi mô hình học thuộc lòng dữ liệu nhiễu thay vì tìm ra quy luật tổng quát.

class MultiLayerModel(nn.Module):
    def __init__(self):
        super(MultiLayerModel, self).__init__()
        # Cấu trúc giảm dần số chiều
        self.layer1 = nn.Linear(8, 6)
        self.layer2 = nn.Linear(6, 4)
        self.layer3 = nn.Linear(4, 1)
        # Hàm kích hoạt phi tuyến
        self.relu = nn.ReLU()
        self.sigmoid = nn.Sigmoid()

    def forward(self, x):
        x = self.relu(self.layer1(x))
        x = self.relu(self.layer2(x))
        x = self.sigmoid(self.layer3(x))
        return x

Hàm kích hoạt ReLU

Trong các lớp ẩn của mạng thần kinh sâu, hàm ReLU() thường được ưu tiên sử dụng thay cho Sigmoid. ReLU sẽ giữ nguyên các giá trị dương và chuyển các giá trị âm về 0. Điều này giúp giảm thiểu vấn đề triệt tiêu đạo hàm (vanishing gradient) và tăng tốc độ hội tụ của mô hình trong quá trình huấn luyện.

Thẻ: PyTorch logistic-regression neural-networks deep-learning machine-learning

Đăng vào ngày 27 tháng 7 lúc 15:51