matconvnet使用教学

研究生期间,一直都在使用MatConvNet这个框架,感觉需要来个小总结以及小教学。

关于部署

从官网下载最新版,当前是1.0-beta-23,matlab中用到mex,所以部署一下VS环境即可,按照官网来,先CPU模式vl_nncomplie()一下,然后再根据GPU命令编译一道。注意的是:1.cuda tool kit的目录,默认在c:program/toolkit…/cuda/v7.5/之类的,然后cudnn用cudnn5,放在matconvnet的matlab下,新建local的文件夹。还需要把cudnn5/bin/cudnn5.dll放到mex文件夹下面。如果遇到round function的问题,可以根据网上教的,把round function写在matconvnet的cuda源代码里面。

关于matconvnet使用

大部分可以参照官方网站还有一个Manuel pdf,剩下的主要阅读项目的matlab代码,cuda代码暂时不需要涉及。主要分为simplenn net and DAG net, simple的是单向线性网,而DAG是多向图,从而方便设计更复杂的网络框架结构。当然暂时来说,matconvnet对于RNN的支持不太够,但在拟合deep learning来说还是很有用的。

设计一个深度学习的程序包括:1.生成训练集 2.设置程序的默认参数 3.初始化网络的结构以及参数 4.训练数据导入和预处理 5.训练部署和优化过程 6.网络测试实验

关于线性网络simplenn

初始化网络
1.导入matconvnet: run(fullfile(fileparts(mfilename('fullpath')),'..','matconvnet-master','matlab','vl_setupnn.m'));
2.初始化网络: net.layers={}
3.加层:net.layers{end+1} = struct('type','conv','weights',{},'params','',{});
4.放入simplenn网络,并添加默认参数: net = vl_simplenn_tidy(net)

训练网络
[net,info] = cnn_train(net,imdb,getBatch(),'expDir',expDir,'train',find(imdb.images.set==1),'val',find(imdb.images.set==2),'learningRate',lr,'theta',weight_theta,'batchSize',bz,'modelname',modelname,'gpus',1);

梯度更新 accumulate_gradients(state,net,res,opts,batchSize,mmap)

定义损失函数(如L2) Y = vl_nnloss(X,c,dzdy,varargin)
if nargin<=2 || isempty(dzdy)
t=((X-c).^2)/2;
Y=t(:);
else
Y = bsxfun(@minus,X,c).*dzdy;
end

线性测试过程: load('mynet.mat')
net = vl_simplenn_tidy(net);
net.layers = net.layers(1:end-1);
res = vl_simplenn(net,input,[],[],'mode','test');

关于训练数据生成与格式
一般是cell,只要在输入层和objective function处(最后层)对应维度即可。meta分为train,val,test。用cell images包括images.input images.label images.set,其中set的来区分训练集和验证集。

#### 关于有向图DAG net
初始化 net.layers={};
net=dagnn.DagNN.fromSimpleNN(net,'canonicalNames',true);
net.addLayer(name,block,input,output,params)

由于Multi-input and multi-output,需要定义好网络的variables和params,让params连接起来.

在数据导入和getBatch函数时,也需要注意名字对上。

MatConvNet Manual

经典DAG
由于最近研究上,一般使用复杂的网络结构比较多,如VGG Net,ResNet,RNN等,传统的AlexNet, Linear Net已经在表达能力上有所欠缺。其中x为输入输出的变量variables(feature maps),f为layer name, w为该层的参数(params),这些元素组成了网络,而DAG的指向是有向任意的,只要输入输出的维度对应上的话。

SimpleNN BP
在网络训练过程中的BP,会创建一个反向的Net用于记录误差导数的值,但结构是完全逆向的,这样完整一次正向和反向才能最后更新网络的参数。

DAG BP
上图是DAG BP的算法:1.将variables x按DAG顺序排列 2.对网络forward pass 3.按照对应x的大小初始化dx 4.遍历每一层:a.根据index找到x,找不到则下一个循环 b.用残差的导数算式更新derivative of x

DAG BP structure
类似simplenn BP, DAG BP过程中也需要完整逆向构建DAG网络,当完成一次正传和反传以后再进行梯度的更新(这时候可以适应多种梯度更新策略)。

针对实现细节,可以直接去研究代码,卷积操作类似CAFFE,先把image通过im2row转化成tensor来加速卷积操作的。

坚持分享,支持原创