(轉)如何使用caffe的MATLAB接口


編譯MatCaffe

轉自: http://blog.csdn.net/ws_20100/article/details/50525879

使用如下命令編譯MatCaffe

make all matcaffe
  • 1

之后,你可以用以下命令測試MatCaffe:

make mattest
  • 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

在Caffe根目錄啟動Matlab之后需要增加路徑:

addpath ./matlab
  • 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.設置模式和設備

模式和設備的設置必須在創建一個net或solver之前。

使用CPU:

caffe.set_mode_cpu();
  • 1

使用GPU並指定gpu_id:

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

2.創建一個網絡並訪問它的layers和blobs

1.創建網絡

創建一個網絡:

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

或者

net = caffe.Net(model, 'test'); % create net but not load weights net.copy_from(weights); % load weights
  • 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

兩個containers.Map對象可以通過layer或者blob的名稱找到對應的索引。

2.訪問blob

你可以訪問網絡中的每一個blob,將data的blob填充為全一:

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

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

net.blobs('data').set_data(net.blobs('data').get_data() * 10);
  • 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

你也可以如下代碼:

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

4.保存網絡

你僅僅需要如下代碼保存網絡:

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

5.獲得一層的類型(string)

layer_type = net.layers('conv1').type;
  • 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

或者

net.blobs('data').set_data(data); net.forward_prefilled(); prob = net.blobs('prob').get_data();
  • 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

或者

net.blobs('prob').set_diff(prob_diff); net.backward_prefilled(); data_diff = net.blobs('data').get_diff();
  • 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

然后,整個網絡就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

這樣可以創建一個solver對象:

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

訓練代碼:

solver.solve();
  • 1

如果只想訓練迭代1000次:

solver.step(1000);
  • 1

來獲取迭代數量:

iter = solver.iter();
  • 1

來獲取這個網絡:

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

假設從一個snapshot中恢復網絡訓練:

solver.restore('your_snapshot.solverstate');
  • 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

為了讀取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

注意: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

你也可以看一下caffe/matlab/demo/classification_demo.m文件,了解如何將輸入圖片crop成多個輸入塊。

你可以查看caffe/matlab/hdf5creation,了解如何通過Matlab讀和寫HDF5數據。但不提供額外的數據輸出函數,因為在Matlab本身已經具有了強大的功能。

7.清除nets和solvers

調用caffe.reset_all()來清理你所創建的所有的solvers,和stand-alone nets。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM