Multi-Class Classification with Octave

2019. 2. 8. 09:15Artificial Intelligence

Programming Exercise 3: 

Multi-class Classification & Neural Networks




이번 프로그래밍 과제에서는 hand-written digit들의 픽셀정보를 저장한 data matrix를 기반으로

각 digit들이 0~9 사이의 어떤 수를 나타내는지를 판단하는

One vs all Multi-class Classification model을 구현하였다.


두 번째 과제로는 간단한 Layer 3의 Neural Networks를 구현하도록 하였다.


구현해야 하는 파일은 다음과 같았다.


ex3.m - Octave/MATLAB script that steps you through part 1
ex3 nn.m - Octave/MATLAB script that steps you through part 2 

ex3data1.mat - Training set of hand-written digits
ex3weights.mat - Initial weights for the neural network exercise 

submit.m - Submission script that sends your solutions to our servers 

displayData.m - Function to help visualize the dataset
fmincg.m - Function minimization routine (similar to fminunc) 

sigmoid.m - Sigmoid function
[] lrCostFunction.m - Logistic regression cost function
[] oneVsAll.m - Train a one-vs-all multi-class classifier

[predictOneVsAll.m - Predict using a one-vs-all multi-class classifier 

[] predict.m - Neural network prediction function





1. lrCostFunction.m

lrCostFunction 함수는 Logistic Regression Cost 함수를 구현하는 것으로, Linear model이 아닌 Logistic Model 이므로 sigmoid 함수의 구현을 통해 Cost Function을 정의해야 한다. 또한 Regularization을 통해 theta vector의 영향력을 조절해주는 변수도 추가해 주어야 한다. 마지막으로는 Cost Function의 비용을 최소화하기 위해 Gradient Descent를 수행해야 하는데, 그러기 위해서는 theta vector의 값으로 Cost Function을 편미분한 값인 Grad 값도 계산해 주어야 한다. 




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)

%


temptheta = theta;

temptheta(1) = 0;


J = (-1/m) * sum(y.*log(sigmoid(X*theta)) + (1-y).*log(1-sigmoid(X*theta)));

J = J + (lambda/(2*m)) * sum(temptheta.^2);

temp = sigmoid(X*theta);

error = temp - y;

grad = (1/m) * (X' * error) + (lambda/m)*temptheta;





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


grad = grad(:);


end





2. oneVsAll.m

oneVsAll Function은 X, y, num_labels(0~9까지의 값을 의미하므로 10), lambda 변수를 파라미터로 받았을 때, 0~9까지의 수 각각을 나타내는 Hypothesis Function의 theta Vector를 리턴하는 함수이다. 1번에서 구현한 lrCostFunction을 fmincg 함수를 이용해 Cost가 최소가 될때까지 반복하여 CostFunction을 최소로 만드는 theta vector를 0~9 digit 각각에 대하여 구현한다.

리턴하게 되는 theta Vector의 dimension 은 10 *  401인데, 10은 0~9사이의 수를 나타내고, 401은 20*20픽셀에 대한 theta 값에, theta(0)값인 1을 추가하여(parameter가 1이다.) 401이 된다. 




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

[theta] = fmincg(@(t)(lrCostFunction(t, X, (y==c), lambda)),initial_theta, options);

all_theta(c,:) = theta';

endfor


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



end






3.predictOneVsAll.m

predictOneVsAll 함수는 앞서 1, 2번에서 구현한 lrCostFunction과 oneVsAll 함수의 실행결과로 리턴된 all_theta값을 이용하여 testCase인 X값이 들어왔을때 (20*20픽셀이므로 5000*400 dimension vector로 들어올 것이다.) 그 값이 0~9사이의 어떤 값인지를 판단하는 함수이다. sigmoid(all_theta * X')를 한 값은 Logistic Function의 성질에 의해 0 아니면 1로 나타나기 때문에, max(sigmoid(all_theta*X'))를 출력하게 되면, 1인 값을 가지는 row의 index가 저장되고, 그 index는 예측된 digit을 나타내게 된다.

즉, predictOneVsAll 함수를 실행하게 되면, 5000개의 test case의 결과인 digit들이 5000*1 vector로 출력된다.




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.

%       



[probability indices] = max(sigmoid(all_theta * X'));

p = indices';

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



end




4.predict.m

predict.m함수는 Neural Networks의 기본적인 모델을 구현하는 함수이다. 

기본적인 모델을 구현함으로써 그 원리를 이해하는데에 그 목적이 있으므로, Layer가 3개인 (input Layer, hidden Layer, output Layer) 모델을 구현하였으며, 각각의 Layer 사이에 들어가는 Theta Vector는 'ex3weights.mat'파일을 통해 불러올 수 있다.

forward propagation만 구현하는 모델이므로, activation Function을 구현하고, 그 결과물을 sigmoid function으로 Mapping한 후에, 다시 그 결과를 activation Function을 통해 구현하고... 이 단계를 반복하면 된다. 나중에 Hidden Layer의 개수가 많아지면, 반복문을 통해 처리해서 코드의 바이트 수를 줄일 수 있을 것 같다.




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.

%


a1 = [ones(m, 1) X];

z2 = a1 * Theta1';

a2 = sigmoid(z2);


a2 = [ones(m, 1) a2];

z3 = a2 * Theta2';

hypo = sigmoid(z3);

[probability indices] = max(hypo');

p = indices';

                           


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



end

반응형

'Artificial Intelligence' 카테고리의 다른 글

Neural Networks & BackPropagation with Octave  (0) 2019.02.11
Neural Networks(3) - Cost Function & BackPropagation  (0) 2019.02.08
Neural Networks(2)  (0) 2019.02.07
Neural Networks (1)  (0) 2019.02.07
Logistic Regression with Octave  (0) 2019.02.04