$$
\definecolor{input}{RGB}{66, 133, 244}
\definecolor{output}{RGB}{219, 68, 55}
\definecolor{dinput}{RGB}{244, 180, 0}
\definecolor{doutput}{RGB}{15, 157, 88}
\definecolor{dweight}{RGB}{102, 0, 255}
$$
Thuật toán phân phối ngược
Thuật toán phân phối ngược là yếu tố cần thiết để đào tạo nhanh mạng nơron lớn. Bài viết này giải thích cách thức hoạt động của thuật toán.
Vui lòng di chuyển xuống...
Mạng nơ-ron đơn giản
Ở bên phải, bạn sẽ thấy một mạng nơron với một đầu vào, một nút đầu ra và hai nút ẩn của mỗi nút.
Các nút trong các lớp lân cận được kết nối với trọng số \(w_{ij}\), tức là các thông số
của mạng.
Hàm kích hoạt
Mỗi nút có một tổng giá trị đầu vào \(\color{input}x\), hàm kích hoạt \(f(\color{input}x\color{black})\)
và kết quả đầu ra \(\color{output}y\color{black}=f(\color{input}x\color{black})\).
\(f(\color{input}x\color{black})\) phải là một hàm phi tuyến tính, nếu không mạng nơron sẽ chỉ có thể học các mô hình tuyến tính.
Hàm kích hoạt thường dùng là
hàm Simomoid:
\(f(\color{input}x\color{black}) = \frac{1}{1+e^{-\color{input}x}}\).
Hàm sai số
Mục tiêu là tự động tìm hiểu trọng số của mạng từ dữ liệu mà đầu ra dự đoán \(\color{output}y_{output}\)
gần với mục tiêu \(\color{output}y_{target}\) cho tất cả dữ liệu đầu vào \(\color{input}x_{input}\).
Để đo lường khoảng cách từ mục tiêu, chúng tôi sử dụng hàm lỗi \(E\).
Một hàm lỗi thường dùng là \(E(\color{output}y_{output}\color{black},\color{output}y_{target}\color{black}) = \frac{1}{2}(\color{output}y_{output}\color{black} - \color{output}y_{target}\color{black})^2 \).
Truyền nhân
Chúng ta bắt đầu bằng cách lấy một ví dụ về đầu vào \((\color{input}x_{input}\color{black},\color{output}y_{target}\color{black})\) và cập nhật lớp đầu vào của mạng.
Để đảm bảo tính nhất quán, chúng tôi sẽ coi đầu vào giống như bất kỳ nút nào khác nhưng không có hàm kích hoạt để đầu ra của đầu vào đó bằng với đầu vào, tức là \( \color{output}y_1 \color{black} = \color{input} x_{input} \).
Truyền nhân
Bây giờ, chúng ta cập nhật lớp ẩn đầu tiên. Chúng ta lấy đầu ra \(\color{output}y\) của các nút trong lớp trước
và sử dụng các trọng số để tính toán dữ liệu đầu vào \(\color{input}x\) của các nút trong lớp tiếp theo.
$$ \color{input} x_j \color{black} = $$$$ \sum_{i\in in(j)} w_{ij}\color{output} y_i\color{black} +b_j$$
Truyền nhân
Sau đó, chúng ta cập nhật kết quả của các nút trong lớp ẩn đầu tiên.
Để làm được điều này, chúng ta sử dụng hàm kích hoạt, \( f(x) \).
$$ \color{output} y \color{black} = f(\color{input} x \color{black})$$
Truyền nhân
Sử dụng 2 công thức này, chúng tôi truyền đi phần còn lại của mạng và nhận kết quả cuối cùng trong mạng.
$$ \color{output} y \color{black} = f(\color{input} x \color{black})$$
$$ \color{input} x_j \color{black} = $$$$ \sum_{i\in in(j)} w_{ij}\color{output} y_i \color{black} + b_j$$
Lỗi phát sinh
Thuật toán phân phối ngược quyết định mức độ cập nhật từng trọng số của mạng sau khi so sánh đầu ra dự đoán với đầu ra mong muốn cho một ví dụ cụ thể.
Do đó, chúng ta cần tính toán sự thay đổi của lỗi liên quan đến từng trọng số \(\color{dweight}\frac{dE}{dw_{ij}}\).
Sau khi có dữ liệu phái sinh lỗi, chúng ta có thể cập nhật trọng số bằng một quy tắc cập nhật đơn giản:
$$w_{ij} = w_{ij} - \alpha \color{dweight}\frac{dE}{dw_{ij}}$$
trong đó \(\alpha\) là một hằng số dương, được gọi là tỷ lệ học tập mà chúng ta cần để tinh chỉnh theo kinh nghiệm.
[Lưu ý] Quy tắc cập nhật rất đơn giản: nếu lỗi giảm khi trọng số tăng (\(\color{dweight}\frac{dE}{dw_{ij}}\color{black} < 0\)), thì hãy tăng trọng số. Ngược lại, nếu lỗi tăng khi trọng số tăng (\(\color{dweight}\frac{dE}{dw_{ij}} \color{black} > 0\)), thì giảm trọng lượng.
Đạo hàm bổ sung
Để giúp tính toán \(\color{dweight}\frac{dE}{dw_{ij}}\), chúng tôi còn lưu trữ thêm cho mỗi nút hai dẫn xuất:
mức độ thay đổi của lỗi với:
- tổng số đầu vào của nút \(\color{dinput}\frac{dE}{dx}\) và
- kết quả của nút \(\color{doutput}\frac{dE}{dy}\).
Truyền trở lại
Hãy bắt đầu sao chép các đạo hàm lỗi.
Vì chúng ta có kết quả dự đoán cho ví dụ đầu vào cụ thể này, nên chúng ta có thể tính toán cách lỗi thay đổi với kết quả đó.
Do hàm lỗi của chúng tôi \(E = \frac{1}{2}(\color{output}y_{output}\color{black} - \color{output}y_{target}\color{black})^2\) chúng tôi có:
$$ \color{doutput} \frac{\partial E}{\partial y_{output}} \color{black} = \color{output} y_{output} \color{black} - \color{output} y_{target}$$
Truyền trở lại
Bây giờ, chúng ta \(\color{doutput} \frac{dE}{dy}\) có thể \(\color{dinput}\frac{dE}{dx}\) sử dụng quy tắc chuỗi.
$$\color{dinput} \frac{\partial E}{\partial x} \color{black} = \frac{dy}{dx}\color{doutput}\frac{\partial E}{\partial y} \color{black} = \frac{d}{dx}f(\color{input}x\color{black})\color{doutput}\frac{\partial E}{\partial y}$$
trong đó \(\frac{d}{dx}f(\color{input}x\color{black}) = f(\color{input}x\color{black})(1 - f(\color{input}x\color{black}))\) khi
\(f(\color{input}x\color{black})\) là hàm kích hoạt Sigmoid.
Truyền trở lại
Ngay khi có phát sinh lỗi liên quan đến tổng số giá trị đầu vào của một nút, chúng ta có thể nhận được dẫn xuất lỗi liên quan đến các trọng số được đưa vào nút đó.
$$\color{dweight} \frac{\partial E}{\partial w_{ij}} \color{black} = \frac{\partial x_j}{\partial w_{ij}} \color{dinput}\frac{\partial E}{\partial x_j} \color{black} = \color{output}y_i \color{dinput} \frac{\partial E}{\partial x_j}$$
Truyền trở lại
Ngoài ra, bằng cách sử dụng quy tắc chuỗi, chúng ta cũng có thể nhận \(\frac{dE}{dy}\) từ lớp trước đó. Chúng ta đã tạo thành một vòng tròn đầy đủ.
$$ \color{doutput} \frac{\partial E}{\partial y_i} \color{black} = \sum_{j\in out(i)} \frac{\partial x_j}{\partial y_i} \color{dinput} \frac{\partial E}{\partial x_j} \color{black} = \sum_{j\in out(i)} w_{ij} \color{dinput} \frac{\partial E}{\partial x_j}$$
Truyền trở lại
Tất cả những việc còn lại phải làm là lặp lại 3 công thức trước đó cho đến khi tính xong tất cả các dẫn xuất lỗi.