% this is a script for the OCR demo on the USPS data set
% Multi-classification using one-versus-the-rest approach
clc;
clear;
close all;
warning off;
addpath(genpath(pwd));
% load the training data - we are only using the first 2007 samples
% because of memory limitations in MATLAB ... (X, y)
load usps_digits_training.mat
X = X(1:2007,:); y = y(1:2007,1);
whos, % show what variables are in the workspace
% load also the testing (validation) data, (Xt yt)
load usps_digits_testing.mat
whos, % show now what variables are in the workspace
% the kernel parameter used is the degree of the polynomial
d = 2;
% now we are now going to create 10 binary classifiers we
% will assign +1 to the digit we desire to learn and then
% -1 to the rest, the digit we want to learn is called digit
for digit = [0 1 2 3 4 5 6 7 8 9],
% display some info
disp(sprintf('Now learning to recognize digit %d', digit));
% create the corresponding output vector
yb = zeros(size(y));
Iminus = find(y ~= digit); Iplus = find(y == digit);
yb(Iminus) = -1; yb(Iplus) = 1;
% fire up our kernel based perceptron algorithm
[alpha, R] = perceptron_dual_kernel(X, yb, d);
% now compute the test error, first what is the correct output
ytb = zeros(size(y));
Iminus = find(yt ~= digit); Iplus = find(yt == digit);
ytb(Iminus) = -1; ytb(Iplus) = 1;
% now compute the estimated ouput for this test data Xt
% note that we really need the support vectors
Isv = find(alpha>0);
% the bias is computed by
b = alpha(Isv)'*(yb(Isv)*R^2);
% compute the kernel
K = kernel(X(Isv,:),Xt,d);
% now compute the corresponding estimate of the output
yest = sign((yb(Isv).*alpha(Isv))'*K + b)';
% how does this estimate correspond to the output
error = sum([ytb ~= yest])/length(ytb)*100
% now let us keep this recognizer in a data structure called OCR
OCR(digit+1).X = X(Isv,:);
OCR(digit+1).y = yb(Isv,:);
OCR(digit+1).alpha = alpha(Isv);
OCR(digit+1).R = R;
OCR(digit+1).LABEL = digit;
end
% OK so how do our binary classifiers perform when they compete
disp('we now classify the whole test using all of our perceptrons');
for i=1:length(OCR),
% compute margin for each perceptron, make sure its the geometric one!
K = kernel(OCR(i).X,Xt,d);
b = OCR(i).alpha'*(OCR(i).y*OCR(i).R^2);
Yest(:,i) = ((OCR(i).y.*OCR(i).alpha)'*K + b)';
end
% now display the result of this experiment:
[dummy,I] = sort(-Yest,2);
character = I(:,1)-1;
total_test_error = sum([yt~=character])/length(yt)*100
% lets show at least the first 50 we failed to classify correctly
Iwrong = yt~=character;
plotdigits(Xt(Iwrong,:), yt(Iwrong), I(Iwrong,:)-1)