Professional Documents
Culture Documents
% The coefficients alpha for the current working set have just been
% optimised, non of those should violate the KKT conditions.
if dodisplay>0,
fprintf('KKT conditions not met in working set (value %g)', ...
max(abs(KKT(ind))));
end
end
if dodisplay>0,
fprintf('%i violations of the KKT conditions.\n', ...
length(find(KKTviolations)));
fprintf(['(%i violations from positive examples, %i from negative' ...
' examples)\n'], length(find(KKTviolations & class1)), ...
length(find(KKTviolations & class0)));
if (dodisplay>1) & ~isempty(find(KKTviolations)),
disp('The following examples violate the KKT conditions:');
fprintf(' %i', find(KKTviolations));
fprintf('\n');
end
end
% Check how many violations of the KKT-conditions have been found. If
% none, we are finished.
if length(find(KKTviolations)) == 0,
break;
end
% Step 5: Determine a new working set. To this aim, a linear
% approximation of the objective function is made. The new working set
% constitutes of the QPSIZE largest elements of the gradient of the
% linear approximation. The gradient of the linear approximation can be
% expressed using the ouput of the SVM on all training examples.
if net.use2norm,
searchDir = SVMout+Y.*(net.alpha./C-1);
set1 = logical(uint8(SV | class0));
set2 = logical(uint8(SV | class1));
else
searchDir = SVMout-Y;
set1 = logical(uint8((SV | class0) & (~SVbound | class1)));
set2 = logical(uint8((SV | class1) & (~SVbound | class0)));
end
% During the very first iteration: If no initial values for net.alpha
% are given, perform a random working set selection
if randomWS,
searchDir = rand([N 1]);
set1 = class1;
set2 = class0;
randomWS = 0;
end
% Step 6: Select the working set.
% Goal is to select an equal number of examples from set1 and set2
% (QPsize/2 examples from set1, QPsize/2 from set2). The examples from
% set1 are the QPsize/2 highest elements of searchDir for set1,
% the examples from set2 are the QPsize/2 smallest elements of searchDir
% for set2.
worksetOld = workset;
workset = logical(uint8(zeros(N, 1)));
if length(find(set1 | set2)) <= QPsize,
workset(set1 | set2) = 1;
% Less than QPsize examples to select from: Use them all
elseif length(find(set1)) <= floor(QPsize/2),
workset(set1) = 1;
% set1 has less than half QPsize examples: Use all of set1, fill the
% rest with examples from set2 starting with the ones that have low
6
%
%
%
%
tic;
% Solve the quadratic program with 1 equality constraint.
% Initial guess for the solution of the QP problem.
startVal = net.alpha(workset);
switch qpsolver
case 'quadprog'
workalpha = quadprog(H, f, [], [], A, eqconstr, VLB, VUB, startVal, ...
quadprogopt);
case 'qp'
workalpha = qp(H, f, A, eqconstr, VLB, VUB, startVal, 1);
case 'loqo'
if isempty(VUB),
% LOQO crashes if upper bound is missing
% Use a relatively low value (instead of Inf) for faster
% convergence
VUB = repmat(1e7, size(VLB));
end
workalpha = loqo(H, f, A, eqconstr, VLB, VUB, startVal, 1);
end
t = toc;
if dodisplay>1,
fprintf('QP subproblem solved after %i minutes, %2.1f seconds.\n', ...
floor(t/60), mod(t, 60));
end
% Sometime QUADPROG returns a solution with small imaginary part
% (usually with ill-posed problems, badly conditioned H)
if any(imag(workalpha)>0),
warning(['The QP solver returned a complex solution. '...
'Check condition number cond(H).']);
workalpha = real(workalpha);
end
% Update the newly found coefficients in NET.alpha
alphaOld = net.alpha;
net.alpha(workset) = workalpha;
iteration = iteration+1;
end
% Finished! Store the Support Vectors and the coefficient given by
% NET.alpha and the corresponding label.
net.svcoeff = net.alpha(net.svind).*Y(net.svind);
net.sv = X(net.svind, :);
if dodisplay>0,
fprintf('\n\n\nTraining finished.\n');
disp('Information about the trained Support Vector Machine:');
svmstat(net,1);
% output statistics over SVs and separating hyperplane
end
function [net, SVthresh, SV, SVbound, SVnonbound] = findSV(net, C)
% FINDSV - Select the Support Vectors from the current coefficients NET.alpha
% Threshold for selecting Support Vectors
maxalpha = max(net.alpha);
if maxalpha > net.alphatol,
% For most cases, net.alphatol is a reasonable choice (approx 1e-2)
SVthresh = net.alphatol;
else
% For complex kernel on small data sets: all alphas will be very small.
% Use the mean between the minimum and maximum logarithm of values
% NET.alpha as a threshold.
9
SVthresh = exp((log(max(eps,maxalpha))+log(eps))/2);
end
% All examples that have a value of NET.alpha above this threshold are
% assumed to be Support Vectors.
SV = logical(uint8(net.alpha>=SVthresh));
% All Support Vectors that have a value at their upper bound C
if net.use2norm,
% There is no such thing in the 2norm case!
SVbound = logical(repmat(uint8(0), size(net.alpha)));
else
SVbound = logical(uint8(net.alpha>(C-net.alphatol)));
end
% The Support Vectors not at the upper bound
SVnonbound = SV & (~SVbound);
% The actual indices of the Support Vectors in the training set
net.svind = find(SV);
10