Skip to content

Commit 3c2da65

Browse files
committed
Adding Source Code for Parallel Forall post on MATLAB Deep Learning
1 parent a20f68f commit 3c2da65

6 files changed

Lines changed: 247 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
% Copyright (c) 2015, MathWorks, Inc.
2+
3+
%% Download and and predict using a pretrained ImageNet model
4+
5+
% Download from MatConvNet pretrained networks repository
6+
urlwrite('http://www.vlfeat.org/matconvnet/models/imagenet-vgg-f.mat', 'imagenet-vgg-f.mat');
7+
cnnModel.net = load('imagenet-vgg-f.mat');
8+
9+
% Setup up MatConvNet, modify the path if it's installed in a different
10+
% folder
11+
run(fullfile('matconvnet-1.0-beta15','matlab','vl_setupnn.m'));
12+
13+
% Load and display an example image
14+
imshow('dog_example.png');
15+
img = imread('dog_example.png');
16+
17+
% Predict label using ImageNet trained vgg-f CNN model
18+
label = cnnPredict(cnnModel,img);
19+
title(label,'FontSize',20)
20+
21+
%% Load images from folder
22+
23+
% Use imageSet to manage images stored in multiple folders
24+
imset = imageSet('pet_images','recursive');
25+
26+
% Preallocate arrays with fixed size for prediction
27+
imageSize = cnnModel.net.normalization.imageSize;
28+
trainingImages = zeros([imageSize sum([imset(:).Count])],'single');
29+
30+
% Load and resize images for prediction
31+
for ii = 1:numel(imset)
32+
for jj = 1:imset(ii).Count
33+
trainingImages(:,:,:,jj) = imresize(single(read(imset(ii),jj)),imageSize(1:2));
34+
end
35+
end
36+
37+
% Get the image labels directly from the ImageSet object
38+
trainingLabels = getImageLabels(imset);
39+
summary(trainingLabels)
40+
41+
%% Extract features using pretrained CNN
42+
43+
% Depending on how much memory you have on your GPU you may use a larger
44+
% batch size. We have 400 images, I'm going to choose 200 as my batch size
45+
cnnModel.info.opts.batchSize = 200;
46+
47+
% Make prediction on a CPU
48+
[~, cnnFeatures, timeCPU] = cnnPredict(cnnModel,trainingImages,'UseGPU',false);
49+
% Make prediction on a GPU
50+
[~, cnnFeatures, timeGPU] = cnnPredict(cnnModel,trainingImages,'UseGPU',true);
51+
52+
% Compare the performance increase
53+
bar([sum(timeCPU),sum(timeGPU)],0.5)
54+
title(sprintf('Approximate speedup: %2.00f x ',sum(timeCPU)/sum(timeGPU)))
55+
set(gca,'XTickLabel',{'CPU','GPU'},'FontSize',18)
56+
ylabel('Time(sec)'), grid on, grid minor
57+
58+
%% Train a classifier using extracted features and calculate CV accuracy
59+
60+
% Train and validate a linear support vector machine (SVM) classifier.
61+
classifierModel = fitcsvm(cnnFeatures, trainingLabels);
62+
63+
% 10 fold crossvalidation accuracy
64+
cvmdl = crossval(classifierModel,'KFold',10);
65+
fprintf('kFold CV accuracy: %2.2f\n',1-cvmdl.kfoldLoss)
66+
67+
%% Object Detection
68+
% Use findPet function that was automatically generated using the
69+
% Image Region Analyzer App
70+
71+
%% Tying the workflow together
72+
frameNumber = 0;
73+
vr = VideoReader(fullfile('PetVideos','videoExample.mov'));
74+
vw = VideoWriter('test.avi','Motion JPEG AVI');
75+
opticFlow = opticalFlowFarneback;
76+
open(vw);
77+
while hasFrame(vr)
78+
% Count frames
79+
frameNumber = frameNumber + 1;
80+
81+
% Step 1. Read Frame
82+
videoFrame = readFrame(vr);
83+
84+
% Step 2. Detect ROI
85+
vFrame = imresize(videoFrame,0.25); % Get video frame
86+
frameGray = rgb2gray(vFrame); % Convert to gray for detection
87+
bboxes = findPet(frameGray,opticFlow); % Find bounding boxes
88+
if ~isempty(bboxes)
89+
img = zeros([imageSize size(bboxes,1)]);
90+
for ii = 1:size(bboxes,1)
91+
img(:,:,:,ii) = imresize(imcrop(vFrame,bboxes(ii,:)),imageSize(1:2));
92+
end
93+
94+
% Step 3. Recognize object
95+
% (a) Extract features using a CNN
96+
[~, scores] = cnnPredict(cnnModel,img,'UseGPU',true,'display',false);
97+
98+
% (b) Predict using a trained Classifier
99+
label = predict(classifierModel,scores);
100+
101+
% Step 4. Annotate object
102+
vFrame = insertObjectAnnotation(vFrame,'Rectangle',bboxes,cellstr(label),'FontSize',40);
103+
end
104+
105+
% Step 5. Write video to file
106+
writeVideo(vw,videoFrame);
107+
108+
% fprintf('Frame: %d of %d\n',frameNumber,ceil(vr.FrameRate*vr.Duration));
109+
end
110+
close(vw);
111+

MATLAB_deeplearning/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Companion Code for "Deep Learning for Computer Vision with MATLAB" by Shashank Prasanna
2+
============================
3+
4+
This folder contains source code from the NVIDIA Parallel Forall Blog post [Deep Learning for Computer Vision with MATLABMATLAB by Joss Knight]() by Shashank Prasanna (The Mathworks).
5+
6+
License
7+
-------
8+
9+
These examples are released under the BSD open source license. Refer to license.txt in this directory for full details.

MATLAB_deeplearning/cnnPredict.m

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
function [classLabel, scores, batchTime] = cnnPredict(cnnModel,predImage,varargin)
2+
% Copyright (c) 2015, MathWorks, Inc.
3+
4+
% Parse inputs
5+
p = inputParser;
6+
addParameter(p,'outputLayer',numel(cnnModel.net.layers),@isnumeric);
7+
addParameter(p,'UseGPU',false,@islogical);
8+
addParameter(p,'display',true,@islogical);
9+
parse(p,varargin{:});
10+
11+
% Get batch size and number of images
12+
if ~isfield(cnnModel,'info')
13+
cnnModel.info.opts.batchSize = 1;
14+
end
15+
batchSize = cnnModel.info.opts.batchSize;
16+
n_obs = size(predImage,4);
17+
isTapLayer = p.Results.outputLayer < numel(cnnModel.net.layers);
18+
19+
if isTapLayer
20+
cnnModel.net.layers(p.Results.outputLayer+1:end) = [];
21+
else
22+
cnnModel.net.layers{end} = struct('type', 'softmax');
23+
end
24+
25+
% Preallocate scores
26+
resTemp = vl_simplenn(cnnModel.net, cnnPreprocess(predImage(:,:,:,1)), [], []);
27+
scores = zeros([size(resTemp(end).x), n_obs]);
28+
29+
% Move model to GPU if requested
30+
if p.Results.UseGPU
31+
cnnModel.net = vl_simplenn_move(cnnModel.net,'gpu');
32+
end
33+
34+
% Make predictions
35+
batchNumber = 0;
36+
numBatches = ceil(n_obs/batchSize);
37+
batchTime = zeros(numBatches,1);
38+
if p.Results.display
39+
disp(' ')
40+
fprintf('Using GPU: %s\n',mat2str(p.Results.UseGPU))
41+
fprintf('Number of images: %d\n',n_obs)
42+
fprintf('Number of batches: %d\n',numBatches)
43+
fprintf('Number of layers in the Network: %d\n',numel(cnnModel.net.layers))
44+
disp('-------------------------------------')
45+
end
46+
for ii = 1:batchSize:n_obs
47+
tic
48+
idx = ii:min(ii+batchSize-1,n_obs);
49+
batchImages = predImage(:,:,:,idx);
50+
im = cnnPreprocess(batchImages);
51+
52+
% Move batch to GPU if requested
53+
if p.Results.UseGPU
54+
im = gpuArray(im);
55+
end
56+
train_res = vl_simplenn(cnnModel.net, im, [], []);
57+
scores(:,:,:,idx) = squeeze(gather(train_res(end).x));
58+
batchNumber = batchNumber + 1;
59+
batchTime(batchNumber) = toc;
60+
if p.Results.display
61+
fprintf('Batch: %2d/%d. Execution time: %2.4f\n',batchNumber,numBatches,batchTime(batchNumber))
62+
end
63+
end
64+
65+
if p.Results.display
66+
fprintf('Avg. execution time/batch: %2.4f\n',mean(batchTime))
67+
disp('-------------------------------------')
68+
fprintf('Total execution time: %2.4f\n',sum(batchTime))
69+
disp('-------------------------------------')
70+
end
71+
72+
if isTapLayer
73+
classLabel = [];
74+
else
75+
scores = squeeze(gather(scores))';
76+
[~, labelId] = max(scores,[],2);
77+
% classLabel = categorical(cnnModel.net.classes.description(labelId)');
78+
classLabel = cnnModel.net.classes.description(labelId)';
79+
end
80+
81+
function im = cnnPreprocess(batchImages)
82+
% Preprocess images
83+
im = single(batchImages);
84+
im = imresize(im, cnnModel.net.normalization.imageSize(1:2));
85+
im = bsxfun(@minus,im,cnnModel.net.normalization.averageImage);
86+
end
87+
88+
end
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
function [BW_out,properties] = filterRegions(BW_in)
2+
% Copyright (c) 2015, MathWorks, Inc.
3+
%filterRegions Filter BW image using auto-generated code from imageRegionAnalyzer app.
4+
% [BW_OUT,PROPERTIES] = filterRegions(BW_IN) filters binary image BW_IN
5+
% using auto-generated code from the imageRegionAnalyzer App. BW_OUT has
6+
% had all of the options and filtering selections that were specified in
7+
% imageRegionAnalyzer applied to it. The PROPERTIES structure contains the
8+
% attributes of BW_out that were visible in the App.
9+
10+
% Auto-generated by imageRegionAnalyzer app on 19-Oct-2015
11+
%---------------------------------------------------------
12+
13+
BW_out = BW_in;
14+
15+
% Filter image based on image properties.
16+
BW_out = bwpropfilt(BW_out, 'Area', [5000 + eps(5000), Inf]);
17+
18+
% Get properties.
19+
properties = regionprops(BW_out, {'BoundingBox','Area'});
20+
21+
% Uncomment the following line to return the properties in a table.
22+
% properties = struct2table(properties);

MATLAB_deeplearning/findPet.m

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function bboxes = findPet(frameGray, opticFlow)
2+
% Copyright (c) 2015, MathWorks, Inc.
3+
4+
flow = estimateFlow(opticFlow,frameGray);
5+
threshImage = ( flow.Magnitude > 4);
6+
[BW_out,regions] = filterRegions(threshImage);
7+
if(size(regions) > 0)
8+
bboxes = regions.BoundingBox;
9+
else
10+
bboxes = [];
11+
end
12+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
function imageType = getImageLabels(imset)
2+
% Copyright (c) 2015, MathWorks, Inc.
3+
imageType = categorical(repelem({imset.Description}', ...
4+
[imset.Count], 1));
5+
end

0 commit comments

Comments
 (0)