深度学习 9. MatConvNet 利用mnist的model来训练自己的data。MatConvNet 训练自己数据(一)。

版权声明:本文为博主原创文章,转载必须注明是转载文章和原文超链接以及作者信息。 https://blog.csdn.net/qq_20259459/article/details/60139586

本文为原创文章转载必须注明本文出处以及附上 本文地址超链接  以及 博主博客地址http://blog.csdn.net/qq_20259459  和 作者邮箱[email protected] )。

(如果喜欢本文,欢迎大家关注我的博客或者动手点个赞,有需要可以邮件联系我)



接上一篇文章(阅读上一篇文章:http://blog.csdn.net/qq_20259459/article/details/54602056 



在介绍完MatConvNet相关的Code之后,现在开始介绍如何使用这个toolbox来训练自己的data。


首先我想介绍如何利用mnist的模型来训练自己的data。在网上我看到有很多人在用imagenet的模型来训练自己的数据,写的都很好,但是好像很少有人写mnist的模型所以我想写一下。当然后面也会更新imagenet相关的介绍。


在我自己学习使用的过程中我发现mnist的模型似乎并不可以使用长方形的input。否则在训练多类误差的过程中会出现维度的错误,当然我也认为是可以修改的,不过与其修改不如直接使用imagenet模型更为便捷。


训练自己的数据的时候,有一些问题需要注意,否则没法运行。

一、input不一定要为正方形,但是在softmax层的INPUT需要为1*1的数据。

二、根据input的大小需要增加layers以确保最后的softmax的数据size为1*1。

三、所需要训练的数据必须有完整的test和train的部分,可自己分配一般比例为3比7。

四、每次训练结束之后如需改变input需要手动删除以创建的train的结构体。

五、在创建label的时候一定要注意test和train的需要分开以免调用的时候出现错位影响结果。

六、当运行可以的时候要做的就是调整,需要通过改变相关的变数和网络的层数以得到最佳的结果。



今天我先写一下通过改变mnist的大小作为自己的新的数据来尝试第一次训练,以证明程序可行性。

主要Code(尝试扩大2倍):

function cnn_mnist_NNclass(varargin)

warning off

% CNN_MNIST  Demonstrated MatConNet on MNIST

%% 运行初始化CNN网络
% run( fullfile(fileparts(mfilename('fullpath')), '../matlab/vl_setupnn.m') ) ;
run('C:\Users\Desktop\matconvnet-1.0-beta23\matconvnet-1.0-beta23\matlab/vl_setupnn.m') ;


%% 初始化网络相关数据
opts.dataDir = 'data/mnist' ;                               %   data的标签的路径
opts.expDir = 'data/mnist-baseline' ;                       %   data的路径
opts.imdbPath = fullfile(opts.expDir, 'imdb.mat');          %   data的fullfile=data/mnist-baseline/imdb.mat
opts.train.batchSize = 100 ;                                %   选择batch大小
opts.train.numEpochs = 100 ;                                %   选择epoch个数
opts.train.continue = true ;                                %   选择判断条件
% opts.train.useGpu = true ; 
opts.train.gpus = []; 
% opts.train.gpus = 1;                                        %   选择是否使用GPU
opts.train.learningRate = 0.001 ;                           %   选择CNN学习率
opts.train.expDir = opts.expDir ;                           %   训练数据的保存位置
opts = vl_argparse(opts, varargin);                         %   调用vl_argparse函数
opts.train.subsetSize = 1e4;                                %   statsogk 子图的大小


%% 准备数据
% --------------------------------------------------------------------
%                                                         Prepare data
% --------------------------------------------------------------------

if exist(opts.imdbPath)                                     %   如果存在imdb.mat
  imdb = load(opts.imdbPath) ;                              %       载入数据
else                                                        %   如果不存在
  imdb = getMnistImdb(opts) ;                               %       获得数据
  mkdir(opts.expDir) ;                                      %       调用mkdir
  save(opts.imdbPath, '-struct', 'imdb') ;                  %       保存在路径下
end

% Use a subset of the images for faster training. 
if opts.train.subsetSize > 0                                %   如果子图大小大于0
    imdb = getSubset(imdb,opts);                            %       调用getSubset
end


%% 定义CNN网络
% Define a network similar to LeNet
f=1/100 ;                                                                   %   初始化一个f
net.layers = {} ;                                                           %      初始化一个空layer
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C1层
                           'filters', f*randn(5,5,1,20, 'single'), ...      %      filter大小(5*5*1)*20
                           'biases', zeros(1, 20, 'single'), ...            %   
                           'stride', 1, ...                                 %      移动为1
                           'pad', 0) ;                                      %      没有pad
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...                             %       pooling类型为max
                           'pool', [2 2], ...                               %       filter大小为2*2
                           'stride', 2, ...                                 %       移动为2
                           'pad', 0) ;                                      %       没有pad
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C2层
                           'filters', f*randn(5,5,20,50, 'single'),...
                           'biases', zeros(1,50,'single'), ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C3层
                           'filters', f*randn(4,4,50,100, 'single'),...
                           'biases', zeros(1,100,'single'), ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C2层
                           'filters', f*randn(3,3,100,500, 'single'),...
                           'biases', zeros(1,500,'single'), ...
                           'stride', 1, ...
                           'pad', 0) ;
net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
                           'method', 'max', ...
                           'pool', [2 2], ...
                           'stride', 2, ...
                           'pad', 0) ;
