caffe的Matlab接口的使用方法以及会出现的问题

编译MatCaffe

使用如下命令编译MatCaffe

make all matcaffe
 
 
  • 1
  • 1

之后,你可以用以下命令测试MatCaffe:

make mattest
 
 
  • 1
  • 1

如果你在运行上面命令时,遇到如下错误:libstdc++.so.6 version ‘GLIBCXX_3.4.15’ not found,说明你的Matlab库不匹配。你需要在启动Matlab之前运行如下命令:

export LD_LIBRARY_PATH=/opt/intel/mkl/lib/intel64:/usr/local/cuda/lib64
export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6
 
 
  • 1
  • 2
  • 1
  • 2

在Caffe根目录启动Matlab之后需要增加路径:

addpath ./matlab
 
 
  • 1
  • 1

你可以使用savepath来保存Matlab搜索路径,这样下次就不用再添加路径了。


使用MatCaffe

MatCaffe 和 PyCaffe 的使用方法很相似。

下面将用一个例子来解释MatCaffe的具体使用细节,假设你已经下载了BVLC CaffeNet,并且在caffe根目录启动matlab。

model = './models/bvlc_reference_caffenet/deploy.prototxt';
weights = './models/bvlc_reference_caffenet/bvlc_reference_caffenet.caffemodel';

 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

1.设置模式和设备

模式和设备的设置必须在创建一个net或solver之前。

使用CPU:

caffe.set_mode_cpu();
 
 
  • 1
  • 1

使用GPU并指定gpu_id:

caffe.set_mode_gpu();
caffe.set_device(gpu_id);
 
 
  • 1
  • 2
  • 1
  • 2

2.创建一个网络并访问它的layers和blobs

1.创建网络

创建一个网络:

net = caffe.Net(model, weights, 'test'); % create net and load weights
 
 
  • 1
  • 1

或者

net = caffe.Net(model, 'test'); % create net but not load weights
net.copy_from(weights); % load weights
 
 
  • 1
  • 2
  • 1
  • 2

它可以创建一个如下的net对象:

  Net with properties:
           layer_vec: [1x23 caffe.Layer]
            blob_vec: [1x15 caffe.Blob]
              inputs: {'data'}
             outputs: {'prob'}
    name2layer_index: [23x1 containers.Map]
     name2blob_index: [15x1 containers.Map]
         layer_names: {23x1 cell}
          blob_names: {15x1 cell}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

两个containers.Map对象可以通过layer或者blob的名称找到对应的索引。

2.访问blob

你可以访问网络中的每一个blob,将data的blob填充为全一:

net.blobs('data').set_data(ones(net.blobs('data').shape));
 
 
  • 1
  • 1

data的blob中数值全部乘以10:

net.blobs('data').set_data(net.blobs('data').get_data() * 10);
 
 
  • 1
  • 1

注意:因为Matlab是以1作为起始单元,且以列为主,在Matlab中使用四维blob为[width, height, channels, num],且width是最快的维度,而且要在BGR通道。而且Caffe使用单精度浮点型数据。如果你的数据不是浮点型的,set_data将会自动转换为single。

3.访问layer

你也可以访问网络的每一层,以便你作一些网络调整。例如把conv1参数乘以10:

net.params('conv1', 1).set_data(net.params('conv1', 1).get_data() * 10); % set weights
net.params('conv1', 2).set_data(net.params('conv1', 2).get_data() * 10); % set bias
 
 
  • 1
  • 2
  • 1
  • 2

你也可以如下代码:

net.layers('conv1').params(1).set_data(net.layers('conv1').params(1).get_data() * 10);
net.layers('conv1').params(2).set_data(net.layers('conv1').params(2).get_data() * 10);
 
 
  • 1
  • 2
  • 1
  • 2

4.保存网络

你仅仅需要如下代码保存网络:

net.save('my_net.caffemodel');
 
 
  • 1
  • 1

5.获得一层的类型(string)

layer_type = net.layers('conv1').type;
 
 
  • 1
  • 1

3.前向和后向计算

前向和后向计算可以使用net.forward或者net.forward_prefilled实现。函数net.forward将一个包含输入blob(s)的cell数组作为输入,并输出一个包含输出blob(s)的cell数组。函数net.forward_prefilled将使用输入blob(s)中的已有数据进行计算,没有输入数据,没有输出数据。

在通过一些方法(如:data = rand(net.blobs('data').shape);)产生输入数据后,你可以运行:

res = net.forward({data});
prob = res{1};
 
 
  • 1
  • 2
  • 1
  • 2

或者

net.blobs('data').set_data(data);
net.forward_prefilled();
prob = net.blobs('prob').get_data();
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

后向计算使用net.backward或者net.backward_prefilled,并且把get_dataset_data替换为get_diffset_diff。在通过一些方法(例如prob_diff = rand(net.blobs('prob').shape);)产生输出blobs的梯度后,你可以运行:

res = net.backward({prob_diff});
data_diff = res{1};
 
 
  • 1
  • 2
  • 1
  • 2

或者

net.blobs('prob').set_diff(prob_diff);
net.backward_prefilled();
data_diff = net.blobs('data').get_diff();
 
 
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

然而,如上的后向计算并不能得到正确的结果,因为Caffe默认网络不需要后向计算。为了获取正确的后向计算结果,你需要在你的网络prototxt文件中设置force_backward: true

在完成前向和后向计算之后,你可以获得中间blobs的data和diff。例如,你可以在前向计算后获取pool5的特征。

