-
Notifications
You must be signed in to change notification settings - Fork 5
/
ldrc.m
120 lines (95 loc) · 3.5 KB
/
ldrc.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
function accuracy = ldrc(TrainSet, TestSet, train_num, test_num, class_num, reduce_dimension, options)
% Linear discriminant regression classificatoin (LDRC) algorithm
%
% Inputs:
% TrainSet train sets of size dxn, where d is dimension and n is number of sets
% TestSet test sets of size dxn, where d is dimension and n is number of sets
% test_num numner of test sets
% class_num numner of classes
% options options
% Output:
% accuracy classification accurary
%
% References:
% S.-M. Huang and J.-F. Yang,
% "Linear discriminant regression classification for face recognition,"
% IEEE Signal Processing Letters, vol.20, no.1, pp.91-94, 2013.
%
%
% Created by H.Kasai on July 05, 2017
% extract options
if ~isfield(options, 'verbose')
verbose = false;
else
verbose = options.verbose;
end
if verbose
fprintf('# LDRC: calculate projection matrix U ...');
end
Eb = 0;
Ew = 0;
for j = 1 : train_num
j_class = TrainSet.y(1, j);
% calcuate Ew
intra_class_index = find(TrainSet.y == j_class);
intra_class_index(intra_class_index == j) = [];
X_intra_wo_j = TrainSet.X(:, intra_class_index); % X^{intra}
for k = 1 : size(X_intra_wo_j, 2)
error_intra = TrainSet.X(:,j) - X_intra_wo_j(:,k);
Ew = Ew + error_intra * error_intra'; % Eq.(14)
end
% calcuate Eb
inter_class_index = find(TrainSet.y ~= j_class);
X_inter = TrainSet.X(:, inter_class_index); % X^{inter}
for k = 1 : size(X_inter, 2)
error_inter = TrainSet.X(:,j) - X_inter(:,k);
end
Eb = Eb + error_inter * error_inter'; % Eq.(13)
end
% calc
Ew = Ew/train_num; % Eq.(14)
Eb = Eb/(train_num * (class_num-1)); % Eq.(13)
epsilon = 0.001;
Ew = Ew + epsilon*eye(size(Ew,2));
[V, ~] = eig(Eb, Ew); % Eq.(18)
for i = 1:reduce_dimension
U(:,i) = V(:,size(V,2)+1-i);
end
if verbose
fprintf('done\n');
end
% reduce dimention
TrainSet.X_red = U' * TrainSet.X;
TestSet.X_red = U' * TestSet.X;
% prepare projection matrix (hat matrix)
H = cell(1, class_num);
for i = 1 : class_num
class_index = find(TrainSet.y == i);
X_i = TrainSet.X_red(:, class_index);
alpha_i = pinv(X_i' * X_i) * X_i';
H{i} = X_i * alpha_i;
if verbose
fprintf('# LDRC: calc Hi for class : %03d/%03d (samples: %03d)\n', i, class_num, length(class_index));
end
end
% prepare predicted label array
identity = zeros(1, test_num);
% predict the class
for j = 1 : test_num
dis = zeros(1, class_num);
y = TestSet.X_red(:, j);
for i = 1 : class_num
y_pred = H{i} * y;
dis(1, i) = norm(y - y_pred);
end
[~, label] = min(dis);
identity(j) = label;
if verbose
correct = (label == TestSet.y(1, j));
fprintf('# LDRC: test:%03d, predict class: %03d --> ground truth :%03d (%d)\n', j, label, TestSet.y(1, j), correct);
end
end
% calculate accuracy
correct_num = sum(identity == TestSet.y);
accuracy = correct_num / test_num;
end