Andrew NG 機器學習編程作業3 Octave


問題描述:使用邏輯回歸(logistic regression)和神經網絡(neural networks)識別手寫的阿拉伯數字(0-9)

一、邏輯回歸實現:

數據加載到octave中,如下圖所示:

①樣本數據的可視化

隨機選擇100個樣本數據,使用Octave可視化的結果如下:

②使用邏輯回歸來實現多分類問題(one-vs-all)

所謂多分類問題,是指分類的結果為三類以上。比如,預測明天的天氣結果為三類:晴(用y==1表示)、陰(用y==2表示)、雨(用y==3表示)

分類的思想,其實與邏輯回歸分類(默認是指二分類,binary classification)很相似,對“晴天”進行分類時,將另外兩類(陰天和下雨)視為一類:(非晴天),這樣,就把一個多分類問題轉化成了二分類問題。示意圖如下:(圖中的圓圈 表示:不屬於某一類的 所有其他類)

對於N分類問題(N>=3),就需要N個假設函數(預測模型),也即需要N組模型參數θ(θ一般是一個向量)

然后,對於每個樣本實例,依次使用每個模型預測輸出,選取輸出值最大的那組模型所對應的預測結果作為最終結果。

因為模型的輸出值,在sigmoid函數作用下,其實是一個概率值。,注意:hθ(1)(x),hθ(2)(x),hθ(3)(x)三組 模型參數θ 一般是不同的。比如:

hθ(1)(x),輸出 預測為晴天(y==1)的概率

hθ(2)(x),輸出 預測為陰天(y==2)的概率

hθ(3)(x),輸出 預測為雨天(y==3)的概率

 

③Octave代碼實現 

對於上面的識別阿拉伯數字的問題,一共需要訓練出10個邏輯回歸模型,每個邏輯回歸模型對應着識別其中一個數字。

我們一共有5000個樣本,樣本的預測結果值就是:y=(1,2,3,4,5,6,7,8,9,10),其中 10 代表 數字0

我們使用fmincg庫函數 來求解使得代價函數取最小值的 模型參數θ

function [all_theta] = oneVsAll(X, y, num_labels, lambda)
%ONEVSALL trains multiple logistic regression classifiers and returns all
%the classifiers in a matrix all_theta, where the i-th row of all_theta 
%corresponds to the classifier for label i
%   [all_theta] = ONEVSALL(X, y, num_labels, lambda) trains num_labels
%   logistic regression classifiers and returns each of these classifiers
%   in a matrix all_theta, where the i-th row of all_theta corresponds 
%   to the classifier for label i

% Some useful variables
m = size(X, 1);
n = size(X, 2);

% You need to return the following variables correctly 
all_theta = zeros(num_labels, n + 1);

% Add ones to the X data matrix
X = [ones(m, 1) X];

% ====================== YOUR CODE HERE ======================
% Instructions: You should complete the following code to train num_labels
%               logistic regression classifiers with regularization
%               parameter lambda. 
%
% Hint: theta(:) will return a column vector.
%
% Hint: You can use y == c to obtain a vector of 1's and 0's that tell you
%       whether the ground truth is true/false for this class.
%
% Note: For this assignment, we recommend using fmincg to optimize the cost
%       function. It is okay to use a for-loop (for c = 1:num_labels) to
%       loop over the different classes.
%
%       fmincg works similarly to fminunc, but is more efficient when we
%       are dealing with large number of parameters.
%
% Example Code for fmincg:
%
%     % Set Initial theta
%     initial_theta = zeros(n + 1, 1);
%     
%     % Set options for fminunc
%     options = optimset('GradObj', 'on', 'MaxIter', 50);
% 
%     % Run fmincg to obtain the optimal theta
%     % This function will return theta and the cost 
%     [theta] = ...
%         fmincg (@(t)(lrCostFunction(t, X, (y == c), lambda)), ...
%                 initial_theta, options);
%