% % % % net.layers{end+1} = struct('type', 'conv', ...                              %%   定义C2层
% % % %                            'filters', f*randn(3,3,500,1000, 'single'),...
% % % %                            'biases', zeros(1,1000,'single'), ...
% % % %                            'stride', 1, ...
% % % %                            'pad', 0) ;
% % % % net.layers{end+1} = struct('type', 'pool', ...                              %%   定义pooling层
% % % %                            'method', 'max', ...
% % % %                            'pool', [2 2], ...
% % % %                            'stride', 2, ...
% % % %                            'pad', 0) ;
net.layers{end+1} = struct('type', 'relu') ;                                %%  定义relu层

net.layers{end+1} = struct('type', 'conv', ...                              %%  定义FC层
                           'filters', f*randn(1,1,500,10, 'single'),...     %       大小为1*1的全连接,厚度为500,10次
                           'biases', zeros(1,10,'single'), ...              %       
                           'stride', 1, ...                                 %       移动为1
                           'pad', 0) ;                                      %       没有pad
net.layers{end+1} = struct('type', 'softmaxloss') ;                         %   定义SMFC


%% Train 部分
% --------------------------------------------------------------------
%                                                                Train
% --------------------------------------------------------------------

% Take the mean out and make GPU if needed
imdb.images.data = bsxfun(@minus, imdb.images.data, mean(imdb.images.data,4)) ;     %   减去mean值
% if opts.train.useGpu
if opts.train.gpus                                                                  %   如果使用GPU
    imdb.images.data = gpuArray(imdb.images.data) ;                                 %   读取data
end

%% 调用CNN_Train
[ net, info ] = cnn_train(net, imdb, @getBatch, opts.train, 'val', find(imdb.images.set == 3)) ;


%% 得到data和相应的label。
% --------------------------------------------------------------------
function [im, labels] = getBatch(imdb, batch)
% --------------------------------------------------------------------
im = imdb.images.data(:,:,:,batch) ;
labels = imdb.images.labels(1,batch) ;


%% 打开data文件
% --------------------------------------------------------------------
function imdb = getMnistImdb(opts)
% --------------------------------------------------------------------
files = {'train-images-idx3-ubyte', ...
         'train-labels-idx1-ubyte', ...
         't10k-images-idx3-ubyte', ...
         't10k-labels-idx1-ubyte'} ;

     
%% 获得data
mkdir(opts.dataDir) ;
for i=1:4
  if ~exist(fullfile(opts.dataDir, files{i}), 'file')
    url = sprintf('http://yann.lecun.com/exdb/mnist/%s.gz',files{i}) ;
    fprintf('downloading %s\n', url) ;
    gunzip(url, opts.dataDir) ;
  end
end

f=fopen(fullfile(opts.dataDir, 'train-images-idx3-ubyte'),'r') ;
x1=fread(f,inf,'uint8');
% x1=zscore(x1);
fclose(f) ;
x1=permute(reshape(x1(17:end),28,28,60e3),[2 1 3]) ;
x11 = x1(:,:,1);
x12 = x1(:,:,2);
x13 = x1(:,:,3);
x11 = imresize(x11,2);
x12 = imresize(x12,2);
x1 = cat(3,x11,x12,x13);

f=fopen(fullfile(opts.dataDir, 't10k-images-idx3-ubyte'),'r') ;
x2=fread(f,inf,'uint8');
% x2=zscore(x2);
fclose(f) ;
x2=permute(reshape(x2(17:end),28,28,10e3),[2 1 3]) ;
x21 = x2(:,:,1);
x22 = x2(:,:,2);
x23 = x2(:,:,3);
x21 = imresize(x21,2);
x22 = imresize(x22,2);
x2 = cat(3,x21,x22,x23);

f=fopen(fullfile(opts.dataDir, 'train-labels-idx1-ubyte'),'r') ;
y1=fread(f,inf,'uint8');
fclose(f) ;
y1=double(y1(9:end)')+1 ;

f=fopen(fullfile(opts.dataDir, 't10k-labels-idx1-ubyte'),'r') ;
y2=fread(f,inf,'uint8');
fclose(f) ;
y2=double(y2(9:end)')+1 ;


imdb.images.data = single(reshape(cat(3, x1, x2),56,56,1,[])) ;
imdb.images.labels = cat(2, y1, y2) ;                                       % 得到[ y1 y2 ]
imdb.images.set = [ones(1,numel(y1)) 3*ones(1,numel(y2))] ;
imdb.meta.sets = {'train', 'val', 'test'} ;
imdb.meta.classes = arrayfun(@(x)sprintf('%d',x),0:9,'uniformoutput',false) ;

% ------------------------------------------------------------------------------
function imdb = getSubset(imdb,opts)
% ------------------------------------------------------------------------------
assert(opts.train.subsetSize <= nnz(imdb.images.set == 1),...
        'Subset size is bigger than the total train set size')
inds = find(imdb.images.set == 1);   % indices  must be from the train set
inds = randsample(inds, length(inds)-opts.train.subsetSize );
imdb.images.labels(inds) = [];
imdb.images.set(inds) = [];
imdb.images.data(:,:,:,inds) = [];


结果:




虽然并没有训练结束,大家可以看到至少我们得到了正确的结果。

先写到这里,大家可以根据上面的code理解一下。

后面会持续更新。


本文为原创文章转载必须注明本文出处以及附上 本文地址超链接  以及 博主博客地址http://blog.csdn.net/qq_20259459  和 作者邮箱[email protected] )。

(如果喜欢本文,欢迎大家关注我的博客或者动手点个赞,有需要可以邮件联系我)

猜你喜欢

转载自blog.csdn.net/qq_20259459/article/details/60139586