此篇講述在matlab中,如何將訓練好的model用於圖像分類。將以mnist為例,主要用到caffe-master\matlab\demo 下的classification_demo.m ,可參考我之前的博客 【caffe-windows】 caffe-master 之 classfication_demo.m 超詳細分析 (http://blog.csdn.net/u011995719/article/details/54135189)
首先貼大神的博客:http://blog.csdn.net/zb1165048017/article/details/52447109
我的實驗是參考了他的步驟,相比之前的mnist分類,這里增加了減均值操作,所以需要對配置文件做出相應的更改,同時也可以學習一下如何求取訓練集的均值文件,以及減均值操作。
前期准備: 下載測試圖片(鏈接:http://pan.baidu.com/s/1o7NySMu密碼:bead 源自:http://blog.csdn.net/zb1165048017/article/details/52217772),放到文件夾caffe-master\matlab\demo 下
第一步: 算出均值,得到均值文件mean.binaryproto
在caffe-master\examples\mnist下創建 文本文檔,后綴更改為 .bat 復制以下code:
..\..\Build\x64\Release\compute_image_mean.exe-backend=lmdb ../../examples\mnist\mnist_train_lmdb mean.binaryproto
Pause
如圖:
雙擊運行,則在caffe-master\examples\mnist下會得到 mean.binaryproto
(PS: 至於mnist數據獲取此處不再重復,請參照我之前的博客:http://blog.csdn.net/u011995719/article/details/54023085)
需要注意的是,當將mnist數據轉換成leveldb的時候,需要對應的更改以上code(imdb改為leveldb)
第二步:訓練model ,需要改動3個文件lenet.prototxt 、lenet_solver.prototxt、lenet_train_test.prototxt
因為要做減均值操作,所以要對lenet_solver.prototxt和lenet_train_test.prototxt進行更改,為了避免和之前的沖突,這里復制了一份,然后分別重命名為lenet_solver_mean.prototxt 和lenet_train_test_mean.prototxt
lenet_solver_mean.prototxt較lenet_solver.prototxt更改處如下:
net:"../../examples/mnist/lenet_train_test_mean.prototxt"
如圖:
lenet_train_test_mean.prototxt較lenet_train_test.prototxt 更改處如下:
phase: TRAIN
}
transform_param {
mean_file:"../../examples/mnist/mean.binaryproto"
scale: 0.00390625
}
phase: TEST
}
transform_param {
mean_file:"../../examples/mnist/mean.binaryproto"
scale: 0.00390625
}
如圖:
請注意自己數據的格式,是LMDB還是LEVELDB 。
最后更改lenet.prototxt,更改處如下:
input_param { shape: { dim:1 dim: 1 dim: 28 dim: 28 } }
這里存在一個問題就是為什么是64,是bug?還是什么? 沒搞沒明白
更改好了以上三個文件,就可以在caffe-master\examples\mnist下創建 .bat 文件訓練了,具體如圖:
訓練好之后會有lenet_iter_10000.caffemodel,這個就是后面在matlab里要用到的模型了
第三步:創建標簽文件 mnist_synset_words.txt
在caffe-master\matlab\demo下創建文本文檔復制以下代碼:
0
1
2
3
4
5
6
7
8
9
保存,為了區別不同的標簽文件,此處更改了文件名為mnist_synset_words,因此在后面的matlab程序中讀取時候需要做相應更改
如圖:
第四步:編輯兩個matlab文件,一個是classification_demo.m的修改,一個是調用classification_demo的主函數
在caffe-master\matlab\demo下創建m文件,保存為mnist_test.m 具體code如下:
clear
clc
close all
im=imread(['binarybmp/5.bmp']); % 讀取圖片
figure;imshow(im); %顯示圖片
[scores, maxlabel] = mnist_CF(im', 1); %獲取得分 第二個參數0為CPU,1為GPU
scores ;
maxlabel ;
figure;plot(scores); % 畫出得分情況
axis([0, 10, -0.1, 0.5]); % 坐標軸范圍
grid on % 有網格
fid = fopen('mnist_synset_words.txt', 'r');
i=0;
while ~feof(fid) % while ~feof 表示 若 未讀到文件末尾 則 繼續 循環
i=i+1;
lin = fgetl(fid); % fgetl 從已經打開的文件中讀取一行,並且丟掉末尾的換行符
lin = strtrim(lin); % strtrim 從字符串或cell開頭去掉空格
if(i==maxlabel)
fprintf('The maxlabel of %d in label txt is %s\n',i,lin)
break
end
end
在caffe-master\matlab\demo下創建m文件,保存為mnist_CF.m
具體code如下:
function [scores, maxlabel] = mnist_CF(im, use_gpu)
%此處為添加路徑,確保能找到caffe-master\matlab\+caffe
if exist('../+caffe', 'dir')
addpath('../..');
else
error('Please run this demo from caffe/matlab/demo');
end
% 設置CPU or 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 = '../../examples/mnist/';
net_model = [model_dir 'lenet.prototxt'];
net_weights = [model_dir 'lenet_iter_10000.caffemodel'];
phase = 'test'; % 指出網絡狀態為test,防止使用dropout
if ~exist(net_weights, 'file')% 檢測模型是否存在,不存在則報錯提醒
error('Please download CaffeNet from Model Zoo before you run this demo');
end
net = caffe.Net(net_model, net_weights, phase); % 初始化網絡
% oversample
mean_data = caffe.io.read_mean('../../examples/mnist/mean.binaryproto'); %
scale = 0.00390625;
im = double(im);
im = (im-mean_data)*scale;
input_data = {im};
scores = net.forward(input_data); % 將數據輸入到網絡,進行前向傳播,得出分數,scores是一個細胞元組
scores = scores{1}; % scores 是 1000*10 的矩陣 10是對應了10個crop圖片
scores = mean(scores, 2); % 對10個crop進行求平均
[~, maxlabel] = max(scores); % 再找出最大的那一個
% 重置 caffe
caffe.reset_all();
第五步 : 運行mnist_test.m即可
PS:很容易出現路徑不正確的問題,出錯先看看是否路徑不正確。其次就是這里我更改了好多文件名,所以相應的文件里面也要做修改,最好用ctrl+c ctrl+v的方法,免得書寫錯誤。