4.Reshape

假设你想要运行1幅图像,而不是10幅时:

net.blobs('data').reshape([227 227 3 1]); % reshape blob 'data'
net.reshape();
 
 
  • 1
  • 2
  • 1
  • 2

然后,整个网络就reshape了,此时net.blobs('prob').shape应该是[1000 1];

5.训练网络

假设你按照ImageNET Tutorial的方法创建了训练lmdb和验证lmdb,产生一个solver并且在ILSVRC 2012 分类数据集上训练:

solver = caffe.Solver('./models/bvlc_reference_caffenet/solver.prototxt');
 
 
  • 1
  • 1

这样可以创建一个solver对象:

  Solver with properties:

          net: [1x1 caffe.Net]
    test_nets: [1x1 caffe.Net]
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

训练代码:

solver.solve();
 
 
  • 1
  • 1

如果只想训练迭代1000次:

solver.step(1000);
 
 
  • 1
  • 1

来获取迭代数量:

iter = solver.iter();
 
 
  • 1
  • 1

来获取这个网络:

train_net = solver.net;
test_net = solver.test_nets(1);
 
 
  • 1
  • 2
  • 1
  • 2

假设从一个snapshot中恢复网络训练:

solver.restore('your_snapshot.solverstate');
 
 
  • 1
  • 1

6.输入和输出

caffe.io类提供了基本的输入函数load_imageread_mean。例如,读取ILSVRC 2012 mean文件(假设你已经通过运行./data/ilsvrc12/get_ilsvrc_aux.sh下载imagenet例程辅助文件)

mean_data = caffe.io.read_mean('./data/ilsvrc12/imagenet_mean.binaryproto');
 
 
  • 1
  • 1

为了读取Caffe例程图片,并且resize到[width, height],且假设width = 256; height = 256;

im_data = caffe.io.load_image('./examples/images/cat.jpg');
im_data = imresize(im_data, [width, height]); % resize using Matlab's imresize
 
 
  • 1
  • 2
  • 1
  • 2

注意:width是最快的维度,通道为BGR,与Matlab存取图片的一般方式不一样。如果你不想要使用caffe.io.load_image,且想自己导入一幅图片:

im_data = imread('./examples/images/cat.jpg'); % read image
im_data = im_data(:, :, [3, 2, 1]); % convert from RGB to BGR
im_data = permute(im_data, [2, 1, 3]); % permute width and height
im_data = single(im_data); % convert to single precision
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

你也可以看一下caffe/matlab/demo/classification_demo.m文件,了解如何将输入图片crop成多个输入块。

你可以查看caffe/matlab/hdf5creation,了解如何通过Matlab读和写HDF5数据。但不提供额外的数据输出函数,因为在Matlab本身已经具有了强大的功能。

7.清除nets和solvers

调用caffe.reset_all()来清理你所创建的所有的solvers,和stand-alone nets。

################################################################################


本节内容主要是实现,利用matlab调用caffe中的matlab接口,实现matlab环境下caffe 的使用


GCC降级

编译matlab

运行demo


(一)matlab支持gcc较低版本,而ubuntu14.04支持gcc4.8,所以要先将gcc降级

我的是matlab2013a,支持的是gcc4.4.x系列,所以我就安装gcc4.4,然后降级

1.安装gcc4.4

[plain]  view plain  copy
  1. sudo apt-get install -y gcc-4.4  
  2. sudo apt-get install -y g++-4.4  

2.降级

[plain]  view plain  copy
  1. cd /usr/bin  
  2. sudo rm gcc  
  3. sudo ln -s gcc-4.4 gcc  
  4. sudo rm g++  
  5. sudo ln -s g++-4.4 g++  

3.验证版本

[plain]  view plain  copy
  1. gcc  -v  



(二)编译matlab

cd 到caffe目录下

[plain]  view plain  copy
  1. sudo make matcaffe  

测试

[plain]  view plain  copy
  1. <span style="font-family:SimSun;font-size:18px;"><strong>make mattest</strong></span>  


出现问题


出现问题的原因:编译caffe时候的库与编译matlab相关的库版本不一样

有一个会在matlab目录下/usr/local/MATLAB/R2013a/sys/os/glnxa64;另外一个在/usr/lib/x86_64-Linux-gnu/libstdc++.so.6

解决措施:

1.(推荐)将matlab下的libstdc++.so.6链接到系统用的那个库的文件去

[plain]  view plain  copy
  1. export LD_LIBRARY_PATH=/usr/local/MATLAB/R2013a/sys/os/glnxa64  
[plain]  view plain  copy
  1. export LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6  

2.(不推荐)将matlab下的libstdc++.so.6 更改名称为libstd++.so.6_back(让matlab找不到这个,但是为了安全还是备份一下吧),这样在执行matlab编译的时候会自动去找系统用的库


执行测试

[plain]  view plain  copy
  1. make  mattest  



(三)caffe中提供了matlab的demo

An ILSVRC image classification demo is in caffe/matlab/demo/classification_demo.m (you need to download BVLC CaffeNet from Model Zoo to run it).

打开matlab,切换目录到caffe-master/matlab/demo目录下,拷贝cat.jpg到此目录下

运行classification_demo.m,得到1000*1的输出 因为imagnet一共1000类,输出的1000维就是每一类的输出,最大值就是对应的类别

[plain]  view plain  copy
  1. <span style="font-family:SimSun;font-size:18px;">run('classification_demo.m')</span>  


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值