MatConvNet对自己的图片分两类及提取图片特征

来源:互联网 发布:矩阵a的 1次方 编辑:程序博客网 时间:2024/04/30 00:40

MatConvNet对自己的图片分两类也可以讲是使用MatConvNet:工具箱可以直接去Github上下载,http://www.studyai.cn/deep_learn/matconvnet/functions/index.html点击打开链接这个网站讲解了MatConvNet的每个函数  很详细!

然而我自己仿照example写分2类的程序 运行还是不断报错。。。最后放弃了自己瞎搞 又去Github上下载了别人使用MatConvNet做车牌识别的例子,是另一个工具箱:MatConvNet-mr-master

打开这个工具箱是这样:

文件夹ann_plate2是我自己加的

先自己测试下这个工具箱:运行cnn_plate_init再运行cnn_plate,对了cnn_plate改成自己路径 还有cnn_plate_setup_data的这几行记得不要注释掉:

就这样!

最终生成的模型就在...\matconvnet-1.0-beta20\data\primerplate9.2-baseline文件夹里面!证明了是可以运行成功的!但太慢了,我就改了cnn_plate_init的迭代次数和batchsize的个数:结果快了很多,这个工具箱如果github上没有 可以在这里下载:

 http://download.csdn.net/detail/wd1603926823/9620127点击打开链接    记得要先下载matconvnet-1.0-beta20工具箱才能用这个工具箱!

/////////////////////////////////////////////////看不见分界线//////////////////////////////////////////////////////////////

测试完工具箱想正确的 可以使用后,接下来我就按照这个工具箱改成我的分2类:

我的图片放在:

我要分2类 所以2个文件夹

1,首先我改了这里:

放图片的路径和最终保存模型的文件夹名字  改了这2处

2,然后我改了这里(不改也行):

迭代次数改成了10次:


3,还改了这里:

使用GPU 还有是2分类 不是multiclass

接下来就可以了:结果:

因为我只有1040张总样本  所以效果不好也正常  我只求不报错!去data文件夹下可以看到刚刚训练好的模型数据:


然后我利用最后一次的模型提取另一个文件夹下的图片特征。。。

run(fullfile('D:\MATLAB_code\matconvnet-1.0-beta20\matlab\vl_setupnn.m')) ;net = load('D:\MATLAB_code\matconvnet-1.0-beta20\data\Bchannel9.5-baseline\net-epoch-100.mat');feat = [];rgbImgList = {};facepath='D:\MATLAB_code\matconvnet-1.0-beta20\data\toExtractFeature\';newpath=facepath;for j=0:1039       k=j+1;       facepath=newpath;       facepath=strcat(facepath,num2str(j));       facepath=strcat(facepath,'.bmp');       oriImg=imread(facepath);       oriImg=imresize(oriImg,[20 20]);       tmpNam =strcat(num2str(j),'.bmp');      if size(oriImg, 3) == 1          rgbImg= oriImg;          im_ = single(rgbImg) ; % note: 255 range          im_ = imresize(im_, net.net.meta.inputSize(1:2)) ;          im_ = im_ - net.net.meta.normalization.averageImage ;          res = vl_simplenn(net.net, im_) ;          featVec = res(7).x;          featVec = featVec(:);          feat = [feat; featVec'];          fprintf('extract %d image\n\n',j);          rgbImgList{k,1} = tmpNam;          clear rgbImg;      else          fprintf('the model need 3 channels but you put in 1 channel images\n');      endendlabels=zeros(1,1040);labels(624:end)=1;feat = normalize1(feat);save('NoVGGBchannel9.5.mat','feat', 'rgbImgList','labels');

其实我还是想用已知的著名的模型如VGG在新数据上重新训练得到属于自己的模型  按照https://github.com/vlfeat/matconvnet/issues/218 点击打开链接 这样对VGG微调  得到新VGG模型 结果我的训练有问题 虽然没报错 就是运行这3个程序:

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,2, 'single'),zeros(1,2,'single')}}, ...%    'stride', 1, ...%    'pad', 0) ;% net.layers{end+1} = struct('type', 'softmaxloss') ;%%%%%%%%%%%%%%%%%%%%%%%%%%use pre-trained model re-train  https://github.com/vlfeat/matconvnet/issues/218 netprimer = load('D:\MATLAB_code\matconvnet-1.0-beta20\CNN-for-Image-Retrieval-master\imagenet-vgg-f.mat'); net.layers=netprimer.layers(1:end-2); net.layers{end+1} = struct('type', 'conv', ...     'weights', {{0.05*randn(3,3,4096,2, 'single'),zeros(1,2,'single')}}, ...     'stride', [1,1], ...     'pad', [0,0,0,0]) ; net.layers{end+1} = struct('type', 'softmaxloss') ; net.meta.inputSize = [224 224 3] ;%%%%%%%%%%%%%%%%%%%%%%%%%%% 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 =10 ;% Fill in defaul valuesnet = vl_simplenn_tidy(net) ;end
然后运行这个:

