【MatConvnet速成】MatConvnet图像分类从模型自定义到测试
歡迎來到專欄《2小時玩轉開源框架系列》,這是我們第10篇,前面已經說過了caffe,tensorflow,pytorch,mxnet,keras,paddlepaddle,cntk,chainer,deeplearning4j。
今天說MatConvnet,本文所用到的數據,代碼請參考我們官方git
https://github.com/longpeng2008/LongPeng_ML_Course
作者&編輯 | 言有三
?
1 MatConvnet是什么
不同于各類深度學習框架廣泛使用的語言Python,MatConvnet是用matlab作為接口語言的開源深度學習庫,底層語言是cuda。
官網地址為:http://www.vlfeat.org/matconvnet/
github地址為:https://github.com/vlfeat/matconvnet
因為是在matlab下面,所以debug的過程非常的方便,而且本身就有很多的研究者一直都使用matlab語言,所以其實該語言的群體非常大。
在用python之前,我也是用matlab的,那個經典的deep-learning-toolbox的代碼其實也非常值得研讀,說起來,matlab還是非常做圖像處理的。
?
2 MatConvnet訓練準備
2.1 安裝
以linux系統為例,首先要安裝好matlab,這個大家自己搞定吧。然后,在matlab環境下進行安裝,幾行代碼就可以。
mex -setup ##設置好編譯器
untar('http://www.vlfeat.org/matconvnet/download/matconvnet-1.0-beta25.tar.gz') ;
cd matconvnet-1.0-beta25
run matlab/vl_compilenn ;
沒有報錯的話就完成了,完成后為了確保沒有問題,先用官方的例子確認一下。
%下載預訓練模型
urlwrite(...? 'http://www.vlfeat.org/matconvnet/models/imagenet-vgg-f.mat', ...? 'imagenet-vgg-f.mat')
%設置環境
run matlab/vl_setupnn
%載入模型
net = load('imagenet-vgg-f.mat') ;
net = vl_simplenn_tidy(net)
%讀取圖像并預處理
im = imread('peppers.png') ;
im_ = single(im) ; % note: 255 range
im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
im_ = im_ - net.meta.normalization.averageImage ;
%得到結果
res = vl_simplenn(net, im_) ;
result.scores = squeeze(gather(res(end).x)) ;
[bestScore, best] = max(scores) ;
figure(1) ; clf ; imagesc(im) ;
title(sprintf('%s (%d), score %.3f',...
? net.meta.classes.description{best}, best, bestScore)) ;
成功的話結果如下:
更復雜的還可以用DagNN wrapper的API,不過這不是本文的主要目標,因此不再講述。
當然,我們是要用GPU的,所以還要完成GPU編譯,按照這里來:
http://www.vlfeat.org/matconvnet/install/
因為版本不一定完全匹配,所以用nvcc編譯。
vl_compilenn('enableGpu', true, 'cudaRoot', '/usr/local/cuda','cudaMethod', 'nvcc')
2.2 數據準備
前面講了官方的例子,接下來就是要用我們自己的例子了,第一步還是老規矩,準備數據,完整的代碼如下。
function imdb = mydataset(datadir)
inputSize =[48,48,1];
subdir=dir(datadir);
imdb.images.data=[];
imdb.images.labels=[];
imdb.images.set = [] ;
imdb.meta.sets = {'train', 'val', 'test'} ;
image_counter=0;
trainratio=0.8;
subdir
for i=3:length(subdir)
? ? ? ? imgfiles=dir(fullfile(datadir,subdir(i).name));
? ? ? ? imgpercategory_count=length(imgfiles)-2;
? ? ? ? disp([i-2 imgpercategory_count]);
? ? ? ? image_counter=image_counter+imgpercategory_count;
? ? ? ? for j=3:length(imgfiles)
? ? ? ? ? ? img=imread(fullfile(datadir,subdir(i).name,imgfiles(j).name));
? ? ? ? ? ? img=imresize(img, inputSize(1:2));
? ? ? ? ? ? img=single(img);
%? ? ? ? ? ? [~,~,d]=size(img);
%? ? ? ? ? ? if d==3
%? ? ? ? ? ? ? ? img=rgb2gray(img);
%? ? ? ? ? ? ? ? continue;
%? ? ? ? ? ? end
? ? ? ? ? ? imdb.images.data(:,:,:,end+1)=single(img);
? ? ? ? ? ? imdb.images.labels(end+1)= i-2;
? ? ? ? ? ? if j-2<imgpercategory_count*trainratio
? ? ? ? ? ? ? ? imdb.images.set(end+1)=1;
? ? ? ? ? ? else
? ? ? ? ? ? ? ? imdb.images.set(end+1)=3;
? ? ? ? ? ? end
? ? ? ? end
end
dataMean=mean(imdb.images.data,4);
imdb.images.data = single(bsxfun(@minus,imdb.images.data, dataMean)) ;
imdb.images.data_mean = dataMean;
end
如果使用過Matlab的同學,應該一下就看懂了,實際上就是3個步驟:
1)使用fullfile函數遍歷圖像。
2)預處理,包括縮放,類型轉換等。
3)生成IMDB格式數據集。
2.3 網絡定義
還是跟以前一樣,定義一個3層的卷積神經網絡,非常簡單,不做過多注釋了噢。
function net =simpleconv3()
rng('default');
rng(0) ;
f=1/100 ;
usebatchNormalization = true ;
net.layers = {};
net.layers{end+1} = struct('type', 'conv', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'weights', {{f*randn(3,3,3,12, 'single'), zeros(1, 12, 'single')}}, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'stride', 1, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pad', 1) ;
net.layers{end+1} = struct('type', 'pool', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'method', 'max', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pool', [2 2], ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'stride', 2, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'conv', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'weights', {{f*randn(3,3,12,24, 'single'),zeros(1,24,'single')}}, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'stride', 1, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pad', 1) ;
net.layers{end+1} = struct('type', 'pool', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'method', 'max', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pool', [2 2], ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'stride', 2, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'conv', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'weights', {{f*randn(3,3,24,48, 'single'),zeros(1,48,'single')}}, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'stride', 1, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pad', 1) ;
net.layers{end+1} = struct('type', 'pool', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'method', 'max', ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pool', [2 2], ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'stride', 2, ...
? ? ? ? ? ? ? ? ? ? ? ? ? 'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;
net.layers{end+1} = struct('type', 'conv', ...
? 'weights', {{f*randn(6,6,48,2, 'single'),zeros(1,2,'single')}}, ...
? 'stride', 1, ...
? 'pad', 0) ;
net.layers{end+1} = struct('type', 'softmaxloss') ;
net = insertBnorm(net, 1) ;
net = insertBnorm(net, 5) ;
net = insertBnorm(net, 9) ;
% Meta parameters
net.meta.inputSize = [48 48 3] ;
net.meta.trainOpts.learningRate = logspace(-2, -5, 100);
net.meta.trainOpts.numEpochs = 50 ;
net.meta.trainOpts.batchSize = 16 ;
% Fill in defaul values
net = vl_simplenn_tidy(net) ;
end
% --------------------------------------------------------------------
?
3 模型訓練
完整代碼如下。
function [net, info] = trainconv3()
global datadir;
run matlab/vl_setupnn ; %初始化
datadir='/home/longpeng/project/LongPeng_ML_Course/projects/classification/matconvnet/conv3/mouth';
opts.expDir = fullfile('/home/longpeng/project/LongPeng_ML_Course/projects/classification/matconvnet/conv3/','imdb') ;
opts.imdbPath = fullfile(opts.expDir, 'imdb.mat');
if exist(opts.imdbPath,'file')
? imdb=load(opts.imdbPath);
else
? imdb=mydataset(datadir);
? mkdir(opts.expDir) ;
? save(opts.imdbPath, '-struct', 'imdb') ;
end
net=simpleconv3();
net.meta.normalization.averageImage =imdb.images.data_mean ;
opts.train.gpus=1;
[net, info] = cnn_train(net, imdb, getBatch(opts), ...
'expDir', opts.expDir, ...
net.meta.trainOpts, ...
opts.train, ...
'val', find(imdb.images.set == 3)) ;
function fn = getBatch(opts)
% --------------------------------------------------------------------
? fn = @(x,y) getSimpleNNBatch(x,y) ;
end
function [images, labels]? = getSimpleNNBatch(imdb, batch)
? images = imdb.images.data(:,:,:,batch) ;
? labels = imdb.images.labels(1,batch) ;
? if opts.train.gpus > 0
? ? ? images = gpuArray(images) ;
? end
end
end
總共就這么幾個步驟:
1)初始化環境,run matlab/vl_setupnn 。
2)定義網絡:net=simpleconv3()。
3)調用訓練接口:[net, info] = cnn_train(net, imdb, getBatch(opts)。
?
4 可視化
工具已經給封裝好了可視化,直接運行代碼就會跳出來,可以看出收斂正常,略有過擬合,展示的分別是softmax損失和錯誤率。
?
5 測試
%netpath=[opts.expDir '/net-epoch-50.mat'];? ?
netpath='/home/longpeng/project/LongPeng_ML_Course/projects/classification/matconvnet/conv3/imdb/net-epoch-50.mat';? ?
class=1;index=1;? ?
datadir='/home/longpeng/project/LongPeng_ML_Course/projects/classification/matconvnet/conv3/mouth';? ?
subdir=dir(datadir);? ?
imgfiles=dir(fullfile(datadir,subdir(class+2).name));? ?
img=imread(fullfile(datadir,subdir(class+2).name,imgfiles(index+2).name));? ?
imshow(img);? ?
net=load(netpath);? ?
net=net.net;? ?
im_=single(img);? ?
im_=imresize(im_,net.meta.inputSize(1:2));? ?
im_=im_ - net.meta.normalization.averageImage;? ?
opts.batchNormalization = false ;? ?
net.layers{end}.type = 'softmax';? ?
res=vl_simplenn(net,im_);? ?
scores=squeeze(gather(res(end).x));? ?
[bestScore,best]=max(scores);? ?
str=[subdir(best+2).name ':' num2str(bestScore)];? ?
title(str);? ?
disp(str);? ?
從上面可以看出,就是載入模型,完成正確的預處理,然后進行分類。
一個樣本的結果如下,0:0.99968,表示分類為類別0的概率是0.99968,可知結果正確,0代表的類別就是中性表情。
?
總結
有很多的優秀代碼仍然使用matconvnet,而且它的社區所包含的預訓練模型也非常多,非常適合訓練過程中進行調試,建議大家有Matlab環境和多余精力的可以學習一下,學習成本很低,技多不壓身嘛。
本系列完整文章:
第一篇:【caffe速成】caffe圖像分類從模型自定義到測試
第二篇:【tensorflow速成】Tensorflow圖像分類從模型自定義到測試
第三篇:【pytorch速成】Pytorch圖像分類從模型自定義到測試
第四篇:【paddlepaddle速成】paddlepaddle圖像分類從模型自定義到測試
第五篇:【Keras速成】Keras圖像分類從模型自定義到測試
第六篇:【mxnet速成】mxnet圖像分類從模型自定義到測試
第七篇:【cntk速成】cntk圖像分類從模型自定義到測試
第八篇:【chainer速成】chainer圖像分類從模型自定義到測試
第九篇:【DL4J速成】Deeplearning4j圖像分類從模型自定義到測試
第十篇:【MatConvnet速成】MatConvnet圖像分類從模型自定義到測試
第十一篇:【Lasagne速成】Lasagne/Theano圖像分類從模型自定義到測試
第十二篇:【darknet速成】Darknet圖像分類從模型自定義到測試
感謝各位看官的耐心閱讀,不足之處希望多多指教。后續內容將會不定期奉上,歡迎大家關注有三公眾號 有三AI!
總結
以上是生活随笔為你收集整理的【MatConvnet速成】MatConvnet图像分类从模型自定义到测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【darknet速成】Darknet图像
- 下一篇: 【杂谈】提升写代码效率不得不做的三件事