import numpy as np # --- 1. Dữ liệu XOR gate --- X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) y = np.array([[0], [1], [1], [0]]) # output XOR # --- 2. Hàm sigmoid & derivative --- def sigmoid(x): return 1 / (1 + np.exp(-x)) def sigmoid_derivative(x): return x * (1 - x) # --- 3. Khởi tạo weights & bias --- np.random.seed(42) input_dim = 2 hidden_dim = 2 # thử đổi thành 3, 4, 5... ''' Ảnh hưởng: 2 neurons: học XOR ổn 1 neuron: không học được 2 neurons: học nhanh hơn, loss giảm mạnh 👉 Đây là chỗ dễ thấy sự thay đổi nhất. ''' output_dim = 1 lr = 0.5 # thử 0.1, 1.0, 2.0 ''' Ảnh hưởng: lr nhỏ → học chậm, mượt lr lớn → lúc học rất nhanh, lúc bị “nhảy loạn”, dễ diverge 👉 Thay đổi learning rate luôn thấy kết quả khác. ''' epochs = 10000 # thử 3000, 50000 ''' Ảnh hưởng: ít epoch → chưa học hết, dự đoán sai nhiều epoch → XOR học hoàn hảo hơn ''' # weights: input -> hidden w1 = np.random.randn(input_dim, hidden_dim) # Có thể thử nhân thêm weight với 0.1 hoặc 0.001 ''' Hiệu ứng: khi nhân với 0.1 Train rất mượt Loss giảm đều Tốc độ học nhanh Đây là “sweet spot”. Hiệu ứng: khi nhân với 0.001 Activation gần 0 → mô hình học chậm Loss giảm nhưng rất từ từ ''' b1 = np.zeros((1, hidden_dim)) # weights: hidden -> output w2 = np.random.randn(hidden_dim, output_dim) b2 = np.zeros((1, output_dim)) # Có thể thử Bias random: b1 = np.random.randn((1, output_dim)) ''' Hiệu ứng CÓ THỂ THẤY RÕ: Decision boundary bắt đầu lệch → học XOR nhanh hơn Loss giảm nhanh từ những bước đầu tiên Output có thể ra đúng từ rất sớm (epoch 10–20) ''' # --- 4. Huấn luyện bằng Backpropagation --- for epoch in range(epochs): # Forward pass z1 = np.dot(X, w1) + b1 h = sigmoid(z1) z2 = np.dot(h, w2) + b2 y_pred = sigmoid(z2) # Tính lỗi error = y - y_pred # Backward pass d_y_pred = error * sigmoid_derivative(y_pred) d_h = d_y_pred.dot(w2.T) * sigmoid_derivative(h) # Cập nhật weights & bias w2 += h.T.dot(d_y_pred) * lr b2 += np.sum(d_y_pred, axis=0, keepdims=True) * lr w1 += X.T.dot(d_h) * lr b1 += np.sum(d_h, axis=0, keepdims=True) * lr # --- 5. Test MLP --- print("Testing trained MLP:") z1 = np.dot(X, w1) + b1 h = sigmoid(z1) z2 = np.dot(h, w2) + b2 y_pred = sigmoid(z2) print(np.round(y_pred)) ''' ✅ Tóm tắt học thuật: | Tiêu chí | Single Layer Perceptron (SLP) | Multi-Layer Perceptron (MLP) | | ------------------------- | ------------------------------------- | ---------------------------------------------------------------------- | | **Số lớp** | 1 lớp (input → output) | Nhiều lớp (input → hidden → output) | | **Hàm học** | Tuyến tính | Phi tuyến tính (nhờ lớp ẩn và activation) | | **Hàm kích hoạt** | Step function | Sigmoid, ReLU, Tanh hoặc các hàm phi tuyến khác | | **Khả năng học XOR** | Không | Có | | **Thuật toán huấn luyện** | Perceptron learning rule | Backpropagation + gradient descent | | **Ứng dụng** | Phân loại tuyến tính cơ bản (AND, OR) | Classification, regression, nhận dạng hình ảnh, NLP, dữ liệu phi tuyến | | **Ưu điểm** | Đơn giản, dễ hiểu | Học được phi tuyến, khả năng biểu diễn cao | | **Hạn chế** | Chỉ học tuyến tính | Dễ overfitting, cần tuning hyperparameters, tốn tài nguyên | ''' ''' Epoch không phải là weight hay bias, nhưng về thuật toán học, nó được coi là hyperparameter. Hyperparameter = tham số do người đặt trước khi huấn luyện (khác với parameter là giá trị học được từ dữ liệu). Các hyperparameters phổ biến: Learning rate (𝜂) Batch size Số epoch Số lớp ẩn, số neuron Hàm kích hoạt Như vậy: Epoch → hyperparameter, ảnh hưởng trực tiếp đến quá trình huấn luyện. 3. Epoch ảnh hưởng đến quá trình học như thế nào Quá ít epoch → underfitting, model chưa học đủ. Quá nhiều epoch → overfitting, model nhớ dữ liệu training quá mức, generalization kém. Kết hợp với learning rate → số epoch quyết định model có hội tụ hay không. 4. Kết luận Epoch là hyperparameter, nhưng nó không phải parameter học được từ dữ liệu. Chọn epoch phù hợp = một phần quan trọng trong tuning hyperparameters để đạt hiệu quả tối ưu. '''