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類中每一類的具體名字是什麼。截圖如下:

然後運行classification.bat文件,看看輸出的top5結果吧。

從上面可以看到,預測出來的結果爲: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下結果顯示爲:
我們看到最大的概率值爲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中國社區也已經成立了喲,大家可以到裏面查資料,說不定你遇到的問題上面已經有了答案了,附帶一下網址:

然後貌似opencv也支持讀取caffemodel文件了,但是在正式發佈的opencv3.1中沒有這個模塊,需要自己添加。把這個環境配置好,肯定是用C++童鞋的福音,深度學習在C++中的可視化也會更方便。以後有時間會加一下這方面的內容。
發佈了37 篇原創文章 · 獲贊 19 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章