function [net, info] = cnn_plate()run(fullfile('D:\MATLAB_code\matconvnet-1.0-beta20\matlab\vl_setupnn.m')) ;%datadir='E:\MachineLearning\caffe\caffe-windows-master\platerecognition\data\platerecognition\chars2';%datadir='D:\MATLAB_code\matconvnet-1.0-beta20\data\Bchannel8.23';datadir='F:\mypic\人工分类8.17\myReclassify0.2';%datadir='D:\MATLAB_code\my_MatConvNet-mr-master\MatConvNet-mr-master\ann_plate2';opts.expDir = fullfile(vl_rootnn, 'data', 'VGGBchannel9.5-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') ;endnet=cnn_plate_init();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) ;endfunction [images, labels]  = getSimpleNNBatch(imdb, batch)    images = imdb.images.data(:,:,:,batch) ;    labels = imdb.images.labels(1,batch) ;    if opts.train.gpus > 0        images = gpuArray(images) ;    endendend
其中:
function imdb =cnn_plate_setup_data(datadir)inputSize =[224,224,3];%inputSize =[20,20,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;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        endenddataMean=mean(imdb.images.data,4);imdb.images.data = single(bsxfun(@minus,imdb.images.data, dataMean)) ;imdb.images.data_mean = dataMean;end
结果一个白板 应该是在cnntrain时一次都不满足train条件:



可是具体问题出在哪里?真的好想直接调用VGG模型然后在自己的新图片数据上微调得到属于自己的VGG 然后用来分类测试或提取特征!可是问题出在哪里??

推荐个网址http://www.studyai.cn/点击打开链接    http://blog.sina.com.cn/s/blog_837f83580102vwv4.html

//////////////////////////////////////////看不见分界线///////////////////////////////////////////////////////////////////////

根据http://blog.csdn.net/willard_yuan/article/details/44861487点击打开链接根据这个人的用已知模型提取图片特征,彩图或灰度图都可以:

% 用已知模型去提取图片特征run(fullfile('D:\MATLAB_code\matconvnet-1.0-beta20\matconvnet-1.0-beta20\matlab\vl_setupnn.m')); %换成你的vl_setupnn.m具体路径%想提取特征的图片所在路径path_imgDB = 'D:\MATLAB_code\matconvnet-1.0-beta20\matconvnet-1.0-beta20\CNN-for-Image-Retrieval-master\database';addpath(path_imgDB);addpath tools;%换成你下载的imagenet-vgg-f.mat具体路径net = load('imagenet-vgg-f.mat') ; % Step 2 LOADING IMAGE AND EXTRACTING FEATUREimgFiles = dir(path_imgDB);imgNamList = {imgFiles(~[imgFiles.isdir]).name};clear imgFiles;imgNamList = imgNamList';numImg = length(imgNamList);feat = [];k = 0;rgbImgList = {};%因为模型要求输入是3通道的 所以先检测如果是灰度图 就变成3通道的 再提取  如果是彩图 就直接提取特征for i = 1:numImg   oriImg = imread(imgNamList{i, 1}); 
   %oriImg=imresize(oriImg,[224 224]);  %如果你想直接用VGG模型 而你的图片不是224X224时就直接这样好了   tmpNam = imgNamList{i, 1};   if size(oriImg, 3) == 3       k = k+1;       im_ = single(oriImg) ; % note: 255 range       im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;       im_ = im_ - net.meta.normalization.averageImage ;       res = vl_simplenn(net, im_) ;       featVec = res(19).x;       featVec = featVec(:);       feat = [feat; featVec'];       fprintf('extract %d image\n\n', i);       rgbImgList{k,1} = tmpNam;   else       rgbImg(:,:,1) = oriImg;       rgbImg(:,:,2) = oriImg;       rgbImg(:,:,3) = oriImg;       k = k+1;       im_ = single(rgbImg) ; % note: 255 range       im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;       im_ = im_ - net.meta.normalization.averageImage ;       res = vl_simplenn(net, im_) ;       featVec = res(19).x;       featVec = featVec(:);       feat = [feat; featVec'];       fprintf('extract %d image\n\n', i);       rgbImgList{k,1} = tmpNam;       clear rgbImg;   endend%归一化feat = normalize1(feat);save('Feat4096Norml.mat','feat', 'rgbImgList', '-v7.3');
其中那个mat可以由语句:urlwrite(...'http://www.vlfeat.org/matconvnet/models/imagenet-vgg-f.mat',...'imagenet-vgg-f.mat'); 进行下载!或者直接去http://www.vlfeat.org/matconvnet/models/点击打开链接   这里快速下载!结果可以看到是一个特征矩阵feat:每一张图片的特征是一个4096维的行向量:

我用这个程序提取我的文件夹下图片特征  我的图片以0.bmp、1.bmp、2.bmp...这样命名  用上面的程序发现提取的特征是乱序的 因为它rgbImgList里是按0.bmp、1.bmp、1001.bmp...999.bmp这样来读取的  而我的文件夹前623张都属于第一类   后面都属于第2类 这样读取不方便我找到原来的标签  所以我改成了按顺序读取并提取特征然后按顺序保存  如下:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%按文件夹图片顺序提取对应图片特征并保存  用vgg模型run(fullfile('D:\MATLAB_code\matconvnet-1.0-beta20\matlab\vl_setupnn.m')) ;net = load('D:\MATLAB_code\matconvnet-1.0-beta20\CNN-for-Image-Retrieval-master\imagenet-vgg-f.mat');feat = [];rgbImgList = {};facepath='D:\MATLAB_code\matconvnet-1.0-beta20\data\toExtractFeature\';newpath=facepath;for j=0:1039       k=j+1;       facepath=newpath;       facepath=strcat(facepath,num2str(j));       facepath=strcat(facepath,'.bmp');       oriImg=imread(facepath);       oriImg=imresize(oriImg,[224 224]);       tmpNam =strcat(num2str(j),'.bmp');      if size(oriImg, 3) == 3          im_ = single(oriImg) ; % note: 255 range          im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;          im_ = im_ - net.meta.normalization.averageImage ;          res = vl_simplenn(net, im_) ;          featVec = res(19).x;          featVec = featVec(:);          feat = [feat; featVec'];          fprintf('extract %d image\n\n', j);          rgbImgList{k,1} = tmpNam;      else          rgbImg(:,:,1) = oriImg;          rgbImg(:,:,2) = oriImg;          rgbImg(:,:,3) = oriImg;          im_ = single(rgbImg) ; % note: 255 range          im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;          im_ = im_ - net.meta.normalization.averageImage ;          res = vl_simplenn(net, im_) ;          featVec = res(19).x;          featVec = featVec(:);          feat = [feat; featVec'];          fprintf('extract %d image\n\n',j);          rgbImgList{k,1} = tmpNam;          clear rgbImg;       endendlabels=zeros(1,1040);labels(624:end)=1;feat = normalize1(feat);save('FeatureBchannel9.5.mat','feat', 'rgbImgList','labels');
结果:

这就是按顺序来了!

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

有时候当训练出模型后,提取特征时,当运行到第二句:


打开看这个net:

class是一个向量 而不是一个数标量,如果继续提取特征会报错,这里就手动把net.net.layers{1,8}.class=2  因为我是2类  所以这样改   几类就改成几   或者把type改成softmax 一样的效果  接下来就不报错了   我觉得这样改怪怪的  但我同事说他看到一个demo就是把type改成softmax  我试了两种方法都可以。。。。。其实我之前自己训练的class自动就是2  而不是一个向量  不需要改 直接提取特征  我觉得那样才是好的。如果需要改动,那我总感觉是人为改变的。。。。。。。但如果报错还是这样改吧!


2 0
原创粉丝点击