用訓練好的caffemodel做前向

2021-07-28 12:49:04 字數 4436 閱讀 4456

這篇部落格是之前部落格:用 caffe 做回歸(下)的後續。在該部落格中訓練得到了caffemodel檔案,那麼在實際應用中,我們需要利用訓練好的caffemodel做前向傳輸,得到網路的輸出,本文就是來解決這乙個問題的。因為之前的部落格是以 回歸 任務作為例子,所以本文中繼續使用回歸任務作為例子,分類任務也是類似的。

相對來說,用python介面會方便很多(畢竟一些底層的c++都被封裝起來了)!也許耐心掌握了c++以及python兩種做前向的方法之後,你會更加理解「人生苦短,我用python!」的道理。不過還是前面說到的,從c++的角度可以對自己所用的工具有更加深刻的而理解。

下面正式進入正題:

首先,我們明確一下,在拿到乙個caffemodel之後,做前向需要的步驟:

1、我們需要用已經有的.caffemodel以及.prototxt初始化乙個網路(net)a;

2、將輸入到上面的a中做前向(這裡的可以是放在乙個資料夾,也可以是攝像頭,看需要);

3、取出a相應的層(一般是最後乙個全連線層)的神經元的值,也就是我們的進入a做前向之後得到的輸出;

4、拿到網路a的輸出之後,就是根據自己的需要做一些計算或者視覺化(比如檢測任務的話就可以把bounding box畫出來)。

首先來看看display.sh檔案:

#! /usr/bin/env sh 

gpu_id=0

camera_id=0

keypointnum=2

export ld_library_path=/home/lichenyang/gesture_caffe/caffe/build/lib:$

### 存放可執行檔案.bin的資料夾路徑

tools=/home/lichenyang/gesture_caffe/caffe/build/examples

### 存放.caffemodel 和.prototxt的資料夾路徑

param=/home/lichenyang/gesture_caffe/caffe/examples/gesture/models/

### 存放均值資料夾的路徑,也就是訓練的時候製作的均值檔案,

### 如果訓練的時候沒有使用均值檔案,則可以在後面提到的extrac_features.cpp檔案中去掉這個引數

meanfilepath=/home/lichenyang/gesture_caffe/caffe/examples/gesture/models/mean.binaryproto

$tools/extract_features.bin \

$param/_iter_100000.caffemodel \

$param/train_val.prototxt \

fc8 \

gpu \

$gpu_id \

$meanfilepath \

$camera_id \

$keypointnum

上面呼叫的extract_features.bin檔案就是我們的extract_features.cpp檔案make編譯之後生成的檔案。後面是一些命令列引數,大家可以先記住命令列引數的位置,我在後面的extract_features.cpp檔案中會解釋,當然在理解了原理之後,命令列引數可以根據自己的需要來修改。這裡還需要注意的一點是,上面提到的.prototxt檔案是指網路結構檔案。也就是訓練的時候類似於train_val.prototxt的檔案,但需要做下面的兩點修改:

input: "data"

input_dim: 1

input_dim: 3

input_dim: 227

input_dim: 227

2、去掉loss層。實際應用的時候不需要計算loss。

下面看看extract_features.cpp檔案:

#include #include #include #include "extract_features.hpp"

using namespace std;

using namespace cv;

//### 定義乙個模板函式

templateint feature_extraction_pipeline(int argc, char** argv);

int main(int argc, char** argv)

//### 模板函式的實現

templateint feature_extraction_pipeline(int argc, char** argv) else

//********************************

//### 初始化乙個網路

//********************************

net* net = new net(feature_extraction_proto, caffe::test);

shared_ptr> feature_extraction_net(net);

feature_extraction_net->copytrainedlayersfrom(pretrained_binary_proto);

//### 定義攝像頭處理類

videocapture capture(camera_id);

if (!capture.isopened())

//### 先reshape乙個blob,用來存放輸入的資訊,這裡的大小根據實際情況來

std::vector*> input_vec;

input_vec.push_back(new blob);

vectorinput_shape(4);

input_shape[0] = 1;

input_shape[1] = 3;

input_shape[2] = 227;

input_shape[3] = 227;

input_vec[0]->reshape(input_shape);

while(true)

coutsrc_vec.push_back(src);

//### 用extract_features.hpp中的cvmat2blobvec函式將mat存放到blob中

//### 如果訓練的時候不是用meanfile而是用meanvalue,則不需要第三個引數,

//### 具體參見下面對extract_features.hpp的解讀

cvmat2blobvec(src_vec, input_vec, meanfilepath);

//### 用上面初始化的網路做前向

feature_extraction_net->forward(input_vec);

//### 取出網路blob_name層的神經元的值

const shared_ptr> feature_blob = feature_extraction_net->blob_by_name(blob_name);

//### 定義指向該區域的指標,到這裡已經取出需要的值,下面愛幹嘛幹嘛

const dtype* feature_blob_data = feature_blob->cpu_data();

//### 做視覺化

std::vectorfingercoord;

for (int k = 0; k < coordnum; k+=2)

imshow("visualize",src);

waitkey(10);

} return 0;

}

最後看看extract_features.hpp檔案:

#include #include #include #include #include "caffe/blob.hpp"   

#include "caffe/common.hpp"

#include "caffe/net.hpp"

#include "caffe/util/io.hpp"

using namespace cv;

using namespace std;

using namespace caffe;

//### 此函式只有兩個引數,訓練的時候使用meanvalue的可以使用這個函式

templatevoid cvmat2blobvec(const vector& srcs, vector* >& transformed_blob_vec)}}

} }//### 此函式有三個引數,訓練的時候使用meanfile的可以使用這個函式

// override

templatevoid cvmat2blobvec(const vector& srcs, vector* >& transformed_blob_vec,

string meanfilepath)}}

} }

好了,所有的步驟到這裡基本上就結束。以上就是用c++**用現有的caffemodel做前向的方法。

用訓練好的caffe模型來測試樣本

如果要把訓練好的模型拿來測試新的樣本,那必須得要乙個deploy.prototxt檔案,這個檔案實際上和test.prototxt檔案差不多,只是頭尾不相同而已。deploy檔案沒有第一層資料輸入層,樣本是被直接輸入到net.blobs裡面的,也沒有最後的accuracy層,但最後多了乙個softm...

用訓練好的神經網路識別字元

在sample資料夾下放了一些測試字元,都是20 20的。用來識別的。同時在工程目錄下放置了訓練好的神經網路xml檔案。如下圖 const int numcharacter 10 這裡只有0 9共10種字元 cvann mlp ann vectorgetfiles const string fold...

caffe練習例項(3) 使用訓練好的模型

input data input shapelayer include opencv2 dnn.hpp include opencv2 imgproc.hpp include opencv2 highgui.hpp using namespace cv using namespace cv dnn ...