機器學習之邏輯迴歸多分類:手寫數字識別

機器學習之邏輯迴歸多分類:手寫數字識別

  • 簡述
  • 手寫數字展示
  • sigmoid函數
  • 代價函數與梯度下降
  • 多分類訓練
  • 多分類結果預測
  • 邏輯迴歸之多分類

簡述

  • 上一篇已經詳細記錄了邏輯迴歸用於二分類的問題,本篇將用邏輯迴歸實現多分類,如手寫數字的識別。
  • 本篇使用octave進行學習。
機器學習之邏輯迴歸多分類:手寫數字識別

手寫數字展示

手寫數字的數據:ex3data1.mat(https://github.com/peedeep/Coursera/blob/master/ex3/ex3data1.mat)此處可下載,是一個(m*n) m=5000, n=400矩陣數據,m表示訓練數據樣本數,n表示每個數據的特徵維度。且提供了displayData.m 函數來對訓練數據中隨機10*10=100張手寫數字顯示,octave/matlab中執行下面代碼即可:

%% =========== 1.Loading and Visualizing Data =============
%% 隨機畫出100個樣本
input_layer_size = 400;
num_labels = 10;
load('ex3data1.mat');
m = size(X, 1);
rand_indices = randperm(m);
sel = X(rand_indices(1:100), :);
displayData(sel);
fprintf('Program paused. Press enter to continue.\\n');
pause;
機器學習之邏輯迴歸多分類:手寫數字識別

sigmoid函數

sigmoid.m 函數將所有實數映射到(0, 1)範圍。

機器學習之邏輯迴歸多分類:手寫數字識別

機器學習之邏輯迴歸多分類:手寫數字識別

%% Sigmoid function
function g = sigmoid(z)
g = zeros(size(z));
g = 1.0 ./ (1.0 + exp(-z));
endfunction

代價函數與梯度下降

機器學習之邏輯迴歸多分類:手寫數字識別

機器學習之邏輯迴歸多分類:手寫數字識別

機器學習之邏輯迴歸多分類:手寫數字識別

機器學習之邏輯迴歸多分類:手寫數字識別

lrCostFunction.m用來計算邏輯迴歸代價函數及梯度下降。

%% Logistic regression cost function
function [J, gradient] = lrCostFunction (X, y, theta, lambda)
m = length(y);
J = 0;
gradient = zeros(size(theta));
theta_temp = [0; theta(2:end)]; %theta(1) 不參與正則化,所以取零
J = -1 * sum(y .* log(sigmoid(X * theta)) + (1 - y) .* log(1 - sigmoid(X * theta))) / m + lambda * (theta_temp' * theta_temp) / (2 * m);
gradient = (X' * (sigmoid(X * theta) - y)) / m + lambda / m * theta_temp;
gradient = gradient(:); %展開
endfunction

以下代碼用於檢驗代價函數及梯度下降是否到達預期效果。

%% =========== 2.Vectorize Logistic Regression =============
fprintf('\\nTesting lrCostFunction() with regularization');
theta_t = [-2; -1; 1; 2];
X_t = [ones(5,1) reshape(1:15,5,3)/10];
y_t = ([1;0;1;0;1] >= 0.5);
lambda_t = 3;
[J grad] = lrCostFunction(X_t, y_t, theta_t, lambda_t);
fprintf('\\nCost: %f\\n', J);
fprintf('Expected cost: 2.534819\\n');
fprintf('Gradients:\\n');
fprintf(' %f \\n', grad);
fprintf('Expected gradients:\\n');
fprintf(' 0.146561\\n -0.548558\\n 0.724722\\n 1.398003\\n');
fprintf('Program paused. Press enter to continue.\\n');
pause;

多分類訓練

oneVsAll.m用於學習多分類(此處假定有K個類別)的

θ 值,手寫數字有0-9,那麼K = 10,該函數迭代K次完成了多分類的計算,這裡將用求最優函數fmincg來代替上一篇的fminuncfmincgfminunc很相似,但是對於大量數據的處理更加有效。

%% Train a one-vs-all multi-class classifier
function [theta] = oneVsAll(X, y, num_labels, lambda)
m = size(X, 1);
n = size(X, 2);
theta = zeros(num_labels, n+1);
X = [ones(m, 1) X];
options = optimset('GradObj', 'on', 'MaxIter', 50);
initial_theta = zeros(n + 1, 1);
for k = 1 : num_labels
theta(k, :) = fmincg(@(t)(lrCostFunction(X, (y == k), t, lambda)), initial_theta, options);
end
endfunction

用上述函數進行訓練求出θ 值,此時θK*(n+1)矩陣:

%% =========== 3.Training One-vs-All Logistic Regression =============
fprintf('\\nTraining One-vs-All Logistic Regression...\\n')
lambda = 0.1;

[theta] = oneVsAll(X, y, num_labels, lambda);
fprintf('size of theta: %d \\n', size(theta));
fprintf('Program paused. Press enter to continue.\\n');
pause;

多分類結果預測

predictOneVsAll.m 用於對輸入數據進行預測,預測值最大的即為正確的分類。

%% Predict using a one-vs-all multi-class classifier
function p = predictOneVsAll(X, theta)
m = size(X, 1);
k = size(theta, 1);
p = zeros(m, 1);
X = [ones(m, 1) X];
[a, p] = max(sigmoid(X * theta'), [], 2);
endfunction

結果預測,準確率達到94.96%!

%% ============ 4.Predict for One-Vs-All ============
pred = predictOneVsAll(X, theta);
fprintf('predict size of pred:%d \\n', size(pred));
fprintf('\\nTraining Set Accuracy: %f\\n', mean(double(pred == y)) * 100);


分享到:


相關文章: