Training accuracy của Neural Network chỉ đạt 80%

Chào mọi người, em có làm một cái neural network bằng python nhưng không biết tại sao training accuracy của nó chỉ có 80 %, trong khi em implement bằng matlab thì nó lên đến 95 %. Em đã kiểm tra các phép toán kỹ rồi nhưng vẫn không biết vấn đề nằm ở đâu, nhờ mọi người xem giúp em với ạ!!

# sigmoid function
def sigmoid(z):
    return 1 / (1 + np.exp(-z))
# sigmoid gradient
def sigmoidGradient(z):
    sm = sigmoid(z)
    return sm * (1 - sm)

# random initialization
def randInitializeWeights(L_in, L_out):
    epsilon_init = 0.12
    return np.random.rand(L_out, L_in + 1) * 2 * epsilon_init - epsilon_init

# Neural networks cost function, nn_params is all theta of input layer and hidden layer unrolled
def nnCostFunction(nn_params, input_layer_size, hidden_layer_size, num_labels, X, y, lam):
    
    # rolled parameters
    Theta_1 = nn_params[: hidden_layer_size * (input_layer_size + 1)].reshape((hidden_layer_size, input_layer_size + 1))
    Theta_2 = nn_params[hidden_layer_size * (input_layer_size + 1) : ].reshape((num_labels, hidden_layer_size + 1))
    m = len(X)
    
    y_b = np.zeros((m, num_labels))
    for i in range(m):
        y_b[i, int(y[i])] = 1
        
    # forward propagation
    X_0 = np.concatenate((np.ones((m, 1)), X), axis = 1)
    
    z_1 = X_0.dot(Theta_1.T)
    a_1 = sigmoid(z_1)
    
    a_1 = np.concatenate((np.ones((m, 1)), a_1), axis = 1)
    
    z_2 = a_1.dot(Theta_2.T)
    a_2 = sigmoid(z_2)
    
    # regularized cost function
    J = np.sum(- y_b * np.log(a_2) - (1 - y_b) * np.log(1 - a_2)) / m
    J = J + lam * (np.sum(Theta_1[:, 1:] ** 2) + np.sum(Theta_2[:, 1:] ** 2)) / (2 * m)
    
    return J

# neural networks gradient
def nnGradient(nn_params, input_layer_size, hidden_layer_size, num_labels, X, y, lam):
    
    # rolled parameters
    Theta_1 = nn_params[: hidden_layer_size * (input_layer_size + 1)].reshape((hidden_layer_size, input_layer_size + 1))
    Theta_2 = nn_params[hidden_layer_size * (input_layer_size + 1) : ].reshape((num_labels, hidden_layer_size + 1))
    m = len(X)
    
    y_b = np.zeros((m, num_labels))
    
    Theta_1_grad = np.zeros(Theta_1.shape)
    Theta_2_grad = np.zeros(Theta_2.shape)
    
    for i in range(m):
        y_b[i, int(y[i])] = 1
        
    # forward propagation
    X_0 = np.concatenate((np.ones((m, 1)), X), axis = 1)
    
    z_1 = X_0.dot(Theta_1.T)
    a_1 = sigmoid(z_1)
    
    a_1 = np.concatenate((np.ones((m, 1)), a_1), axis = 1)
    
    z_2 = a_1.dot(Theta_2.T)
    a_2 = sigmoid(z_2)
    
    # backpropagation
    delta_2 = a_2 - y_b
    
    delta_1 = delta_2.dot(Theta_2) * sigmoidGradient(np.concatenate((np.ones((m, 1)), z_1), axis = 1))
    delta_1 = delta_1[:, 1:]
    
    Theta_2_grad = Theta_2_grad + delta_2.T.dot(a_1)
    Theta_1_grad = Theta_1_grad + delta_1.T.dot(X_0)
    
    # regularized gradient
    Theta_1[:, 0] = 0
    Theta_2[:, 0] = 0
    Theta_1_grad = Theta_1_grad / m + lam * Theta_1 / m
    Theta_2_grad = Theta_2_grad / m + lam * Theta_2 / m
    
    # unrolled gradient
    return np.concatenate((Theta_1_grad.flatten(), Theta_2_grad.flatten()))


def predictNeuralNetwork(nn_params, input_layer_size, hidden_layer_size, num_labels, X):
    Theta_1 = nn_params[:hidden_layer_size * (input_layer_size + 1)].reshape((hidden_layer_size, input_layer_size + 1))
    Theta_2 = nn_params[hidden_layer_size * (input_layer_size + 1):].reshape((num_labels, hidden_layer_size + 1))
    
    X = np.concatenate((np.ones((len(X), 1)), X), axis = 1)
    
    z_1 = X.dot(Theta_1.T)
    a_1 = sigmoid(z_1)
    
    a_1 = np.concatenate((np.ones((len(X), 1)), a_1), axis = 1)
    
    z_2 = a_1.dot(Theta_2.T)
    a_2 = sigmoid(z_2)
    
    return np.argmax(a_2, axis = 1)

def trainingAccuracyNn(nn_params, input_layer_size, hidden_layer_size, num_labels, X, y):
    return np.mean(predictNeuralNetwork(nn_params, input_layer_size, hidden_layer_size, num_labels, X) == y) * 100

input_layer_size, hidden_layer_size, num_labels, lam = 784, 25, 10, 1
initial_Theta_1 = randInitializeWeights(input_layer_size, hidden_layer_size)
initial_Theta_2 = randInitializeWeights(hidden_layer_size, num_labels)
initial_nn_params = np.concatenate((initial_Theta_1.flatten(), initial_Theta_2.flatten()))

# measure training time
start_time = time.time()

# train model
result = op.minimize(fun = nnCostFunction, x0 = initial_nn_params, \
    args = (input_layer_size, hidden_layer_size, num_labels, X, y, lam), method = 'CG', jac = nnGradient, options={'maxiter':50})
print('-------------------------------------')
print('Training time: %s' % (time.time() - start_time), 's')
print('-------------------------------------')
print(result)
all_theta = result.x

trainingAccuracyNn(all_theta, input_layer_size, hidden_layer_size, num_labels, X, y)

Đây là kết quả:


Sau 50 vòng lặp, nó vẫn chưa hội tụ !!
Bài toán training các chữ số viết tay có kích thước 10000x784, mỗi mẫu có kích thước 28x28. Mạng neural có input_layer_size: 784, 1 hidden_layer_size: 25, num_labels: 10.
Ma trận X có kích thước 10000x784, ma trận y có kích thước (10000,) chứa nhãn tương ứng của các mẫu.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?