Bạn từng tự sao model AI của mình huấn luyện mãi mà kết quả không khá lên? Hoặc loss function nhảy loạn xạ ngay từ vòng đầu tiên? Rất có thể vấn đề nằm ở Weight Initialization — bước thiết lập trọng số ban đầu tưởng nhỏ nhưng quyết định model có học được hay không.
Weight Initialization Là Gì?

Weight Initialization là quá trình gán giá trị ban đầu cho các trọng số (weights) trong neural network trước khi bắt đầu huấn luyện. Thay vì để tất cả bằng 0 hoặc gán ngẫu nhiên vô tội vạ, bạn dùng các phương pháp có tính toán để model hội tụ nhanh hơn và ổn định hơn.
Nói đơn giản hơn: nó giống như việc bạn chọn điểm xuất phát trong một cuộc đua. Đứng đúng chỗ, bạn đến đích nhanh. Đứng sai chỗ, bạn có thể lạc mãi mãi.
Tại Sao Weight Initialization Quan Trọng?
Nếu tất cả trọng số ban đầu bằng 0, mọi neuron trong cùng một lớp sẽ tính ra giá trị giống hệt nhau. Gradient cũng giống nhau. Kết quả là mạng neuron học một cách đối xứng, không khác gì dùng 1 neuron thay vì cả lớp. Hiệu ứng này gọi là symmetry breaking problem.
Nếu trọng số quá lớn, gradient bùng nổ (exploding gradient). Quá nhỏ, gradient biến mất (vanishing gradient). Cả hai đều khiến model không học được gì.
Mình từng thấy một bạn khởi tạo trọng số bằng np.random.randn() không chia chuẩn, model chạy 500 epoch mà accuracy vẫn dính ở 10%. Đổi sang He initialization, accuracy nhảy lên 85% ngay sau 20 epoch. Cùng dữ liệu, cùng kiến trúc, khác nhau mỗi bước khởi tạo.
Các Phương Pháp Weight Initialization Phổ Biến
1. Random Initialization (Ngẫu nhiên)
Phương pháp đơn giản nhất: gán giá trị ngẫu nhiên từ phân phối uniform hoặc normal. Tuy nhiên, nếu chọn phương sai không phù hợp, model sẽ gặp vấn đề vanishing hoặc exploding gradient khi mạng sâu.
2. Xavier / Glorot Initialization
Phát triển bởi Xavier Glorot và Yoshua Bengio năm 2010, phương pháp này chia trọng số cho căn bậc hai của số neuron đầu vào cộng đầu ra. Phù hợp cho hàm kích hoạt đối xứng như tanh hoặc sigmoid.
Công thức: W ~ N(0, sqrt(2 / (fan_in + fan_out)))
Xavier trở thành tiêu chuẩn cho các mạng không dùng ReLU. Nó cân bằng tốt variance của tín hiệu đầu vào và đầu ra, giúp gradient ổn định qua từng lớp.
3. He / Kaiming Initialization
Kaiming He (tác giả của ResNet) đề xuất phương pháp này năm 2015, tối ưu cho hàm ReLU và các biến thể (Leaky ReLU, PReLU). Thay vì chia cho fan_in + fan_out, He chỉ chia cho fan_in.
Công thức: W ~ N(0, sqrt(2 / fan_in))
Vì ReLU đặt nửa giá trị về 0, variance cần lớn hơn để bù đắp. Nếu bạn dùng ReLU mà khởi tạo Xavier, model vẫn chạy nhưng chậm hội tụ hơn đáng kể.
4. LeCun Initialization
Yann LeCun đề xuất phương pháp này, chia cho fan_in nhưng với variance 1 / fan_in. Phù hợp cho SELU — hàm kích hoạt tự chuẩn hóa (self-normalizing). Ít phổ biến hơn He nhưng vẫn xuất hiện trong các mạng SNN (Self-Normalizing Neural Networks).
5. Orthogonal Initialization
Khởi tạo trọng số dưới dạng ma trận trực giao (orthogonal matrix). Giúp bảo toàn norm của tín hiệu khi truyền qua nhiều lớp. Thường dùng trong RNN, LSTM — các kiến trúc dễ bị vanishing gradient nhất.
Chọn Phương Pháp Nào?
Quy tắc thực tế mà mình áp dụng:
- Dùng ReLU hoặc biến thể: chọn He initialization
- Dùng tanh hoặc sigmoid: chọn Xavier initialization
- Dùng SELU: chọn LeCun initialization
- RNN, LSTM, mạng rất sâu: thử Orthogonal initialization
- Không chắc: He initialization là mặc định an toàn cho hầu hết trường hợp
Trong PyTorch, bạn không cần tự implement. Mọi lớp nn.Linear đều đã dùng He initialization mặc định cho ReLU-based networks. TensorFlow Keras cũng tự chọn Xavier hoặc He dựa trên hàm kích hoạt. Điều bạn cần là hiểu原理 để debug khi model không học.
Lỗi Thường Gặp Khi Khởi Tạo Trọng Số
Lỗi 1: Quên đổi initialization khi đổi activation. Chuyển từ sigmoid sang ReLU mà vẫn dùng Xavier? Model chạy nhưng học chậm. Đây là lỗi tinh tế nhất vì không báo lỗi, chỉ thấy loss giảm rùa.
Lỗi 2: Khởi tạo bias quá lớn. Bias thường khởi tạo bằng 0, nhưng nếu gán ngẫu nhiên lớn, neuron có thể bị bão hòa ngay từ đầu, đặc biệt với sigmoid.
Lỗi 3: Dùng seed khác nhau giữa các layer. Không phải lỗi kỹ thuật, nhưng khi reproduce kết quả, bạn cần kiểm soát seed chặt chẽ. Mình từng mất 2 ngày debug vì tưởng bug thuật toán, hóa ra do numpy seed không được set đúng.
Weight Initialization Trong Transfer Learning
Khi dùng pretrained model (như GPT, BERT, ResNet), bạn không cần khởi tạo trọng số từ đầu. Model đã có trọng số tốt từ pretraining. Weight initialization chỉ quan trọng khi bạn train from scratch hoặc thêm layer mới lên trên pretrained backbone.
Trong trường hợp thêm layer mới, nguyên tắc: layer mới nên dùng cùng initialization với kiến trúc gốc. Nếu backbone dùng He, layer mới cũng nên dùng He.
Mối Quan Hệ Với Batch Normalization
Một câu hỏi hay gặp: “Có cần weight initialization khi đã có Batch Normalization?” Câu trả lời là có. Batch Norm giúp ổn định phân phối qua từng lớp, giảm dependence vào initialization. Nhưng nó không thay thế hoàn toàn. Nghiên cứu cho thấy kết hợp He/Xavier initialization + Batch Norm cho kết quả tốt hơn so với chỉ dùng một trong hai.
Kết Luận
Weight Initialization là bước nền móng quyết định model AI của bạn học nhanh hay chậm, ổn định hay mất niềm. Chọn đúng phương pháp (He cho ReLU, Xavier cho tanh/sigmoid) tốn 1 dòng code nhưng tiết kiệm hàng giờ huấn luyện. Khi model không học, trước khi blame dữ liệu hay kiến trúc, hãy kiểm tra initialization trước.
Nhớ: khởi tạo đúng là nửa chặng đường của huấn luyện.