caffe for windows 下使用caffemodel 实现cifar10的图像分类

在上一篇的博客中,已经训练出来了迭代了4000次的caffemodel模型,那么怎样使用这个模型来应用于实际的图像分类中呢?其实也是很简单的,因为前辈已经写好了.cpp文件,我们只需要生成.cpp文件对应的.exe然后调用即可。还有,如果已经配置好了matcaffe,也可以使用matlab来实现图像分类。

一、c++实现图像分类

在tools文件夹下面,有classification文件,该代码即实现图像分类。
可以在Solution下新建一个cuda project,导入tools文件夹中的classification.cpp文件,配置环境。编译,通过之后会看到bin\文件夹下面有一个classification.exe。
我们看看源代码中,介绍怎样使用这个可执行文件classification的。
  if (argc != 6) {
    std::cerr << "Usage: " << argv[0]
              << " deploy.prototxt network.caffemodel"
              << " mean.binaryproto labels.txt img.jpg" << std::endl;
    return 1;
  }

  caffe::GlobalInit(&argc, &argv);

  string model_file   = argv[1];
  string trained_file = argv[2];
  string mean_file    = argv[3];
  string label_file   = argv[4];
  Classifier classifier(model_file, trained_file, mean_file, label_file);

  string file = argv[5];
上面是classification.cpp文件中main函数的前几行代码,我们可以看到我们需要网络结构的deploy.prototxt文件,需要caffemodel模型文件,均值文件,标签文件和待分类的图片。获取它们的路径。将路径作为参数即可。(本示例中全部使用的绝对路径,当然相对路径也是可以的,而且更简洁方便)
新建一个.bat,输入以下内容保存。
classification.exe H:\happynearcaffe\caffe-windows-master\caffe-windows-master\examples\cifar10\cifar10_quick.prototxt H:\happynearcaffe\caffe-windows-master\caffe-windows-master\examples\cifar10\cifar10_quick_iter_4000.caffemodel H:\happynearcaffe\caffe-windows-master\caffe-windows-master\examples\cifar10\mean.binaryproto H:\happynearcaffe\caffe-windows-master\caffe-windows-master\examples\cifar10\synset_words.txt H:\happynearcaffe\caffe-windows-master\caffe-windows-master\examples\cifar10\dog2.jpg
pause
从上面的.bat的内容中也可以看到,我所要进行分类的是一幅dog图片,这里一定要注意,因为我一次只预测一幅图像,所以batchsize应当设置为1.(应当在网络结构中修改过来)。待分类图像dog的原始大小为32*32,它的原始图像为:

synset_words.txt是标签文件,告诉我们分类的cifar10的10类中每一类的具体名字是什么。截图如下:
caffe for windows 下使用caffemodel 实现cifar10的图像分类_第1张图片
然后运行classification.bat文件,看看输出的top5结果吧。
caffe for windows 下使用caffemodel 实现cifar10的图像分类_第2张图片
从上面可以看到,预测出来的结果为:75%的概率是dog,10%的概率是truck......还算精确地了。

二、matlab实现图像分类

首先将当前目录设置在caffe-windows-master\matlab\demo下,然后新建一个classification_cifar.m文件,加入以下代码:
% Add caffe/matlab to you Matlab search PATH to use matcaffe
if exist('../+caffe', 'dir')
  addpath('..');
else
  error('Please run this demo from caffe/matlab/demo');
end

% Set caffe mode
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 = '../../examples/cifar10/';
net_model = [model_dir 'cifar10_quick.prototxt'];
net_weights = [model_dir 'cifar10_quick_iter_4000.caffemodel'];
phase = 'test'; % run with phase test (so that dropout isn't applied)
if ~exist(net_weights, 'file')
  error('Please download CaffeNet from Model Zoo before you run this demo');
end

% Initialize a network
net = caffe.Net(net_model, net_weights, phase);

if nargin < 1
  % For demo purposes we will use the cat image
  fprintf('using caffe/examples/images/dogs.jpg as input image\n');
  im = imread('../../examples/images/dog2.jpg');
end
input_data = {prepare_image(im)};
scores = net.forward(input_data);
scores = scores{1};
scores = mean(scores, 2);  % take average scores over 10 crops

[~, maxlabel] = max(scores);

% call caffe.reset_all() to reset caffe
caffe.reset_all();

其中用到了对图像预处理的prepare_image函数,所以加入以下代码预处理图片:
function im_data = prepare_image(im)
d = load('./cifar10_mean.mat');
mean_data = d.image_mean;
IMAGE_DIM = 32;
im_data = im(:, :, [3, 2, 1]);  % permute channels from RGB to BGR
im_data = permute(im_data, [2, 1, 3]);  % flip width and height
im_data = single(im_data);  % convert from uint8 to single
im_data = imresize(im_data, [IMAGE_DIM IMAGE_DIM], 'bilinear');  % resize im_data
im_data = im_data - mean_data;  % subtract mean_data (already in W x H x C, BGR)
end
这里有一个cifar10_mean.mat的均值文件,我们在使用C++进行图片分类的时候均值文件从leveldb中生成的.binaryproto文件,所以要想得到cifar10_mean.mat的均值文件,我们需要将而知文件转成.mat。在caffe-windows-master\matlab\+caffe文件夹下新建一个read_mean.m文件(本来就有的,就直接将里面的内容注释掉也可以),然后新添加matlab代码:
%   Read binary proto file to mat
clear
clc
mean_file = 'H:\Gastric_DB\train_mean.binaryproto';
CHECK(ischar(mean_file), 'mean_file must be a string');
CHECK_FILE_EXIST(mean_file);
image_mean = caffe_('read_mean', mean_file);
将获得的.mat均值文件保存即可。
运行,classification_cifar.m文件,得到了结果,command window下结果显示为:
caffe for windows 下使用caffemodel 实现cifar10的图像分类_第3张图片
我们看到最大的概率值为0.8661,对应的标签为6,从 synset_words.txt中查找到,第六个标签确实为dog,分类结果是合理的。
但是有一点我们发现,c++分类的概率值与matlab分类的概率值是不一样的,matlab稍微好于C++,在使用的网络结构prototxt,网络模型参数caffemodel和均值、预测图片一致的情况下,出现这个问题也是正常的,不必大惊小怪,我的猜测是预测图像在预处理环节上可能是不一样的,所以导致结果的差异。要想知道原因需要自己审读源代码,理解图像处理的过程。

三、PS:本篇博客结束语

本人也是刚刚接触深度学习,对caffe代码的理解程度还不够,所以博客基本只介绍运行示例的步骤过程,要想加深对caffe,对深度学习的认识,肯定需要理解caffe的源码的。
caffe在windows上运行会出现各种各样的BUG,有时候挺折磨人的,建议在linux下使用caffe吧,苦海无涯,回头是岸,可是我回头也看不到岸了,所以就一直把基于windows下的caffe用下去了。以后估计还是得要转到linux下。
caffe中国社区也已经成立了哟,大家可以到里面查资料,说不定你遇到的问题上面已经有了答案了,附带一下网址:
caffecn中国社区网址链接

然后貌似opencv也支持读取caffemodel文件了,但是在正式发布的opencv3.1中没有这个模块,需要自己添加。把这个环境配置好,肯定是用C++童鞋的福音,深度学习在C++中的可视化也会更方便。以后有时间会加一下这方面的内容。

你可能感兴趣的:(caffe学习)