initial_theta = zeros(n + 1, 1);

options = optimset('GradObj','on','MaxIter',50);

for c = 1:num_labels %num_labels 為邏輯回歸訓練器的個數,num of logistic regression classifiers
all_theta(c, :) = fmincg(@(t)(lrCostFunction(t, X, (y == c),lambda)), initial_theta,options );
end









% =========================================================================


end
function [J, grad] = lrCostFunction(theta, X, y, lambda)
%LRCOSTFUNCTION Compute cost and gradient for logistic regression with 
%regularization
%   J = LRCOSTFUNCTION(theta, X, y, lambda) computes the cost of using
%   theta as the parameter for regularized logistic regression and the
%   gradient of the cost w.r.t. to the parameters. 

% Initialize some useful values
m = length(y); % number of training examples

% You need to return the following variables correctly 
J = 0;
grad = zeros(size(theta));

% ====================== YOUR CODE HERE ======================
% Instructions: Compute the cost of a particular choice of theta.
%               You should set J to the cost.
%               Compute the partial derivatives and set grad to the partial
%               derivatives of the cost w.r.t. each parameter in theta
%
% Hint: The computation of the cost function and gradients can be
%       efficiently vectorized. For example, consider the computation
%
%           sigmoid(X * theta)
%
%       Each row of the resulting matrix will contain the value of the
%       prediction for that example. You can make use of this to vectorize
%       the cost function and gradient computations. 
%
% Hint: When computing the gradient of the regularized cost function, 
%       there're many possible vectorized solutions, but one solution
%       looks like:
%           grad = (unregularized gradient for logistic regression)
%           temp = theta; 
%           temp(1) = 0;   % because we don't add anything for j = 0  
%           grad = grad + YOUR_CODE_HERE (using the temp variable)
%

J = ( log( sigmoid(theta'*X') ) * y + log( 1-sigmoid(theta'*X') ) * (1 - y) )/(-m) + (lambda / (2*m)) * ( ( theta( 2:length(theta) ) )' * theta(2:length(theta)) );

grad = ( X' * ( sigmoid(X*theta)-y ) )/m + ( lambda / m ) * ( [0; ones( length(theta) - 1 , 1 )].*theta );








% =============================================================

grad = grad(:);

end

 

下面來解釋一下 for循環:

num_labels 為分類器個數,共10個,每個分類器(模型)用來識別10個數字中的某一個。

我們一共有5000個樣本,每個樣本有400中特征變量,因此:模型參數θ 向量有401個元素。

initial_theta = zeros(n + 1, 1); % 模型參數θ的初始值(n == 400)

all_theta是一個10*401的矩陣,每一行存儲着一個分類器(模型)的模型參數θ 向量,執行上面for循環,就調用fmincg庫函數 求出了 所有模型的參數θ 向量了。

求出了每個模型的參數向量θ,就可以用 訓練好的模型來識別數字了。對於一個給定的數字輸入(400個 feature variables) input instance,每個模型的假設函數hθ(i)(x) 輸出一個值(i = 1,2,...10)。取這10個值中最大值那個值,作為最終的識別結果。比如g(hθ(8)(x))==0.96 比其它所有的 g(hθ(i)(x)) (i = 1,2,...10,但 i 不等於8) 都大,則識別的結果為 數字 8

 

function p = predictOneVsAll(all_theta, X)
%PREDICT Predict the label for a trained one-vs-all classifier. The labels 
%are in the range 1..K, where K = size(all_theta, 1). 
%  p = PREDICTONEVSALL(all_theta, X) will return a vector of predictions
%  for each example in the matrix X. Note that X contains the examples in
%  rows. all_theta is a matrix where the i-th row is a trained logistic
%  regression theta vector for the i-th class. You should set p to a vector
%  of values from 1..K (e.g., p = [1; 3; 1; 2] predicts classes 1, 3, 1, 2
%  for 4 examples) 

m = size(X, 1);
num_labels = size(all_theta, 1);

% You need to return the following variables correctly 
p = zeros(size(X, 1), 1);

% Add ones to the X data matrix
X = [ones(m, 1) X];

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned logistic regression parameters (one-vs-all).
%               You should set p to a vector of predictions (from 1 to
%               num_labels).
%
% Hint: This code can be done all vectorized using the max function.
%       In particular, the max function can also return the index of the 
%       max element, for more information see 'help max'. If your examples 
%       are in rows, then, you can use max(A, [], 2) to obtain the max 
%       for each row.
%       





[~,p] = max( X * all_theta',[],2); % 求矩陣(X*all_theta')每行的最大值,p 記錄矩陣每行的最大值的索引

% =========================================================================


end

二、神經網絡實現

由於邏輯回歸是線性分類(它的假設函數是一個線性函數,就是划一條直線,把數據分成了兩類。

對於一些復雜的類別,邏輯回歸就解決不了了。比如下面這個圖片中的分類。(無法通過 划直線 將 叉叉 和 圓圈 分開)

 

而神經網絡,則能夠實現很復雜的非線性分類問題。

對於神經網絡而言,同樣有一個訓練樣本矩陣 X,同時還有一個模型參數 Theta 矩陣,通過某種算法將 模型參數矩陣 訓練好之后(求出 Theta 矩陣),再使用前向傳播算法( feedforward propagation algorithm)(感覺就像是矩陣相乘嘛), 就可以對輸入的測試樣本進行預測了。

本作業中, 模型參數 Theta 矩陣是已經訓練好了的,直接 load 即可。如下所示:

function p = predict(Theta1, Theta2, X)
%PREDICT Predict the label of an input given a trained neural network
%   p = PREDICT(Theta1, Theta2, X) outputs the predicted label of X given the
%   trained weights of a neural network (Theta1, Theta2)

% Useful values
m = size(X, 1);
num_labels = size(Theta2, 1);

% You need to return the following variables correctly 
p = zeros(size(X, 1), 1);

% ====================== YOUR CODE HERE ======================
% Instructions: Complete the following code to make predictions using
%               your learned neural network. You should set p to a 
%               vector containing labels between 1 to num_labels.
%
% Hint: The max function might come in useful. In particular, the max
%       function can also return the index of the max element, for more
%       information see 'help max'. If your examples are in rows, then, you
%       can use max(A, [], 2) to obtain the max for each row.
%



% 模擬實現前向傳播算法
X = [ones(m, 1) X];
a_super_2 = sigmoid(Theta1 * X');
a_super_2 = [ones(1,m); a_super_2];% add bias unit
a_super_3 = sigmoid(Theta2 * a_super_2);
%==================================
[~,p] = max( a_super_3' ,[], 2 ); % 對樣本的結果進行預測,與邏輯回歸的預測類似,選取輸出的最大值 作為最終的預測結果





% =========================================================================


end

 注意:我們正是通過 max 函數,求得矩陣 a_super3 每一行的最大值。將每一行的中的最大值 的索引 賦值給向量p。其中,a_super3 是一個5000行乘10列的矩陣 

向量p就是預測的結果向量。而由於 a_super3 有10列,故 p 中每個元素的取值范圍為[1,10],即分別代表了數字 0-9(其中10 表示 0)

測試代碼如下:

 rp = randperm(m);
>>
>> for i = 1:m
    % Display
    fprintf('\nDisplaying Example Image\n');
    displayData(X(rp(i), :));

    pred = predict(Theta1, Theta2, X(rp(i),:));
    fprintf('\nNeural Network Prediction: %d (digit %d)\n', pred, mod(pred, 10));

    % Pause with quit option
    s = input('Paused - press enter to continue, q to exit:','s');
    if s == 'q'
      break
    end
end

例如下圖所示的數字:

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM