🏷️sec_numerical_stability
Cho đến nay, đối với mọi mô hình mà ta đã lập trình, ta đều phải khởi tạo các tham số theo một phân phối cụ thể nào đó. Tuy nhiên, ta mới chỉ lướt qua các chi tiết thực hiện mà không để tâm lắm tới việc tại sao lại khởi tạo tham số như vậy. Bạn thậm chí có thể nghĩ rằng các lựa chọn này không đặc biệt quan trọng. Tuy nhiên, việc lựa chọn cơ chế khởi tạo đóng vai trò rất lớn trong quá trình học của mạng nơ-ron và có thể là yếu tố quyết định để duy trì sự ổn định số học. Hơn nữa, các phương pháp khởi tạo cũng có thể bị ràng buộc bởi các hàm kích hoạt phi tuyến theo những cách thú vị. Việc lựa chọn hàm kích hoạt và cách khởi tạo tham số có thể ảnh hưởng tới tốc độ hội tụ của thuật toán tối ưu. Nếu ta lựa chọn không hợp lý, việc bùng nổ hoặc tiêu biến gradient có thể sẽ xảy ra. Trong phần này, ta sẽ đi sâu hơn vào các chi tiết của chủ đề trên và thảo luận một số phương pháp thực nghiệm hữu ích mà bạn có thể sẽ sử dụng thường xuyên trong suốt sự nghiệp học sâu.
Xét một mạng nơ-ron sâu với
Nếu tất cả giá trị kích hoạt và đầu vào là vector, ta có thể viết lại gradient của
$$\partial_{\mathbf{W}l} \mathbf{o} = \underbrace{\partial{\mathbf{h}^{L-1}} \mathbf{h}^L}{:= \mathbf{M}L} \cdot \ldots \cdot \underbrace{\partial{\mathbf{h}^{l}} \mathbf{h}^{l+1}}{:= \mathbf{M}l} \underbrace{\partial{\mathbf{W}l} \mathbf{h}^l}{:= \mathbf{v}_l}.$$
Nói cách khác, gradient này là tích của
Thông thường, thủ phạm gây ra vấn đề tiêu biến gradient này là hàm kích hoạt sec_mlp
) là lựa chọn phổ biến bởi nó hoạt động giống với một hàm lấy ngưỡng.
Bởi các mạng nơ-ron nhân tạo thời kỳ đầu lấy cảm hứng từ mạng nơ-ron sinh học, ý tưởng rằng các nơ-ron được kích hoạt hoàn toàn hoặc không hề kích hoạt (giống như nơ-ron sinh học) có vẻ rất hấp dẫn.
Hãy cùng xem xét hàm sigmoid kỹ lưỡng hơn để thấy tại sao nó có thể gây ra vấn đề tiêu biến gradient.
%matplotlib inline
from d2l import mxnet as d2l
from mxnet import autograd, np, npx
npx.set_np()
x = np.arange(-8.0, 8.0, 0.1)
x.attach_grad()
with autograd.record():
y = npx.sigmoid(x)
y.backward()
d2l.plot(x, [y, x.grad], legend=['sigmoid', 'gradient'], figsize=(4.5, 2.5))
Như ta có thể thấy, gradient của hàm sigmoid tiêu biến khi đầu vào của nó quá lớn hoặc quá nhỏ. Hơn nữa, khi thực hiện lan truyền ngược qua nhiều tầng, trừ khi giá trị nằm trong vùng Goldilocks, tại đó đầu vào của hầu hết các hàm sigmoid có giá trị xấp xỉ không, gradient của cả phép nhân có thể bị tiêu biến. Khi mạng nơ-ron có nhiều tầng, trừ khi ta cẩn trọng, nhiều khả năng luồng gradient sẽ bị ngắt tại một tầng nào đó. Vấn đề này đã từng gây nhiều khó khăn cho quá trình huấn luyện mạng nơ-ron sâu. Do đó, ReLU, một hàm số ổn định hơn (nhưng lại không hợp lý lắm từ khía cạnh khoa học thần kinh) đã và đang dần trở thành lựa chọn mặc định của những người làm học sâu.
Một vấn đề đối lập là bùng nổ gradient cũng có thể gây phiền toái không kém.
Để giải thích việc này rõ hơn, chúng ta lấy
M = np.random.normal(size=(4, 4))
print('A single matrix', M)
for i in range(100):
M = np.dot(M, np.random.normal(size=(4, 4)))
print('After multiplying 100 matrices', M)
Một vấn đề khác trong việc thiết kế mạng nơ-ron sâu là tính đối xứng hiện hữu trong quá trình tham số hóa.
Giả sử ta có một mạng nơ-ron sâu với một tầng ẩn gồm hai nút
Đây không chỉ là phiền toái về mặt lý thuyết.
Thử hình dung xem điều gì sẽ xảy ra nếu ta khởi tạo giá trị của mọi tham số ở các tầng như sau:
Một cách giải quyết, hay ít nhất giảm thiểu các vấn đề được nêu ở trên là khởi tạo tham số một cách cẩn thận. Chỉ cần cẩn trọng một chút trong quá trình tối ưu hóa và điều chuẩn mô hình phù hợp, ta có thể cải thiện tính ổn định của quá trình học.
Trong các phần trước, ví dụ như trong :numref:sec_linear_gluon
, ta đã sử dụng net.initialize(init.Normal(sigma=0.01))
để khởi tạo các giá trị cho trọng số.
Nếu ta không chỉ định sẵn một phương thức khởi tạo như net.initialize()
, MXNet sẽ sử dụng phương thức khởi tạo ngẫu nhiên mặc định: các trọng số được lấy mẫu ngẫu nhiên từ phân phối đều
Hãy cùng nhìn vào phân phối khoảng giá trị kích hoạt của các nút ẩn
Các trọng số
Một cách để giữ phương sai cố định là đặt
Đây là lý luận đằng sau phương thức khởi tạo Xavier, được đặt tên theo người đã tạo ra nó :cite:Glorot.Bengio.2010
.
Bây giờ nó đã trở thành phương thức tiêu chuẩn và rất hữu dụng trong thực tiễn.
Thông thường, phương thức này lấy mẫu cho trọng số từ phân phối Gauss với trung bình bằng không và phương sai
Các lập luận đưa ra ở trên mới chỉ chạm tới bề mặt của những kỹ thuật khởi tạo tham số hiện đại.
Trên thực tế, MXNet có nguyên một mô-đun mxnet.initializer
với hàng chục các phương pháp khởi tạo dựa theo thực nghiệm khác nhau đã được lập trình sẵn.
Hơn nữa, các phương pháp khởi tạo vẫn đang là một chủ đề nghiên cứu căn bản rất được quan tâm trong học sâu.
Trong số đó là những phương pháp dựa trên thực nghiệm dành riêng cho trường hợp tham số bị trói buộc (được chia sẻ), cho bài toán siêu phân giải, mô hình chuỗi và nhiều trường hợp khác.
Nếu có hứng thú, chúng tôi khuyên bạn nên đào sâu hơn vào mô-đun này, đọc các bài báo mà có đề xuất và phân tích các phương pháp thực nghiệm, và rồi tự khám phá các bài báo mới nhất về chủ đề này.
Có lẽ bạn sẽ gặp (hay thậm chí phát minh ra) một ý tưởng thông minh và lập trình nó để đóng góp cho MXNet.
- Tiêu biến hay bùng nổ gradient đều là những vấn đề phổ biến trong những mạng nơ-ron sâu. Việc khởi tạo tham số cẩn thận là rất cần thiết để đảm bảo gradient và các tham số được kiểm soát tốt.
- Các kĩ thuật khởi tạo tham số dựa trên thực nghiệm là cần thiết để đảm bảo rằng gradient ban đầu không quá lớn hay quá nhỏ.
- Hàm kích hoạt ReLU giải quyết được vấn đề tiêu biến gradient. Điều này có thể làm tăng tốc độ hội tụ.
- Khởi tạo ngẫu nhiên là chìa khóa để đảm bảo tính đối xứng bị phá vỡ trước khi tối ưu hóa.
- Ngoài tính đối xứng hoán vị giữa các tầng, bạn có thể nghĩ ra các trường hợp mà mạng nơ-ron thể hiện tính đối xứng khác cần được phá vỡ không?
- Ta có thể khởi tạo tất cả trọng số trong hồi quy tuyến tính hoặc trong hồi quy softmax với cùng một giá trị hay không?
- Hãy tra cứu cận chính xác của trị riêng cho tích hai ma trận. Nó cho ta biết gì về việc đảm bảo rằng gradient hợp lý?
- Nếu biết rằng một vài số hạng sẽ phân kỳ, bạn có thể khắc phục vấn đề này không? Bạn có thể tìm cảm hứng từ bài báo LARS :cite:
You.Gitman.Ginsburg.2017
.
Bản dịch trong trang này được thực hiện bởi:
- Đoàn Võ Duy Thanh
- Lý Phi Long
- Lê Khắc Hồng Phúc
- Phạm Minh Đức
- Nguyễn Văn Tâm
- Trần Yến Thy
- Bùi Chí Minh
- Phạm Hồng Vinh