Fork me on GitHub

MatConvNet 练习使用CNN

  • 首先在 VGG Convolutional Neural Networks Practical 官网上做了四个练习。现在代码可以直接用
  • 但是在using pretrained models中有个错,net模型不一致,待解决!直接复制代码有问题;但是下载数据后运行Exe05是可以运行的。
net = load('data/imagenet-vgg-verydeep-16.mat') ;
vl_simplenn_display(net) ;

% obtain and preprocess an image
im = imread('peppers.png') ;
im_ = single(im) ; % note: 255 range

% im_ = imresize(im_, net.normalization.imageSize(1:2)) ;
% im_ = im_ - net.normalization.averageImage ;

im_ = imresize(im_, net.meta.normalization.imageSize(1:2)) ;
im_ = im_ - net.meta.normalization.averageImage ; % 操作的数组维度必须匹配


% run the CNN
res = vl_simplenn(net, im_) ;

% show the classification result
scores = squeeze(gather(res(end).x)) ;
[bestScore, best] = max(scores) ;

figure(1) ; clf ; imagesc(im) ;
title(sprintf('%s (%d), score %.3f',...
  net.classes.description{best}, best, bestScore)) ;
  • 一、卷积

Y = VL_NNCONV(X, F, B)计算图像堆x的卷积,F是卷积核,B是偏置。X=H*W*D*N, (H,W)是图像的高和宽,D是图像深度(特征频道的数目,例彩色就是3),N是堆中图像的数目。F=FW*FH*FD*K ,(FH,FW)是卷积核的大小,FD是卷积核的深度,须与D一致,或能整除D,K是卷积核的数目。针对一幅图像来说,卷积的公式为:

       其中ij分别代表图像的高和宽,d”则代表了卷积核的数目,从而对应d”个输出。
  [DZDX, DZDF, DZDB] = VL_NNCONV(X, F, B, DZDY)计算映射到DZDY上的块的导数。这是反向传播中应用的梯度计算公式。
  另外还有一些具体的变量设置。包括Stride=(sh,sw)是步长,即在卷积过程中每次移动的大小,这也决定了最后输出的大小,pad是补0的大小,表示为:


则最终输出的大小为:

  [注]:1、在Matconvnet中并不区分全连接层和卷积层,而认为前者是后者的一种特殊情况。

     2、在Matconvnet中有Filter groups(即滤波组)的概念,意思是说vl_nnconv允许对输入x的通道进行分组,且每组应用不同子集的过滤器。groups=D/D',D是图像深度,D'是滤波器的深度,从而第一组可包括输入的1、2,,,D'维度,第二组包括输入的D'+1,,,2D',以此类推,但输出的大小是不变的。

  •   二、卷积转换(反卷积)

  Y = VL_NNCONVT(X, F, B)计算CNN的卷积转换,即进行卷积的反操作,其输入输出形式与上同。由于卷积支持输入补0输出进行下采样,因此反卷积支持输入上采样输出裁剪。

 二、卷积转换(反卷积)

  Y = VL_NNCONVT(X, F, B)计算CNN的卷积转换,即进行卷积的反操作,其输入输出形式与上同。由于卷积支持输入补0输出进行下采样,因此反卷积支持输入上采样输出裁剪。

  三、空间池化

  Y = VL_NNPOOL(X, POOL)或Y = VL_NNPOOL(X, [POOLY, POOLX])对输入x的每个通道进行池化操作,池化的方式可以是求patch的最大值或平均值。同卷积相同,池化也支持pad和Stride操作,但pad有时是补负无穷。

  四、激活函数

  RELU函数:y = vl_nnrelu(x,dzdy,varargin),在leak=0时,表达式为

  Sigmoid函数:out = vl_nnsigmoid(x,dzdy)

  这里只给出了正向传播时的函数表达式,反向传播的(涉及dzdy)具体表达式可以看程序。

  五、归一化

  1、VL_NNNORMALIZE :CNN Local Response Normalization (LRN)

  Local Response Normalization是对一个局部的输入区域进行的归一化,从表达式来看,也就是对每一个groups(前文)里的输入的相应子集进行归一化。表达式如下;其中的参数包括PARAM = [N KAPPA ALPHA BETA]

  其中G(k)是对应通道k的输入相应子集,在程序中定义为 Q(k) = [max(1, k-FLOOR((N-1)/2)), min(D, k+CEIL((N-1)/2))];

  2、VL_NNBNORM CNN 实现批次归一化

   Y = VL_NNBNORM(X,G,B),这里XY均是4维张量,第4维T表示每批次处理的大小。标准化的表达式为


 
 3.VL_NNSPNORM实现空间归一化
 
 y = vl_nnspnorm(x, param, dzdy),PARAM = [PH PW ALPHA BETA];即对每个通道先进行池化操作,池化的方式为取平均,然后在进行归一化操作。其表达式为

  4、VL_NNSOFTMAX CNN softmax

  Y = vl_nnsoftmax(X,dzdY):在一个groups(前文)中应用softmax函数,softmax函数可以看做一个激活函数和一个归一化操作的联合

   六、损失和比较

  1、 [y1, y2] = vl_nnpdist(x, x0, p, varargin)计算每个向量x与目标x0之间的距离,定义为:

  2. Y = vl_nnloss(X,c,dzdy,varargin)

 

  • 抽象出来这个模型结构就像下面这样: 

这里写图片描述

可以这个模型的结构依次为:输入-卷积1-pool1-卷积2-pool2-卷积2-relu-卷积4(也可以是全连接层)-sofrmax分类。

根据代码中的结构定义,我们也可以推算出每一层的输出大小(上述图)。

这里需要注意的是,这个网络层的设计大小一定要吻合。比如,经过一系列的卷积pool后,到全连接层时,输入一定要是1*1*X*X,且上一层的map,和下一层的卷积数map一定要一样。比如输入为28*28*1,那么第一个卷积核是5*5*1*20,这个1就是上一层的只有一个图。再往下走卷积为5*5*20*50,这里为什么是20,因为上一层的map有20个。一次类推,计算到最后正好为1*1*500,这样才可以全连接层。如果你自己设计网络,自己计算一下一定要保证后面全连接层时输入为1*1*X*X,否则会训练错误。

  • 先运行mnist-demo数据集没有下载下来,然后自己下载放在文件夹里面结果有错;不知道什么原因;晚上在实验室电脑跑,一下子网络就好了,成功运行了;代码结果如下:
  • 后面再来详细的研究代码:
  • matconvnet不能把类别标签设置为“0”,否则对其他一些类别不能再识别;而本次作业为二分类问题,这里,男性对应于标签“1”,女性对应于标签“2”。
  • “top1err”是“softmax”层输出过程中最高得分项对应错误率,而由于是二分类问题,“top5err”(前5项得分最高项对应错误率)是没有意义的。
  • 由于是二分类问题,最后分类器一般“logistic regression”,而“softmax”是“logistic regression”升级版,支持多分类问题。由于,我们网络最后是全连接到2个神经元上,其中“1”代表女性,“2”代表男性(需要注意的是,运用“softmax”,matconvnet类别标签是不支持0的),并且通过“softmax”进行分类。

参考:还有很多变体,用来测试人脸,辨别左右手等

深度学习(十三):Matconvnet详解与实验手写体数据库

如何在MatConvNet下训练自己的数据 plate车牌

Matconvnet学习笔记

 CNN神经网络层次分析

学习网络的使用多层BP算法的原理

Softmax回归

posted @ 2017-06-29 10:56  ranjiewen  阅读(1418)  评论(0编辑  收藏  举报