-
Notifications
You must be signed in to change notification settings - Fork 122
/
Copy pathaddPCA.m
87 lines (65 loc) · 2.89 KB
/
addPCA.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
function net= addPCA(net, dbTrain, varargin)
opts= struct(...
'pcaDim', 4096, ...
'doWhite', true, ...
'nTrainCap', 10000, ...
'useGPU', true, ...
'numThreads', 12, ...
'batchSize', 10 ...
);
opts= vl_argparse(opts, varargin);
if ~isfield(net.meta, 'sessionID') || ~isfield(net.meta, 'epoch')
error('net should have a sessionID and epoch properties, I''m assuming you didn''t use the provided functions to create the networks? (loadNet, addLayers, pickBestNet)');
end
paths= localPaths();
trainDbFeatFn= sprintf('%s%s_ep%06d_traindescs_for_pca.bin', paths.outPrefix, net.meta.sessionID, net.meta.epoch);
pcaFn= sprintf('%s%s_ep%06d_pca.mat', paths.outPrefix, net.meta.sessionID, net.meta.epoch);
D= relja_netOutputDim(net);
if ~exist(pcaFn, 'file')
relja_displayDateTime();
if ~exist(trainDbFeatFn, 'file')
relja_display('%s Computing training vectors for PCA', net.meta.sessionID);
imageFns= dbTrain.dbImageFns;
nTrain= length(imageFns);
if nTrain>opts.nTrainCap
rng(43);
imageFns= imageFns(randsample(nTrain, opts.nTrainCap));
end
serialAllFeats(net, dbTrain.dbPath, imageFns, trainDbFeatFn, ...
'useGPU', opts.useGPU, 'numThreads', opts.numThreads, 'batchSize', opts.batchSize);
clear nTrain;
end
relja_display('%s Computing PCA', net.meta.sessionID);
dbFeat= fread( fopen(trainDbFeatFn, 'rb'), [D, inf], 'float32=>single');
nTrain= size(dbFeat, 2);
assert( opts.pcaDim < D );
if nTrain>opts.nTrainCap
rng(43);
dbFeat= dbFeat(:, randsample(nTrain, opts.nTrainCap));
end
[U, lams, mu, Utmu]= relja_PCA(dbFeat, opts.pcaDim);
clear dbFeat;
save(pcaFn, 'U', 'lams', 'mu', 'Utmu');
clear U lams mu Utmu;
end
pcaParams= load(pcaFn, 'U', 'lams', 'mu', 'Utmu');
assert(opts.pcaDim<=size(pcaParams.U, 2));
U= pcaParams.U(:, 1:opts.pcaDim);
lams= pcaParams.lams(1:opts.pcaDim);
if opts.doWhite
U= U*diag(1./sqrt(lams+1e-9));
pcaStr= 'WPCA';
else
pcaStr= 'PCA';
end
Utmu= U'*pcaParams.mu;
% --- Add the PCA (+whitening) layer to the network:
net.layers{end+1}= struct('type', 'conv', 'name', pcaStr, ...
'weights', {{ reshape(U, [1,1,D,opts.pcaDim]), -Utmu }}, ...
'stride', 1, 'pad', 0, 'opts', {{}}, 'precious', false);
% final normalization
net.layers{end+1}= layerWholeL2Normalize('finalL2');
net.meta.sessionID= sprintf('%s_%s', net.meta.sessionID, pcaStr);
% account for future changes in MatConvNet
net = relja_simplenn_tidy(net);
end