AI Cho Mọi Người

AI Cho Mọi Người

Multi-layer Perceptron (MLP)

 

 

Trong bài học này, chúng ta sẽ học về multi-layer perceptron (MLP). Điểm khác biệt của MLP so với softmax regression ở bài học trước là MLP xử dụng thêm các lớp (chứa các node), gọi là hidden layer. Việc thêm các hidden layer giúp cho mô hình phân loại tăng khả năng học từ các bộ dữ liệu phức tạp.

 

MLP có cấu trúc như sau

Số lượng hidden layer và số node trong mỗi hidden layer là tùy ý. Với bài toán classification, các bước tính toán ở output layer giống với phương pháp softmax regression. Điểm khác biệt của MLP nằm ở việc tính toán trong các hidden layer. Các node trong hidden layer bao gồm 2 bước tính

    1. Tính inner product, tương tự như trong linear regression
    2. Dùng hàm activation, ví dụ như hàm ReLU

Phần sau chúng ta sẽ áp dụng MLP cho bài toán phân loại hoa Iris và so sánh với phương pháp softmax regression.

Bài tập: Dựa vào các công thức tính trong linear regression, logistic regression và softmax regression, các bạn hãy xây dựng công thức tính forward và backward cho MLP.

 

Áp dụng MLP cho bài toán phân loại hoa Iris

Chúng ta sẽ thiết lập điều kiện dữ liệu giống như bài trước để so sánh kết quả giữa 2 phương pháp Chúng ta sẽ dùng MLP với 1 hidden layer chứa 50 node, và dùng hàm activation ReLU.

Đầu tiên, chúng ta đọc dữ liệu và chuẩn hóa như sau

import numpy as np
import matplotlib.pyplot as plt
from sklearn import preprocessing

iris = np.genfromtxt('iris_full.csv', dtype=None, delimiter=',', skip_header=1) 
X = iris[:, 2:4]
y = iris[:, 4]

X = preprocessing.scale(X)
y = y.astype('uint8')

plt.figure(figsize=(10, 6))
plt.scatter(X[y == 0][:, 0], X[y == 0][:, 1], color='b', label='0')
plt.scatter(X[y == 1][:, 0], X[y == 1][:, 1], color='r', label='1')
plt.scatter(X[y == 2][:, 0], X[y == 2][:, 1], color='g', label='2')
plt.legend()

 

Sau đó, chúng ta khởi tạo các tham số và huấn luyện MLP với 20000 epoch. Giá trị loss được lưu sau mỗi 100 epoch. Source code để huấn luyện MLP như sau

N = 50 # number of points per class
D = 2 # dimensionality
K = 3 # number of classes

# initialize parameters randomly
h = 50 # size of hidden layer
W = 0.01 * np.random.randn(D,h)
b = np.zeros((1,h))
W2 = 0.01 * np.random.randn(h,K)
b2 = np.zeros((1,K))

# gradient descent loop
num_examples = X.shape[0]
learning_rate = 0.9

losses = []
for i in range(20000):  
    # evaluate class scores, [N x K]
    hidden_layer = np.maximum(0, np.dot(X, W) + b) # ReLU activation
    scores = np.dot(hidden_layer, W2) + b2

    # compute the class probabilities
    exp_scores = np.exp(scores)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True) # [N x K]

    # compute the loss: average cross-entropy loss and regularization
    corect_logprobs = -np.log(probs[range(num_examples),y])
    loss = np.sum(corect_logprobs)/num_examples
    if i % 100 == 0:
        losses.append(loss)

    # compute the gradient on scores
    dscores = probs
    dscores[range(num_examples),y] -= 1
    dscores /= num_examples

    # backpropate the gradient to the parameters
    # first backprop into parameters W2 and b2
    dW2 = np.dot(hidden_layer.T, dscores)
    db2 = np.sum(dscores, axis=0, keepdims=True)
    
    # next backprop into hidden layer
    dhidden = np.dot(dscores, W2.T)
    
    # backprop the ReLU non-linearity
    dhidden[hidden_layer <= 0] = 0
    
    # finally into W,b
    dW = np.dot(X.T, dhidden)
    db = np.sum(dhidden, axis=0, keepdims=True)    

    # perform a parameter update
    W += -learning_rate * dW
    b += -learning_rate * db
    W2 += -learning_rate * dW2
    b2 += -learning_rate * db2

Ở đây learning_rate được gán bằng 0.9. Hình sau thể hiện giá trị loss trong quá trình huấn luyện.

Chúng ta tính độ chính xác của MLP sau khi huấn luyện như sau

và hiển thị miền phân loại.

h = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                     np.arange(y_min, y_max, h))
Z = np.dot(np.maximum(0, np.dot(np.c_[xx.ravel(), yy.ravel()], W) + b), W2) + b2
Z = np.argmax(Z, axis=1)
Z = Z.reshape(xx.shape)

fig = plt.figure()
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral, alpha=0.8)
plt.scatter(X[:, 0], X[:, 1], c=y, s=40, cmap=plt.cm.Spectral)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())

 

Chúng ta thấy rằng MLP có độ chính xác tốt hơn softmax regression (95%). Điều này chứng tỏ rằng MLP có khả năng học tốt hơn softmax regression.

Chú ý là chúng ta chỉ khẳng định MLP học tốt hơn softmax regression, và điều này không có nghĩa ra MLP tốt hơn softmax regression trong mọi trường hợp. Với những bài toán đơn giản, dùng MLP dễ gặp phải vấn đề overfitting (sẽ học trong bài tới).