Matlab caffe 具体使用方法
caffe 的matlab接口网络上的资料比较少,这里把几个基本的操作简单介绍,主要包括:
classification_demo的简单介绍
卷积核的显示
各层数据的显示
classification_demo的简单介绍
本文的前提是要编译好caffe的matlab接口,这个问题网上有很多的博文介绍,我觉得我不能够比他们说的更清楚,所以这里不再介绍,如果出现错误:Invalid MEX-file “…….caffe_.mexw64”找不到指定的模块 记得把3rdparty\bin中的dll文件,拷贝到 “caffe-windows-master\matlab+caffe\private“中,我出现了这个问题。现在我们就可以好好的看下这个例子。
classification_demo.m需要文件bvlc_reference_caffenet.caffemodel,可以到http://dl.caffe.berkeleyvision.org/ 下载,下载后放到“models/bvlc_reference_caffenet/”中。
首先有确定是用cpu还是gpu,同时要注意调用gpu的方法。
if exist('use_gpu', 'var') && use_gpu
caffe.set_mode_gpu();
gpu_id = 0; % we will use the first gpu in this demo
caffe.set_device(gpu_id);
else
caffe.set_mode_cpu();
end
指定网络结构和相应的参数。
model_dir = '../../models/bvlc_reference_caffenet/';
net_model = [model_dir 'deploy.prototxt'];
net_weights = [model_dir 'bvlc_reference_caffenet.caffemodel'];
接下来就可以创建一个网络。
net = caffe.Net(model, weights, 'test'); % create net and load weights
或者
net = caffe.Net(model, 'test'); % create net but not load weights
net.copy_from(weights); % load weights
简单的看一下这个net
Net (带属性):
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}
net.blob_names'
'data' 'conv1' 'pool1' 'norm1' 'conv2' 'pool2' 'norm2' 'conv3' 'conv4' 'conv5' 'pool5' 'fc6' 'fc7' 'fc8' 'prob'
net.layer_names'
'conv1' 'relu1' 'pool1' 'norm1' 'conv2' 'relu2' 'pool2' 'norm2' 'conv3' 'relu3' 'conv4' 'relu4' 'conv5' 'relu5' 'pool5' 'fc6' 'relu6' 'drop6' 'fc7' 'relu7' 'drop7' 'fc8' 'prob'
其中两个map的作用就如他们的名字一样,matlab中各layer和blob都有相应的index,而对于我们来说对他们的具体名字更加清楚,这两个map就给出了从名字到index的一个映射。例如我想获得网络conv2的参数
nth_layer = net.layer_vec(net.name2layer_index('conv2'));
nth_layer_blob1_data = nth_layer.params(1).get_data();
也可以访问网络的每一层,以便作一些网络调整。例如把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
你也可以如下代码:
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);
卷积核的显示
接下来就可以做一个简单的显示网络参数的工作
sizeB = size(nth_layer_blob1_data);% 5 5 48 256
GridL = ceil(sqrt(sizeB(4)));
scale = 4;
border = 2;
sizeB(1) = sizeB(1) * scale;
sizeB(2) = sizeB(2) * scale;
background = zeros((border+sizeB(1))*GridL+border,(border+sizeB(2))*GridL+border,1);
minV = min(nth_layer_blob1_data(:));
maxV = max(nth_layer_blob1_data(:));
nth_layer_blob1_data = (nth_layer_blob1_data - minV) / (maxV - minV);
for i = 1:sizeB(4)
x = ceil(i / GridL);
y = mod(i - 1,GridL) + 1;
patch = imresize(nth_layer_blob1_data(:,:,1,i),[sizeB(1) sizeB(2)],'nearest');
patch = (patch - min(patch(:))) / (max(patch(:)) - min(patch(:)));
background(border + (x-1)*(border+sizeB(1)) + 1 : x*(border+sizeB(1)),border + (y-1)*(border+sizeB(2)) + 1 : y*(border+sizeB(2)),:) = patch;
end;
figure(1);
imshow(background);
colormap('jet');
colorbar();
以下是前三个卷积核的显示结果:
这里要注意,只有在我们做过了前向预测之后才能去观察blob中的数据,不然全部都是0.
各层结果的显示
scores = net.forward(input_data);
这是我们已经做完了前向传播,也就是说已经可以看每一层输出的结果了。
nth_layer_blob1_data=net.blobs('conv1').get_data();
%卷积结果的可视化
sizeB = size(nth_layer_blob1_data);
GridL = ceil(sqrt(sizeB(3)));
scale = 4;
border = 2;
sizeB(1) = sizeB(1) * scale;
sizeB(2) = sizeB(2) * scale;
background = zeros((border+sizeB(1))*GridL+border,(border+sizeB(2))*GridL+border);
minV = min(nth_layer_blob1_data(:));
maxV = max(nth_layer_blob1_data(:));
nth_layer_blob1_data = (nth_layer_blob1_data - minV) / (maxV - minV);
for i = 1:sizeB(3)
x = ceil(i / GridL);
y = mod(i - 1,GridL) + 1;
patch = imresize(nth_layer_blob1_data(:,:,i,1),[sizeB(1) sizeB(2)],'nearest');
patch = (patch - min(patch(:))) / (max(patch(:)) - min(patch(:)));
background(border + (x-1)*(border+sizeB(1)) + 1 : x*(border+sizeB(1)),border + (y-1)*(border+sizeB(2)) + 1 : y*(border+sizeB(2)),:) = patch;
end;
figure();
imshow(background);
colormap('jet');
colorbar();
这里要注意一点就是layer中参数与blob中的数据的维度对应关系要看清晰。
前两层的convblob数据以及poolblob中的数据显示结果。
实验中的原始图像: