前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【MatConvnet速成】MatConvnet图像分类从模型自定义到测试

【MatConvnet速成】MatConvnet图像分类从模型自定义到测试

作者头像
用户1508658
发布2019-07-28 15:05:51
9680
发布2019-07-28 15:05:51
举报
文章被收录于专栏:有三AI有三AI有三AI

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环境和多余精力的可以学习一下,学习成本很低,技多不压身嘛。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-03-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 有三AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
批量计算
批量计算(BatchCompute,Batch)是为有大数据计算业务的企业、科研单位等提供高性价比且易用的计算服务。批量计算 Batch 可以根据用户提供的批处理规模,智能地管理作业和调动其所需的最佳资源。有了 Batch 的帮助,您可以将精力集中在如何分析和处理数据结果上。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档