Lớp tuyến tính (Linear Layer)
Lớp tuyến tính, hay còn gọi là lớp kết nối đầy đủ (Fully Connected Layer), thực hiện phép biến đổi affine lên dữ liệu đầu vào. Trong PyTorch, chúng ta có thể sử dụng công cụ có sẵn hoặc tự triển khai để hiểu rõ bản chất toán học bên dưới.
import torch
import torch.nn as nn
# Sử dụng thư viện chuẩn PyTorch
input_dim, output_dim = 128, 64
layer = nn.Linear(input_dim, output_dim, bias=True)
Dưới đây là cách triển khai thủ công lớp tuyến tính bằng cách khởi tạo trọng số (weights) và độ lệch (bias):
class CustomLinear:
def __init__(self, d_in, d_out, use_bias=True):
# Khởi tạo trọng số ngẫu nhiên
self.w = torch.randn(d_out, d_in, requires_grad=True)
self.b = torch.randn(d_out, requires_grad=True) if use_bias else None
def __call__(self, x):
# Phép nhân ma trận: y = xW^T + b
self.output = x @ self.w.t()
if self.b is not None:
self.output += self.b
return self.output
def get_params(self):
return [self.w, self.b] if self.b is not None else [self.w]
Container tuần tự (Sequential)
Lớp Sequential giúp đóng gói nhiều tầng của mạng thần kinh thành một khối thống nhất, dữ liệu sẽ đi qua từng lớp theo thứ tự định sẵn.
# Sử dụng nn.Sequential của PyTorch
simple_net = nn.Sequential(
nn.Linear(784, 256),
nn.ReLU(),
nn.Linear(256, 10)
)
Chúng ta có thể tự xây dựng một lớp tương đương để quản lý danh sách các layer:
class LayerStack:
def __init__(self, *layers):
self.layers = layers
def __call__(self, x):
for layer in self.layers:
x = layer(x)
return x
def collect_parameters(self):
all_params = []
for layer in self.layers:
if hasattr(layer, 'parameters'):
all_params.extend(layer.parameters())
return all_params
Hàm kích hoạt Sigmoid
Hàm Sigmoid nén giá trị đầu vào vào khoảng (0, 1), thường được dùng trong các bài toán phân loại nhị phân để dự đoán xác suất.
class ActivationSigmoid:
def __call__(self, z):
self.out = 1 / (1 + torch.exp(-z))
return self.out
def parameters(self):
return []
Cơ chế tối ưu hóa (Optimizer)
Optimizer chịu trách nhiệm cập nhật trọng số dựa trên gradient tính toán được để giảm thiểu hàm mất mát. Phương pháp phổ biến nhất là SGD (Stochastic Gradient Descent).
# Cập nhật tham số thủ công trong PyTorch
def update_weights(params, lr):
with torch.no_grad():
for p in params:
if p.grad is not None:
p -= lr * p.grad
p.grad.zero_()
Mạng dư thừa (Residual Network - ResNet)
ResNet giải quyết các vấn đề phát sinh khi huấn luyện các mạng thần kinh cực sâu như biến mất gradient (vanishing gradient) và suy giảm hiệu năng (network degradation) bằng cách sử dụng các kết nối tắt (skip connections).
Nguyên lý cơ bản:
- Giải quyết biến mất gradient: Gradient có thể truyền trực tiếp qua các kết nối tắt về các lớp phía trước.
- Học ánh xạ đồng nhất: Nếu một lớp không mang lại lợi ích, mạng có thể dễ dàng học cách bỏ qua nó bằng cách đưa trọng số về 0, giữ nguyên giá trị đầu vào thông qua kết nối tắt.
Triển khai một khối Residual đơn giản:
import torch.nn.functional as F
class ResidualBlock(nn.Module):
def __init__(self, in_ch, out_ch, stride=1):
super().__init__()
self.conv_path = nn.Sequential(
nn.Conv2d(in_ch, out_ch, kernel_size=3, stride=stride, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(),
nn.Conv2d(out_ch, out_ch, kernel_size=3, stride=1, padding=1),
nn.BatchNorm2d(out_ch)
)
self.shortcut = nn.Identity()
if stride != 1 or in_ch != out_ch:
self.shortcut = nn.Sequential(
nn.Conv2d(in_ch, out_ch, kernel_size=1, stride=stride),
nn.BatchNorm2d(out_ch)
)
def forward(self, x):
residual = self.shortcut(x)
out = self.conv_path(x)
return F.relu(out + residual)
Xây dựng kiến trúc ResNet bằng cách chồng các khối Residual:
class MiniResNet(nn.Module):
def __init__(self, num_classes=10):
super().__init__()
self.stage1 = ResidualBlock(1, 16)
self.stage2 = ResidualBlock(16, 32, stride=2)
self.stage3 = ResidualBlock(32, 64, stride=2)
self.avg_pool = nn.AdaptiveAvgPool2d((1, 1))
self.classifier = nn.Linear(64, num_classes)
def forward(self, x):
x = self.stage1(x)
x = self.stage2(x)
x = self.stage3(x)
x = self.avg_pool(x)
x = torch.flatten(x, 1)
return self.classifier(x)
Việc sử dụng BatchNorm2d cùng với ResNet là kỹ thuật tiêu chuẩn để ổn định quá trình phân phối dữ liệu qua các lớp, giúp hội tụ nhanh hơn và giảm độ nhạy với việc khởi tạo tham số.