关于matconvnet的几个小程序(2)用制作的滑动窗口数据进行训练

本文介绍了一个使用CNN进行苹果图片分类的项目,详细说明了数据准备、网络构建与训练过程,并展示了如何利用训练好的模型进行预测。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考:参考链接1
之前的滑动窗口准备2
构建自己的神经网络的三步:
1.准备数据;
2.设计神经网络的结构;
3.设置参数,用数据训练网络。

我们的数据有两类,单个苹果(1文件夹)和非单个苹果(0文件夹)。
首先是将文件中的图片导入、格式化、划分训练集测试集交叉验证集,求取均值后以.mat的格式存储在磁盘上。
cnn_setup_data.m:

function imdb =cnn_setup_data(datadir)  
%输入为存放多个分类的文件夹地址,输出为imdb结构体
inputSize =[64,64]; %输入图像尺寸 
subdir=dir(datadir); %
imdb.images.data=[]; 
imdb.images.labels=[];  
imdb.images.set = [] ;  
imdb.meta.sets = {'train', 'val', 'test'} ;  
image_counter=0; 
trainratio=0.8;%0.8的数据用于训练,0.2的数据用于测试
for i=3:length(subdir)  
    imdb.meta.classes(i-2) = {subdir(i).name}; %提取类名
    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)); %把图像imresize成inputSize大小的输入,建议查一下imresize函数的用法,我们原始的图像不必一定是严格的64*64,因为···
        img=single(img);  
        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)=2;%前0.8用于训练。后0.2用于验证,分别在set里打上“1”和“2”的标签。一般来说,1是训练,2是验证,3是测试。但是我发现把第二部分打上’2‘和’3‘是等价的?最后迭代的结果图都一模一样···
        end  
    end  
end  

dataMean=mean(imdb.images.data,4); %如前所知,第四个维度是存储的图像,所以求均值
imdb.images.data = single(bsxfun(@minus,imdb.images.data, dataMean)) ;  
imdb.images.data_mean = single(dataMean);%哦哦知道这个地方的作用了
end

第二部分即是初始化神经网络,
这一部分包含了对神经网络各个层的设计(每一层的种类、维度、正则化以及在训练中的一些参数等。)

function net = cnn_mnist_init(varargin)  
% 初始化一个类似于mnist的CNN 
opts.batchNormalization = true ; %进行归一化操作 
opts.networkType = 'simplenn' ; %网络类型为simplenn
opts = vl_argparse(opts, varargin) ;%  

rng('default');  
rng(0) ;  

