Lan truyền ngược (Backpropagation) cho người mới (Phần 3): Cách hoạt động thực sự
Backpropagation không phải là một phép toán mới, mà là cách tổ chức quy tắc chuỗi để tính gradient hiệu quả cho mạng nơ-ron. Bài viết giải thích vì sao việc tái sử dụng các đạo hàm trung gian giúp tiết kiệm tài nguyên tính toán, đồng thời hướng dẫn từng bước lan truyền ngược từ hàm mất mát qua các lớp ẩn. Đây là phần cuối giúp bạn hiểu trọn vẹn cơ chế học của mạng nơ-ron.

Lan truyền ngược (Backpropagation) cho người mới (Phần 3): Cách hoạt động thực sự
Nếu bạn từng tự hỏi làm thế nào một mạng nơ-ron với hàng triệu tham số có thể học được, câu trả lời nằm ở backpropagation — thuật toán lan truyền ngược giúp tính gradient một cách hệ thống và hiệu quả. Trong phần cuối của chuỗi bài này, chúng ta sẽ tìm hiểu vì sao cách tính gradient thủ công trở nên lãng phí, và cách backpropagation tái sử dụng các giá trị trung gian để tối ưu hóa quá trình huấn luyện.
Giới thiệu
Chào mừng bạn quay trở lại với chuỗi bài về backpropagation. Trong Phần 1 và Phần 2, chúng ta đã sử dụng quy tắc chuỗi để tính gradient cho tham số w₁ của một mạng nơ-ron nhỏ. Tuy nhiên, đó mới chỉ là một tham số trong tổng số bảy tham số của mạng. Nếu cứ lặp lại quy trình tương tự cho từng tham số, chúng ta sẽ nhận ra có rất nhiều phép tính đang bị làm đi làm lại một cách không cần thiết.
Mạng nơ-ron và quá trình lan truyền tín hiệu
Vấn đề: Tính lặp lại các đạo hàm trung gian
Khi tính gradient cho w₁, chúng ta có chuỗi:
∂L/∂w₁ = ∂L/∂ŷ · ∂ŷ/∂a₁ · ∂a₁/∂z₁ · ∂z₁/∂w₁
Còn khi tính gradient cho b₁, chuỗi này trở thành:
∂L/∂b₁ = ∂L/∂ŷ · ∂ŷ/∂a₁ · ∂a₁/∂z₁ · ∂z₁/∂b₁
Bạn có nhận thấy điều gì không? Ba đạo hàm đầu tiên hoàn toàn giống nhau ở cả hai biểu thức. Điều khác biệt duy nhất nằm ở thành phần cuối cùng. Nếu chúng ta tính toán từng tham số một cách độc lập, các giá trị trung gian này sẽ bị tính lại nhiều lần dù kết quả không hề thay đổi.
Với một mạng nơ-ron nhỏ, việc tính lặp này có vẻ không đáng lo ngại. Nhưng trong thực tế, các mạng nơ-ron hiện đại có thể có hàng triệu, thậm chí hàng tỷ tham số. Nếu tiếp tục cách tiếp cận này, thời gian huấn luyện sẽ tăng lên khủng khiếp và chi phí tính toán trở nên không thể chấp nhận được.
Ý tưởng đằng sau backpropagation
Giải pháp tự nhiên xuất hiện trong đầu chúng ta là: thay vì tính lại, hãy lưu trữ và tái sử dụng. Khi đã tính ∂L/∂ŷ, ∂L/∂a₁ và ∂L/∂z₁ cho w₁, chúng ta có thể dùng lại chúng ngay khi tính gradient cho b₁. Tương tự, khi lan truyền sâu hơn vào mạng, mỗi giá trị gradient trung gian chỉ cần tính một lần và được dùng đi dùng lại cho nhiều tham số khác nhau.
Đây chính là ý tưởng cốt lõi của backpropagation. Quan trọng hơn, backpropagation không phải một phương pháp tính gradient mới — nó vẫn dựa hoàn toàn vào quy tắc chuỗi. Điều khác biệt nằm ở cách tổ chức và thứ tự tính toán.
Từ ý tưởng đến một thuật toán tổng quát
Với mạng nơ-ron nhỏ, chúng ta có thể tự quyết định giá trị nào cần lưu, giá trị nào cần tái sử dụng và tính theo thứ tự nào. Nhưng khi mạng có hàng nghìn lớp với cấu trúc phức tạp, việc làm thủ công là bất khả thi.
Điều chúng ta thực sự cần là một thuật toán tổng quát — hoạt động hiệu quả cho bất kỳ mạng nơ-ron khả vi nào, bất kể kiến trúc hay kích thước. Backpropagation chính là thuật toán đó. Nó cung cấp một quy trình có hệ thống để tính gradient cho tất cả tham số, không cần thiết kế lại logic mỗi khi thay đổi kiến trúc mạng.
Ôn lại quá trình forward pass
Trước khi đi sâu vào backward pass, hãy cùng ôn lại những gì đã xảy ra trong forward pass (lượt truyền xuôi):
- Đầu vào
xđi qua nơ-ron ẩn thứ nhất:z₁ = w₁x + b₁ - Đầu vào
xđi qua nơ-ron ẩn thứ hai:z₂ = w₂x + b₂ - Cả hai giá trị lần lượt được đưa qua hàm kích hoạt ReLU:
a₁ = ReLU(z₁),a₂ = ReLU(z₂) - Nơ-ron đầu ra tính dự đoán:
ŷ = w₃a₁ + w₄a₂ + b₃ - Cuối cùng, hàm mất mát MSE so sánh giá trị dự đoán với giá trị thực:
L = (1/n)Σ(yᵢ - ŷᵢ)²
Sau forward pass, chúng ta có sẵn các giá trị z₁, a₁, z₂, a₂, ŷ và L — tất cả đều sẽ được tái sử dụng trong backward pass.
Công thức dự đoán tại nơ-ron đầu ra
Bắt đầu backward pass
Lưu ý: *Backward


