Session 08🔮

Neural Network

Từ neuron đến backpropagation: XOR, MLP, forward pass, activation, loss, gradient descent, 4 phương trình BP, vanishing gradient và khởi tạo.


Learning Objectives

  • Hiểu vì sao cần NN (bài toán XOR) và neuron = 1 Logistic Regression
  • Nắm cấu trúc MLP, forward pass và kiểm tra kích thước ma trận
  • Hiểu các activation function và vai trò tạo phi tuyến
  • Nắm 4 phương trình backpropagation dựa trên chain rule
  • Hiểu vanishing/exploding gradient, khởi tạo He/Xavier và Batch Norm

Tại Sao Cần Neural Network?

Logistic Regression chỉ học được 1 đường phân tách tuyến tính — thất bại với bài toán XOR (4 điểm, không đường thẳng nào tách được). Ý tưởng đột phá: 1 LR không đủ → dùng nhiều LR cùng lúc, mỗi neuron học một "góc nhìn" (ranh giới) khác nhau, kết hợp lại để hiểu cấu trúc phức tạp. Mỗi neuron = 1 bộ Logistic Regression thu nhỏ: a = σ(wᵀx + b). Activation function σ có hai vai trò: (1) tạo phi tuyến — không có σ thì 100 lớp vẫn chỉ tương đương 1 LR; (2) On/Off kiểm soát miền giá trị, quyết định neuron "lên tiếng" hay "im lặng".

Cấu Trúc MLP & Forward Pass

MLP (Multi-Layer Perceptron) xếp chồng: input (a[0]=x) → hidden layers → output. Universal Approximation Theorem (Cybenko, 1989): 1 hidden layer với đủ neurons xấp xỉ được bất kỳ hàm liên tục nào; Deep NN (nhiều tầng) học biểu diễn phân cấp. Forward pass tại lớp l: z[l] = W[l]·a[l-1] + b[l], rồi a[l] = σ(z[l]) — chỉ tính toán, chưa học gì. Kiểm tra kích thước ma trận là kỹ năng debug số 1: W[l] có shape (n[l], n[l-1]), b[l] là (n[l], 1). Lưu cache (z[l], a[l]) để dùng lại trong backprop.

Forward pass — mạng [2, 16, 1]Python
import numpy as np

def forward(X, params):
    Z1 = params['W1'] @ X + params['b1']   # (16,2)@(2,m)=(16,m)
    A1 = np.tanh(Z1)                        # hidden: tanh
    Z2 = params['W2'] @ A1 + params['b2']  # (1,16)@(16,m)=(1,m)
    A2 = 1 / (1 + np.exp(-Z2))             # output: sigmoid
    return A2, (Z1, A1, Z2, A2)            # cache cho backprop

Activation Functions

Sigmoid σ(z)=1/(1+e⁻ᶻ), range (0,1), diễn giải như xác suất — dùng ở output layer nhị phân, nhưng vanishing gradient khi |z| lớn. Tanh, range (−1,1), zero-centered tốt hơn Sigmoid nhưng vẫn vanishing. ReLU(z)=max(0,z), range [0,+∞) — nhanh, ít vanishing gradient, là mặc định cho hidden layer hiện nay, nhưng có thể "dying ReLU" khi z<0 mãi. Softmax σ(zᵢ)=eᶻⁱ/Σeᶻʲ, tổng=1 — chỉ dùng ở output layer cho phân loại đa lớp. Cơ chế On/Off của ReLU: mỗi input kích hoạt một tập con neurons khác nhau → mạng học các "chuyên gia" cho từng vùng dữ liệu.

Hàm Mất Mát & Gradient Descent

Ba hàm mất mát: MSE = (1/m)Σ(y−ŷ)² cho hồi quy (phạt sai số bình phương, nhạy outlier); Binary Cross-Entropy cho phân loại nhị phân (nguồn gốc từ MLE, kết hợp với Sigmoid); Categorical Cross-Entropy cho đa lớp (kết hợp với Softmax, y one-hot). Gradient Descent cập nhật: θ ← θ − η·∇θL, với η là learning rate ("bước đi"). η quá nhỏ hội tụ chậm, kẹt local minimum; η quá lớn dao động, weights phát nổ; η vừa phải thường trong [0.001, 0.1]. Biến thể Mini-batch GD (batch 32–256, lũy thừa của 2 để tận dụng GPU) là chuẩn thực tế.