f=1/100 ;  
net.layers = {} ;  
net.layers{end+1} = struct('type', 'conv', ...  
                           'weights', {{f*randn(5,5,3,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', 'conv', ...  
                           'weights', {{f*randn(10,10,20,50, 'single'),zeros(1,50,'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', 'conv', ...  
                           'weights', {{f*randn(10,10,50,500, 'single'),  zeros(1,500,'single')}}, ...  
                           'stride', 1, ...  
                           'pad', 0) ;  
net.layers{end+1} = struct('type', 'relu') ;  
net.layers{end+1} = struct('type', 'conv', ...  
                           'weights', {{f*randn(1,1,500,4, 'single'), zeros(1,4,'single')}}, ...  
                           'stride', 1, ...  
                           'pad', 0) ;  
net.layers{end+1} = struct('type', 'softmaxloss') ;  

% optionally switch to batch normalization  
if opts.batchNormalization  
  net = insertBnorm(net, 1) ;  
  net = insertBnorm(net, 4) ;  
  net = insertBnorm(net, 7) ;  
end  

% Meta parameters  
net.meta.inputSize = [64 64] ;  
net.meta.trainOpts.learningRate = 0.0005 ;  
net.meta.trainOpts.numEpochs = 30 ;  
net.meta.trainOpts.batchSize = 200 ;  

% Fill in defaul values  
net = vl_simplenn_tidy(net) ;  

% Switch to DagNN if requested  
switch lower(opts.networkType)  
  case 'simplenn'  
    % done  
  case 'dagnn'  
    net = dagnn.DagNN.fromSimpleNN(net, 'canonicalNames', true) ;  
    net.addLayer('top1err', dagnn.Loss('loss', 'classerror'), ...  
      {'prediction', 'label'}, 'error') ;  
    net.addLayer('top5err', dagnn.Loss('loss', 'topkerror', ...  
      'opts', {'topk', 5}), {'prediction', 'label'}, 'top5err') ;  
  otherwise  
    assert(false) ;  
end  

% --------------------------------------------------------------------  
function net = insertBnorm(net, l)  
% --------------------------------------------------------------------  
assert(isfield(net.layers{l}, 'weights'));  
ndim = size(net.layers{l}.weights{1}, 4);  
layer = struct('type', 'bnorm', ...  
               'weights', {{ones(ndim, 1, 'single'), zeros(ndim, 1, 'single')}}, ...  
               'learningRate', [1 1 0.05], ...  
               'weightDecay', [0 0]) ;  
net.layers{l}.biases = [] ;  
net.layers = horzcat(net.layers(1:l), layer, net.layers(l+1:end)) ;

这里写图片描述

第三步为训练网络:

function [net, info] = cnn_mnist(varargin)  


run(fullfile(fileparts(mfilename('fullpath')),...  
  '..', '..', 'matlab', 'vl_setupnn.m')) ;  

opts.batchNormalization = true;  %??
opts.networkType = 'simplenn' ;  
[opts, varargin] = vl_argparse(opts, varargin) ;  

sfx = opts.networkType ;  
if opts.batchNormalization, sfx = [sfx '-bnorm'] ; end  
datadir='E:\学习\机器学习\matconvnet-1.0-beta20\photos\multi-label';  
opts.expDir = fullfile(vl_rootnn, 'data', ['mnist-zyp-' sfx]) ;  
[opts, varargin] = vl_argparse(opts, varargin) ;  

%opts.dataDir = fullfile(vl_rootnn, 'data', 'mnist') ;  
opts.imdbPath = fullfile(opts.expDir, 'imdb.mat');  
opts.train = struct() ;  
opts = vl_argparse(opts, varargin) ;  
if ~isfield(opts.train, 'gpus'), opts.train.gpus = []; end;  

% --------------------------------------------------------------------  
%                                                         Prepare data  
% --------------------------------------------------------------------  

net = cnn_mnist_init('batchNormalization', opts.batchNormalization, ...  
                     'networkType', opts.networkType) ;  

if exist(opts.imdbPath, 'file')  
  imdb = load(opts.imdbPath) ;  
else  
  imdb=cnn_setup_data(datadir);  
  mkdir(opts.expDir) ;  
  save(opts.imdbPath, '-struct', 'imdb') ;  
end  

net.meta.classes.name = arrayfun(@(x)sprintf('%d',x),1:2,'UniformOutput',false) ;  

% --------------------------------------------------------------------  
%                                                                Train  
% --------------------------------------------------------------------  

switch opts.networkType  
  case 'simplenn', trainfn = @cnn_train ;  
  case 'dagnn', trainfn = @cnn_train_dag ;  
end  

[net, info] = trainfn(net, imdb, getBatch(opts), ...  
  'expDir', opts.expDir, ...  
  net.meta.trainOpts, ...  
  opts.train, ...  
  'val', find(imdb.images.set == 3)) ;  
net.meta.data_mean = imdb.images.data_mean;  
net.layers{end}.class = [1] ;  

% --------------------------------------------------------------------  
function fn = getBatch(opts)  
% --------------------------------------------------------------------  
switch lower(opts.networkType)  
  case 'simplenn'  
    fn = @(x,y) getSimpleNNBatch(x,y) ;  
  case 'dagnn'  
    bopts = struct('numGpus', numel(opts.train.gpus)) ;  
    fn = @(x,y) getDagNNBatch(bopts,x,y) ;  
end  

% --------------------------------------------------------------------  
function [images, labels] = getSimpleNNBatch(imdb, batch)  
% --------------------------------------------------------------------  
images = imdb.images.data(:,:,:,batch) ;  
labels = imdb.images.labels(1,batch) ;  

% --------------------------------------------------------------------  
function inputs = getDagNNBatch(opts, imdb, batch)  
% --------------------------------------------------------------------  
images = imdb.images.data(:,:,:,batch) ;  
labels = imdb.images.labels(1,batch) ;  
if opts.numGpus > 0  
  images = gpuArray(images) ;  
end  
inputs = {'input', images, 'label', labels} ;

训练结果:
这里写图片描述

这里写图片描述

四、应用-测试程序

%初次运行一次,之后不再运行
%[net_bn, info_bn] = cnn_mnist('batchNormalization', true);
load('F:\matconvnet-1.0-beta23\data\apple-fry-simplenn-bnorm\imdb.mat');
im=imread('F:\matconvnet-1.0-beta23\oneapple.png');
im=imresize(im,[64 64 ]);
imshow(im);
im = single(im);
im = im - images.data_mean;
res = vl_simplenn(net_bn, im,[],[],...
                      'accumulate', 0, ...
                      'mode', 'test', ...
                      'backPropDepth', inf, ...
                      'sync', 0, ...
                      'cudnn', 1) ;
scores = res(11).x(1,1,:);
[bestScore, best] = max(scores);
switch best
    case 1
        title('判断结果:不是苹果');
    case 2
        title('判断结果:1个苹果');
%     case 3
%         title('判断结果:2个苹果');
%     case 4 
%         title('判断结果:3个苹果');
end

运行结果:
这里写图片描述

这时候,我们可以和之前的滑动窗口联系起来,
主程序:

% setup MatConvNet  
run  matlab/vl_setupnn  
% load the pre-trained CNN  
%net = dagnn.DagNN.loadobj(load('imagenet-googlenet-dag.mat')) ;
net = load('F:\matconvnet-1.0-beta23\data\apple-fry-simplenn-bnorm\imdb.mat'); 
net.mode = 'test' ;  
a = zeros(1,1);  
a = input('Please input the pngs name.\n','s');  
a = ['photos/',a];  

% load and preprocess an image  
im = imread(a);  

addpath test;  
[ out_image,n ] = var_slide( im, 100, 100, 100, 100, net  );figure;imshow(out_image);  
saveas(gcf,'myfig.jpg');

运行时如果直接套用会出现很多问题,原因是我们自己训练出来的imdb.mat和imagenet-googlenet-dag.mat结构上有很多不同之处。
主要问题出在slide.m上,比如:
这里写图片描述

这里写图片描述
这时我们最好的办法是重写slide.m,也很简单,只需做一些简单的修改,
置信度设为0.1时,23333333
这里写图片描述
问题出在分类上,分成了四类。后头重新训练···懒得写了,有空再继续。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值