2016-04-28 21:40:36 +02:00
|
|
|
function WriteOutFaceCheckersCNNbinary(locationTxt, faceCheckers)
|
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
addpath('../PDM_helpers\');
|
2016-04-28 21:40:36 +02:00
|
|
|
|
|
|
|
% use little-endian
|
|
|
|
faceCheckerFile = fopen(locationTxt, 'w', 'l');
|
|
|
|
|
|
|
|
views = numel(faceCheckers);
|
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
% Type 0 - linear SVR, 1 - feed forward neural net, 2 - CNN, 3 - new
|
|
|
|
% CNN
|
|
|
|
fwrite(faceCheckerFile, 3, 'uint'); % 4 bytes
|
|
|
|
|
2016-04-28 21:40:36 +02:00
|
|
|
% Number of face checkers
|
|
|
|
fwrite(faceCheckerFile, views, 'uint'); % 4 bytes
|
|
|
|
|
|
|
|
% Matrices representing view orientations
|
|
|
|
for i=1:views
|
|
|
|
% this indicates that we're writing a 3x1 double matrix
|
|
|
|
writeMatrixBin(faceCheckerFile, faceCheckers(i).centres', 6);
|
|
|
|
end
|
|
|
|
|
|
|
|
for i = 1:views
|
|
|
|
|
|
|
|
% The normalisation models
|
|
|
|
% Mean of images
|
|
|
|
writeMatrixBin(faceCheckerFile, faceCheckers(i).mean_ex, 6);
|
|
|
|
|
|
|
|
% Standard deviation of images
|
|
|
|
writeMatrixBin(faceCheckerFile, faceCheckers(i).std_ex, 6);
|
|
|
|
|
|
|
|
cnn = faceCheckers(i).cnn;
|
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
num_depth_layers = size(cnn.layers,2);
|
2016-04-28 21:40:36 +02:00
|
|
|
|
|
|
|
% Get the number of layers
|
|
|
|
fwrite(faceCheckerFile, num_depth_layers, 'uint'); % 4 bytes
|
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
% For disambiguation between FC and conv layers
|
|
|
|
res = vl_simplenn(cnn, single(faceCheckers(i).mask), [], []);
|
|
|
|
|
|
|
|
for layers=1:num_depth_layers
|
2016-04-28 21:40:36 +02:00
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
% write layer type: 0 - convolutional, 1 - max pooling (2x2 stride 2), 2 -
|
|
|
|
% fully connected, 3 - relu, 4 - sigmoid
|
|
|
|
if(cnn.layers{layers}.type == 'conv')
|
2016-04-28 21:40:36 +02:00
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
% First check if it is an FC layer (they are represented
|
|
|
|
% like that in matconvnet)
|
|
|
|
if(numel(res(layers).x) == numel(cnn.layers{layers}.weights{1}(:,:,:,1)))
|
|
|
|
% This is the fully connected layer
|
|
|
|
fwrite(faceCheckerFile, 2, 'uint'); % 4 bytes
|
|
|
|
|
|
|
|
% the bias term
|
|
|
|
writeMatrixBin(faceCheckerFile, cnn.layers{layers}.weights{2}(:), 5);
|
|
|
|
% the weights
|
|
|
|
|
|
|
|
% Convert the filters to a matrix
|
|
|
|
weights_c = cnn.layers{layers}.weights{1};
|
|
|
|
size_w = size(weights_c);
|
|
|
|
weights = zeros(size_w(1)*size_w(2)*size_w(3), size_w(4));
|
|
|
|
weights(:) = weights_c;
|
|
|
|
writeMatrixBin(faceCheckerFile, weights, 5);
|
|
|
|
else
|
2016-04-28 21:40:36 +02:00
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
% write the type (convolutional)
|
|
|
|
fwrite(faceCheckerFile, 0, 'uint'); % 4 bytes
|
2016-04-28 21:40:36 +02:00
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
num_in_map = size(cnn.layers{layers}.weights{1},3);
|
2016-04-28 21:40:36 +02:00
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
% write the number of input maps
|
|
|
|
fwrite(faceCheckerFile, num_in_map, 'uint'); % 4 bytes
|
2016-04-28 21:40:36 +02:00
|
|
|
|
2017-08-01 23:11:02 +02:00
|
|
|
num_out_kerns = size(cnn.layers{layers}.weights{1},4);
|
|
|
|
|
|
|
|
% write the number of kernels for each output map
|
|
|
|
fwrite(faceCheckerFile, num_out_kerns, 'uint'); % 4 bytes
|
|
|
|
|
|
|
|
% Write output map bias terms
|
|
|
|
for k2=1:num_out_kerns
|
|
|
|
fwrite(faceCheckerFile, cnn.layers{layers}.weights{2}(k2), 'float32'); % 4 bytes
|
2016-04-28 21:40:36 +02:00
|
|
|
end
|
2017-08-01 23:11:02 +02:00
|
|
|
|
|
|
|
for k=1:num_in_map
|
|
|
|
for k2=1:num_out_kerns
|
|
|
|
% Write out the bias term
|
|
|
|
W = squeeze(cnn.layers{layers}.weights{1}(:,:,k,k2));
|
|
|
|
writeMatrixBin(faceCheckerFile, W, 5);
|
|
|
|
end
|
|
|
|
end
|
2016-04-28 21:40:36 +02:00
|
|
|
end
|
2017-08-01 23:11:02 +02:00
|
|
|
elseif(cnn.layers{layers}.type == 'pool')
|
|
|
|
fwrite(faceCheckerFile, 1, 'uint'); % 4 bytes, indicate max pooling layer, no params, assume (2x2 stride 2)
|
|
|
|
elseif(cnn.layers{layers}.type == 'relu')
|
|
|
|
fwrite(faceCheckerFile, 3, 'uint'); % 4 bytes, indicate relu layer, no params
|
|
|
|
end
|
2016-04-28 21:40:36 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
% Piecewise affine warp
|
|
|
|
|
|
|
|
nPix = faceCheckers(i).nPix;
|
|
|
|
minX = faceCheckers(i).minX;
|
|
|
|
minY = faceCheckers(i).minY;
|
|
|
|
|
|
|
|
destination = reshape(faceCheckers(i).destination, numel(faceCheckers(i).destination), 1);
|
|
|
|
triangulation = faceCheckers(i).triangulation;
|
|
|
|
triX = faceCheckers(i).triX;
|
|
|
|
mask = faceCheckers(i).mask;
|
|
|
|
alphas = faceCheckers(i).alphas;
|
|
|
|
betas = faceCheckers(i).betas;
|
|
|
|
|
|
|
|
fwrite(faceCheckerFile, nPix, 'uint'); % 4 bytes
|
|
|
|
fwrite(faceCheckerFile, minX, 'float64'); % 8 bytes
|
|
|
|
fwrite(faceCheckerFile, minY, 'float64'); % 8 bytes
|
|
|
|
|
|
|
|
% Destination shape
|
|
|
|
writeMatrixBin(faceCheckerFile, destination, 6);
|
|
|
|
|
|
|
|
% Triangulation
|
|
|
|
writeMatrixBin(faceCheckerFile, triangulation, 4);
|
|
|
|
|
|
|
|
% Triangle map
|
|
|
|
writeMatrixBin(faceCheckerFile, triX, 4);
|
|
|
|
|
|
|
|
% Mask
|
|
|
|
writeMatrixBin(faceCheckerFile, mask, 4);
|
|
|
|
|
|
|
|
% Alphas
|
|
|
|
writeMatrixBin(faceCheckerFile, alphas, 6);
|
|
|
|
|
|
|
|
% Betas
|
|
|
|
writeMatrixBin(faceCheckerFile, betas, 6);
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
fclose(faceCheckerFile);
|
|
|
|
|
|
|
|
end
|