(3)如何在MatConvNet下训练自己的数据

之前用了比较简单的DeepLearningtoolbox工具包,为了深入把所有的m文件解析了一次。换到MatConvNet,发现它比前者要“庞大”很多,之前写了几篇解析就写不下去了;但MatConvNet基本的层层调用关系,和DeepLearningtoolbox还是很相似的,如果能先跑一个我们自己的例子,再来分析层级结构,有些东西理解起来就会快很多吧。。

车牌识别 <–在这里下载我们这次实验需要的数据,下载后解压,文件结构是这样的,
(3)如何在MatConvNet下训练自己的数据_第1张图片
每个文件夹下存放对应的图片,然后我们在自己的MatConvNet/examples下建立一个我们自己的例子,我这里取名为myplate,里面有这么几个文件,接下来我们进行一一解析,
(3)如何在MatConvNet下训练自己的数据_第2张图片

首先是新建cnn_plate_setup.m文件

,读取相应的图片和标签,并且减去均值。

function imdb =cnn_plate_setup_data(datadir)
inputSize =[20,20,1];
subdir=dir(datadir);%Dir函数,返回一个 String,用以表示一个文件名、目录名或文件夹名称
imdb.images.data=[];
imdb.images.labels=[];
imdb.images.set = [] ;
imdb.meta.sets = {'train', 'val', 'test'} ;
image_counter=0;
trainratio=0.8;
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;

这里做一个解释,之所以要从3开始,是因为试了下length(subdir)结果是67,而我们的文件夹里的总个数是65,所以应该是把前两个去掉了。(到这里我觉得有必要补习matlab中结构体的知识。)

for j=3:length(imgfiles)
img=imread(fullfile(datadir,subdir(i).name,imgfiles(j).name));
img=imresize(img, inputSize(1:2));
img=single(img);
imdb.images.data(:,:,:,end+1)=single(img);
imdb.images.labels(end+1)= i-2;
if j-2.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

这一部分是把输入图像做一些处理,因为trainratio=0.8,所以在80%之前的被用作训练集,set为1,后面是测试,set设置为3。(刚刚入手matconvnet,有很多都是自己的理解,有错误的地方欢迎指出,大家一起进步哈)同时这里进行了一个计算均值的操作。

接下来在cnn_plate_init.m中设计网络结构

function net =cnn_plate_init()
rng('default');
rng(0) ;
f=1/100 ;
net.layers = {};
net.layers{end+1} = struct('type', 'conv', ...
'weights', {{f*randn(3,3,1,20, 'single'), zeros(1, 20, 'single')}}, ...
'stride', 1, ...
'pad', 0) ;
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,20,100, 'single'),zeros(1,100,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
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,100,1000, 'single'),zeros(1,1000,'single')}}, ...
'stride', 1, ...
'pad', 0) ;
net.layers{end+1} = struct('type', 'softmaxloss') ;
% Meta parameters
net.meta.inputSize = [20 20 1] ;
net.meta.trainOpts.learningRate = logspace(-3, -5, 100);
net.meta.trainOpts.numEpochs = 50 ;
net.meta.trainOpts.batchSize = 1000 ;
% Fill in defaul values
net = vl_simplenn_tidy(net) ;
end

这个文件一目了然,是用来设计网络结构的,开头的rng(‘default’)是恢复matlab启动时默认的全局随机流,至于rng函数,用来保证每次生成的随机变量是一致的。这里设计的结构是conv1->pool1->relu->conv2->pool2->relu->conv3->softmax
其中conv1的参数设置为20个3*3大小的卷积核,偏置为20个0,步长为1,没有补零,后面的层可以一一分析。
网络结构的设计要特别小心,不行的话就多调几个试一试。

最后是一个cnn_plate()文件把这些串联起来进行训练

function [net, info] = cnn_plate()
run(fullfile(fileparts(mfilename('fullpath')),...
'..', '..', 'matlab', 'vl_setupnn.m')) ;
datadir='F:\resources\train\ann';%这里放自己的数据路径
opts.expDir = fullfile(vl_rootnn, 'data', 'plate-baseline') ;
opts.imdbPath = fullfile(opts.expDir, 'imdb.mat');
if exist(opts.imdbPath,'file')
imdb=load(opts.imdbPath);
else
imdb=cnn_plate_setup_data(datadir);
mkdir(opts.expDir) ;
save(opts.imdbPath, '-struct', 'imdb') ;
end
net=cnn_plate_init();
net.meta.normalization.averageImage =imdb.images.data_mean ;
opts.train.gpus=?;%这里注意,根据自己用CPU还是GPU做相应修改,不然会出错
[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

然后就是训练过程,放几张截图:
(3)如何在MatConvNet下训练自己的数据_第3张图片
训练好之后,我们就自己写一个test来识别下吧,

run(fullfile(fileparts(mfilename('fullpath')),...
'..', '..', 'matlab', 'vl_setupnn.m')) ;
addpath F:\matconvnet-master\data\plate-baseline;
datadir='F:\resources\train\ann';
class=50;index=1;
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('net-epoch-50.mat');%取出我们的最终训练模型,这里只训练了50次
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);
disp([subdir(best+2).name ' ' bestScore]);

(3)如何在MatConvNet下训练自己的数据_第4张图片

你可能感兴趣的:(matlab,matconvnet)