11.1. Tối ưu và Học sâu

Trong phần này, ta sẽ thảo luận mối quan hệ giữa tối ưu và học sâu, cũng như những thách thức khi áp dụng các thuật toán tối ưu trong học sâu. Đối với một bài toán học sâu, đầu tiên chúng ta thường định nghĩa hàm mất mát, sau đó sử dụng một thuật toán tối ưu nhằm cực tiểu hóa hàm mất mát đó. Hàm mất mát trong học sâu thường được xem là hàm mục tiêu của bài toán tối ưu. Thông thường, đa số các thuật toán tối ưu thường giải quyết bài toán cực tiểu hóa. Tuy nhiên, nếu ta cần cực đại hóa, có một cách khá đơn giản là đổi dấu hàm mục tiêu.

11.1.1. Tối ưu và Ước lượng

Mặc dù các phương pháp tối ưu thường được sử dụng để cực tiểu hóa hàm mất mát trong học sâu, nhưng mục đích của tối ưu và học sâu về bản chất là khác nhau. Mối quan tâm của tối ưu chủ yếu là cực tiểu hóa một mục tiêu nào đó, trong khi đối với học sâu là tìm kiếm một mô hình phù hợp với một lượng dữ liệu hữu hạn. Trong Section 4.4, ta đã thảo luận chi tiết về sự khác biệt giữa các mục đích trên. Chẳng hạn như là sự khác biệt giữa lỗi huấn luyện và lỗi khái quát. Do hàm mục tiêu của thuật toán tối ưu thường là hàm mất mát trên tập huấn luyện nên mục đích của tối ưu là giảm thiểu lỗi huấn luyện. Tuy nhiên, mục đích của suy luận thống kê (statistical inference) và học sâu nói riêng là giảm thiểu lỗi khái quát. Để thực hiện điều này, bên cạnh việc giảm thiểu lỗi huấn luyện, ta cần chú ý đến hiện tượng quá khớp. Hãy bắt đầu bằng việc nhập một số thư viện sử dụng trong chương này.

%matplotlib inline
from d2l import mxnet as d2l
from mpl_toolkits import mplot3d
from mxnet import np, npx
npx.set_np()

<!–

–>

Tiếp theo, ta định nghĩa hai hàm: hàm kỳ vọng \(f\) và hàm thực nghiệm \(g\) để minh họa vấn đề này. Ở đây, \(g\) kém mượt hơn \(f\) vì ta chỉ có một lượng dữ liệu hữu hạn.

def f(x): return x * np.cos(np.pi * x)
def g(x): return f(x) + 0.2 * np.cos(5 * np.pi * x)

Đồ thị phía dưới mô tả chi tiết hơn về vấn đề trên. Do ta chỉ có một lượng dữ liệu hữu hạn, cực tiểu của lỗi huấn luyện có thể khác so với cực tiểu kỳ vọng của lỗi (lỗi trên tập kiểm tra).

def annotate(text, xy, xytext):  #@save
    d2l.plt.gca().annotate(text, xy=xy, xytext=xytext,
                           arrowprops=dict(arrowstyle='->'))

x = np.arange(0.5, 1.5, 0.01)
d2l.set_figsize((4.5, 2.5))
d2l.plot(x, [f(x), g(x)], 'x', 'risk')
annotate('empirical risk', (1.0, -1.2), (0.5, -1.1))
annotate('expected risk', (1.1, -1.05), (0.95, -0.5))
../_images/output_optimization-intro_vn_5c9184_6_0.svg

11.2. Các Thách thức của Tối ưu trong Học sâu

Ở chương này, ta sẽ chỉ tập trung vào chất lượng của thuật toán tối ưu trong việc cực tiểu hóa hàm mục tiêu, thay vì lỗi khái quát của mô hình. Trong Section 3.1, ta đã phân biệt giữa nghiệm theo công thức và nghiệm xấp xỉ trong các bài toán tối ưu. Trong học sâu, đa số các hàm mục tiêu khá phức tạp và không tính được nghiệm theo công thức. Thay vào đó, ta phải dùng các thuật toán tối ưu xấp xỉ. Các thuật toán tối ưu dưới đây được liệt vào loại này.

Có rất nhiều thách thức về tối ưu trong học sâu. Các điểm cực tiểu, điểm yên ngựa, tiêu biến gradient là một số vấn đề gây đau đầu hơn cả. Hãy cùng tìm hiểu về các vấn đề này.

11.3. Các vùng Cực tiểu

Cho hàm mục tiêu \(f(x)\), nếu giá trị của \(f(x)\) tại \(x\) nhỏ hơn các giá trị khác của \(f(x)\) tại lân cận của \(x\) thì \(f(x)\) có thể là một cực tiểu (local minimum). Nếu giá trị của hàm mục tiêu \(f(x)\) tại \(x\) là nhỏ nhất trên toàn tập xác định thì \(f(x)\)giá trị nhỏ nhất (global minimum).

Ví dụ, cho hàm

(11.3.1)\[f(x) = x \cdot \text{cos}(\pi x) \text{ for } -1.0 \leq x \leq 2.0,\]

ta có thể tính xấp xỉ cực tiểu và giá trị nhỏ nhất của hàm này.

x = np.arange(-1.0, 2.0, 0.01)
d2l.plot(x, [f(x), ], 'x', 'f(x)')
annotate('local minimum', (-0.3, -0.25), (-0.77, -1.0))
annotate('global minimum', (1.1, -0.95), (0.6, 0.8))
../_images/output_optimization-intro_vn_5c9184_8_0.svg

Hàm mục tiêu trong các mô hình học sâu thường có nhiều vùng cực trị. Khi nghiệm xấp xỉ của một bài toán tối ưu đang ở gần giá trị cực tiểu, gradient của hàm mục tiêu tại nghiệm này gần hoặc bằng 0, tuy nhiên nghiệm này có thể chỉ đang cực tiểu hóa hàm mục tiêu một cách cục bộ chứ không phải toàn cục. Chỉ với một mức độ nhiễu nhất định thì mới có thể đẩy tham số ra khỏi vùng cực tiểu. Trên thực tế, nhiễu là một trong những tính chất có lợi của hạ gradient ngẫu nhiên khi sự biến động của gradient qua từng minibatch có thể đẩy các tham số ra khỏi các vùng cực tiểu.

11.4. Các điểm Yên ngựa

Ngoài các vùng cực tiểu, các điểm yên ngựa cũng có gradient bằng 0. Một điểm yên ngựa là bất cứ điểm nào mà tất cả gradient của một hàm bằng 0, nhưng đó không phải là một điểm cực tiểu hay giá trị nhỏ nhất. Xét hàm \(f(x) = x^3\), đạo hàm bậc một và bậc hai của hàm này bằng 0 tại điểm \(x=0\). Việc tối ưu có thể bị ngưng trệ tại điểm này, cho dù đó không phải là điểm cực tiểu.

x = np.arange(-2.0, 2.0, 0.01)
d2l.plot(x, [x**3], 'x', 'f(x)')
annotate('saddle point', (0, -0.2), (-0.52, -5.0))
../_images/output_optimization-intro_vn_5c9184_10_0.svg

Các điểm yên ngựa trong không gian nhiều chiều còn khó chịu hơn nhiều, như ví dụ dưới đây. Xét hàm \(f(x, y) = x^2 - y^2\). Hàm này tồn tại một điểm yên ngựa tại \((0, 0)\). Đây là một điểm cực đại theo \(y\) và là điểm cực tiểu theo \(x\). Tên gọi của tính chất toán học này bắt nguồn từ chính việc đồ thị tại đó có hình dạng giống một cái yên ngựa.

x, y = np.meshgrid(np.linspace(-1.0, 1.0, 101), np.linspace(-1.0, 1.0, 101))
z = x**2 - y**2

ax = d2l.plt.figure().add_subplot(111, projection='3d')
ax.plot_wireframe(x, y, z, **{'rstride': 10, 'cstride': 10})
ax.plot([0], [0], [0], 'rx')
ticks = [-1, 0, 1]
d2l.plt.xticks(ticks)
d2l.plt.yticks(ticks)
ax.set_zticks(ticks)
d2l.plt.xlabel('x')
d2l.plt.ylabel('y');
../_images/output_optimization-intro_vn_5c9184_12_0.svg

Giả sử đầu vào của một hàm là một vector \(k\) chiều và đầu ra là một số vô hướng; do đó ma trận Hessian của nó có \(k\) trị riêng (xem thêm tại Section 18.1). Nghiệm của hàm này có thể là một cực tiểu, cực đại, hoặc một điểm yên ngựa tại vị trí mà gradient của hàm bằng 0.

  • Điểm cực tiểu là vị trí mà ở đó gradient bằng 0 và các trị riêng của ma trận Hessian đều dương.
  • Điểm cực đại là vị trí mà ở đó graident bằng 0 và các trị riêng của ma trận Hessian đều âm.
  • Điểm yên ngựa là vị trí mà ở đó gradient bằng 0 và các trị riêng của ma trận Hessian mang cả giá trị âm lẫn dương.

Đối với bài toán trong không gian nhiều chiều, khả năng có một vài trị riêng âm là khá cao. Do đó các điểm yên ngựa có khả năng xuất hiện cao hơn các cực tiểu. Ta sẽ thảo luận một số ngoại lệ của vấn đề này ở phần tới khi giới thiệu đến tính lồi. Nói ngắn gọn, các hàm lồi là hàm có các trị riêng của ma trận Hessian không bao giờ âm. Nhưng không may, đa số bài toán học sâu đều không thuộc loại này. Dù sao thì tính lồi vẫn là một công cụ tốt để học về các thuật toán tối ưu.

11.5. Tiêu biến Gradient

Có lẽ vấn đế khó chịu nhất mà ta phải đối mặt là tiêu biến gradient. Ví dụ, giả sử ta muốn cực tiểu hóa hàm \(f(x) = \tanh(x)\) và ta bắt đầu tại \(x = 4\). Như ta có thể thấy, gradient của \(f\) gần như là bằng 0. Cụ thể, \(f'(x) = 1 - \tanh^2(x)\) và do đó \(f'(4) = 0.0013\). Hậu quả là quá trình tối ưu sẽ bị trì trệ khá lâu trước khi có tiến triển. Đây hóa ra lại là lý do tại sao việc huấn luyện các mô hình học sâu khá khó khăn trước khi hàm kích hoạt ReLU xuất hiện.

x = np.arange(-2.0, 5.0, 0.01)
d2l.plot(x, [np.tanh(x)], 'x', 'f(x)')
annotate('vanishing gradient', (4, 1), (2, 0.0))
../_images/output_optimization-intro_vn_5c9184_14_0.svg

Tối ưu trong học sâu mang đầy thử thách. May mắn thay, có khá nhiều thuật toán hoạt động tốt và dễ sử dụng ngay cả đối với người mới bắt đầu. Hơn nữa, việc tìm kiếm giải pháp tốt nhất là không thật cần thiết. Các cực tiểu và ngay cả nghiệm xấp xỉ cũng đã rất hữu dụng rồi.

11.5.1. Tóm tắt

  • Cực tiểu hóa lỗi huấn luyện không đảm bảo việc ta sẽ tìm ra tập tham số tốt nhất để cực tiểu hóa lỗi khái quát.
  • Các bài toán tối ưu thường có nhiều vùng cực tiểu.
  • Và do các bài toán thường không có tính lồi, số lượng điểm yên ngựa thậm chí có thể nhiều hơn.
  • Tiêu biến gradient có thể khiến cho quá trình tối ưu bị đình trệ. Thường thì việc tái tham số hóa bài toán (reparameterization) và khởi tạo tham số cẩn thận cũng sẽ giúp ích.

11.5.2. Bài tập

  1. Xét một mạng perceptron đa tầng đơn giản với một tầng ẩn \(d\) chiều và một đầu ra duy nhất. Chỉ ra rằng bất kỳ cực tiểu nào cũng có ít nhất \(d!\) nghiệm tương đương khiến mạng vận hành giống nhau.
  2. Giả sử ta có một ma trận đối xứng \(\mathbf{M}\) ngẫu nhiên, trong đó mỗi phần tử \(M_{ij} = M_{ji}\) tuân theo phân phối xác suất \(p_{ij}\). Ngoài ra, giả sử \(p_{ij}(x) = p_{ij}(-x)\), tức phân phối là đối xứng (xem [Wigner, 1958] để biết thêm chi tiết).
    • Chứng minh rằng phân phối của các trị riêng cũng là đối xứng, tức với mọi vector riêng \(\mathbf{v}\), trị riêng \(\lambda\) tương ứng thoả mãn \(P(\lambda > 0) = P(\lambda < 0)\).
    • Tại sao điều trên không có nghĩa là \(P(\lambda > 0) = 0.5\)?
  3. Liệu còn thử thách tối ưu nào trong học sâu không?
  4. Giả sử bạn muốn cân bằng một quả bóng (thật) trên một chiếc yên ngựa (thật).
    • Tại sao điều này lại khó khăn?
    • Hãy vận dụng kết quả trên vào các thuật toán tối ưu.

11.5.4. Những người thực hiện

Bản dịch trong trang này được thực hiện bởi:

  • Đoàn Võ Duy Thanh
  • Đỗ Trường Giang
  • Lê Khắc Hồng Phúc
  • Nguyễn Văn Quang
  • Phạm Minh Đức
  • Nguyễn Văn Cường
  • Phạm Hồng Vinh