Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.
Softmax và Cross Entropy trong PyTorch Beginner
Trong lĩnh vực học sâu, đặc biệt là các bài toán phân loại, hai thành phần cốt lõi thường được sử dụng là Hàm Softmax và Hàm mất mát Cross Entropy. Hàm Softmax giúp chuyển đổi đầu ra của mô hình thành xác suất, từ đó dễ dàng xác định lớp dự đoán. Trong khi đó, hàm mất mát Cross Entropy được dùng để đánh giá mức độ chính xác của các dự đoán, giúp mô hình học tập hiệu quả hơn. Trong bài viết này, chúng ta sẽ cùng tìm hiểu chi tiết về cách hoạt động của hai hàm này, mối quan hệ giữa chúng, cũng như cách ứng dụng thực tế trong PyTorch.

Hàm Softmax và Cross Entropy (Với Numpy và PyTorch)
.jpg)
Hàm Softmax
import numpy as np
import torch
# Định nghĩa hàm Softmax sử dụng Numpy
def softmax(x):
return np.exp(x) / np.sum(np.exp(x), axis=0)
x = np.array([2.0, 1.0, 0.1])
outputs = softmax(x)
print('Softmax (numpy):', outputs)
# Hàm Softmax sử dụng PyTorch
x = torch.tensor([2.0, 1.0, 0.1])
outputs = torch.softmax(x, dim=0)
print('Softmax (torch):', outputs)
Giải thích:
Hàm Softmax:
- Tính e^x cho từng phần tử.
- Chia mỗi giá trị cho tổng tất cả các giá trị đã nâng lũy thừa .
- Đảm bảo kết quả đầu ra nằm trong khoảng [0, 1] và tổng bằng 1.
Hàm Cross Entropy
# Hàm tính Cross Entropy (Numpy)
def cross_entropy(actual, predicted):
EPS = 1e-15 # Tránh log(0)
predicted = np.clip(predicted, EPS, 1 - EPS)
loss = -np.sum(actual * np.log(predicted))
return loss
# Ví dụ với dữ liệu
Y = np.array([1, 0, 0]) # Nhãn thực tế (one-hot)
Y_pred_good = np.array([0.7, 0.2, 0.1]) # Dự đoán tốt
Y_pred_bad = np.array([0.1, 0.3, 0.6]) # Dự đoán tệ
l1 = cross_entropy(Y, Y_pred_good)
l2 = cross_entropy(Y, Y_pred_bad)
print(f'Loss tốt (numpy): {l1:.4f}')
print(f'Loss tệ (numpy): {l2:.4f}')
Giải thích:
- Cross Entropy đánh giá độ khác biệt giữa nhãn thực tế và nhãn dự đoán .
- Nếu dự đoán đúng (xác suất cao ở nhãn chính xác), loss sẽ nhỏ.
Sử dụng Cross Entropy trong PyTorch
PyTorch cung cấp hàm mất mát tích hợp CrossEntropyLoss, bao gồm cả Softmax.
import torch.nn as nn
# Khởi tạo loss function
loss = nn.CrossEntropyLoss()
# Ví dụ 1: Phân loại 3 lớp
Y = torch.tensor([0]) # Nhãn thực tế (lớp 0)
Y_pred_good = torch.tensor([[2.0, 1.0, 0.1]]) # Logits với dự đoán tốt
Y_pred_bad = torch.tensor([[0.5, 2.0, 0.3]]) # Logits với dự đoán tệ
l1 = loss(Y_pred_good, Y)
l2 = loss(Y_pred_bad, Y)
print(f'Loss tốt (PyTorch): {l1.item():.4f}')
print(f'Loss tệ (PyTorch): {l2.item():.4f}')
Lưu ý:
Bài viết này được đăng tại [free tuts .net]
- Logits: Đầu ra chưa chuẩn hóa (không cần áp dụng Softmax trước).
- Hàm
CrossEntropyLosstự động xử lý chuẩn hóa bằng LogSoftmax.
Loss trên batch và dự đoán
# Ví dụ với nhiều mẫu (batch)
Y = torch.tensor([2, 0, 1]) # Nhãn thực tế cho batch
Y_pred_good = torch.tensor([
[0.1, 0.2, 3.9], # Dự đoán đúng: lớp 2
[1.2, 0.1, 0.3], # Dự đoán đúng: lớp 0
[0.3, 2.2, 0.2] # Dự đoán đúng: lớp 1
])
Y_pred_bad = torch.tensor([
[0.9, 0.2, 0.1], # Sai
[0.1, 0.3, 1.5], # Sai
[1.2, 0.2, 0.5] # Sai
])
l1 = loss(Y_pred_good, Y)
l2 = loss(Y_pred_bad, Y)
print(f'Batch Loss tốt: {l1.item():.4f}')
print(f'Batch Loss tệ: {l2.item():.4f}')
# Dự đoán lớp từ logits
_, predictions1 = torch.max(Y_pred_good, 1)
_, predictions2 = torch.max(Y_pred_bad, 1)
print(f'Lớp thực tế: {Y}')
print(f'Dự đoán tốt: {predictions1}')
print(f'Dự đoán tệ: {predictions2}')
Phân biệt Phân loại nhị phân và Đa lớp trong PyTorch
Phân loại nhị phân
- Sử dụng hàm Sigmoid để chuẩn hóa đầu ra (xác suất cho một lớp).
- Hàm mất mát:
BCELoss().
class NeuralNetBinary(nn.Module):
def __init__(self, input_size, hidden_size):
super(NeuralNetBinary, self).__init__()
self.linear1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.linear2 = nn.Linear(hidden_size, 1)
def forward(self, x):
out = self.linear1(x)
out = self.relu(out)
out = self.linear2(out)
return torch.sigmoid(out)
Phân loại đa lớp
- Không sử dụng Softmax trong mô hình (PyTorch tự xử lý trong
CrossEntropyLoss). - Hàm mất mát:
CrossEntropyLoss().
class NeuralNetMulticlass(nn.Module):
def __init__(self, input_size, hidden_size, num_classes):
super(NeuralNetMulticlass, self).__init__()
self.linear1 = nn.Linear(input_size, hidden_size)
self.relu = nn.ReLU()
self.linear2 = nn.Linear(hidden_size, num_classes)
def forward(self, x):
out = self.linear1(x)
out = self.relu(out)
return self.linear2(out) # Không Softmax

Các kiểu dữ liệu trong C ( int - float - double - char ...)
Thuật toán tìm ước chung lớn nhất trong C/C++
Cấu trúc lệnh switch case trong C++ (có bài tập thực hành)
ComboBox - ListBox trong lập trình C# winforms
Random trong Python: Tạo số random ngẫu nhiên
Lệnh cin và cout trong C++
Cách khai báo biến trong PHP, các loại biến thường gặp
Download và cài đặt Vertrigo Server
Thẻ li trong HTML
Thẻ article trong HTML5
Cấu trúc HTML5: Cách tạo template HTML5 đầu tiên
Cách dùng thẻ img trong HTML và các thuộc tính của img
Thẻ a trong HTML và các thuộc tính của thẻ a thường dùng