Optimizers Nâng Cao

SGD cơ bản dễ dao động. Momentum tích lũy "quán tính": v ← βv + (1−β)∇L; θ ← θ − η·v — vượt saddle points nhanh hơn. RMSprop điều chỉnh learning rate theo từng tham số: s ← βs + (1−β)(∇L)²; θ ← θ − η·∇L/√(s+ε) — tốt cho dữ liệu non-stationary. Adam (mặc định) kết hợp Momentum + RMSprop, là lựa chọn cho hầu hết bài toán (biến thể: AdamW, AMSGrad). LR Schedule (step decay, cosine annealing, warm-up) giảm η theo epoch: học nhanh lúc đầu, tinh chỉnh chậm ở cuối.

Backpropagation — 4 Phương Trình Cốt Lõi

Để cập nhật W[l] cần ∂L/∂W[l], nhưng W[l] không ảnh hưởng trực tiếp đến L. Giải pháp là Chain Rule theo chuỗi phụ thuộc W[l]→z[l]→a[l]→…→L. Định nghĩa error signal δ[l] = ∂L/∂z[l], ta có 4 phương trình: BP1: δ[L] = ∇ₐL ⊙ σ′(z[L]) (error tại output); BP2: δ[l] = (W[l+1])ᵀ·δ[l+1] ⊙ σ′(z[l]) (truyền ngược); BP3: ∂L/∂W[l] = δ[l]·(a[l-1])ᵀ (gradient weight); BP4: ∂L/∂b[l] = δ[l] (gradient bias). Backprop tính gradient cho TẤT CẢ layers chỉ trong 1 forward + 1 backward pass.

Backprop — 4 phương trình (NumPy)Python
def backward(X, y, params, cache):
    m = X.shape[1]
    Z1, A1, Z2, A2 = cache
    dZ2 = A2 - y                              # BP1: BCE+Sigmoid → đơn giản!
    dW2 = (1/m) * dZ2 @ A1.T                  # BP3
    db2 = (1/m) * np.sum(dZ2, axis=1, keepdims=True)  # BP4
    dZ1 = params['W2'].T @ dZ2 * (1 - A1**2)  # BP2: đạo hàm tanh
    dW1 = (1/m) * dZ1 @ X.T                    # BP3
    db1 = (1/m) * np.sum(dZ1, axis=1, keepdims=True)  # BP4
    return {'dW1':dW1, 'db1':db1, 'dW2':dW2, 'db2':db2}

Vanishing Gradient, Khởi Tạo & Batch Norm

Vanishing Gradient: Sigmoid/Tanh có σ′(z) ≤ 0.25, nhân qua L layers → (0.25)ᴸ → 0, khiến lớp đầu không học được gì. Khắc phục: dùng ReLU, Batch Normalization, Residual connections (ResNet), khởi tạo He/Xavier. Exploding Gradient: gradient tăng cấp số nhân, weights → ∞, Loss = NaN — khắc phục bằng Gradient Clipping, khởi tạo weights nhỏ, giảm learning rate. Khởi tạo tham số: Xavier/Glorot W ~ N(0, 2/(n[l-1]+n[l])) cho Sigmoid/Tanh; He W ~ N(0, 2/n[l-1]) cho ReLU. Batch Normalization chuẩn hóa z[l] theo mini-batch, giảm internal covariate shift, cho phép learning rate lớn hơn và có tác dụng regularization nhẹ.

He init + BatchNorm (Keras)Python
from tensorflow.keras.layers import Dense, BatchNormalization

# He initialization cho ReLU + Batch Normalization
model.add(Dense(64, activation='relu', kernel_initializer='he_normal'))
model.add(BatchNormalization())  # thêm sau Dense, giảm vanishing gradient
# Quy trình: (1) Overfit trước — chứng minh đủ capacity
#            (2) Rồi thêm regularization (L2, Dropout, Early Stopping)