0%

使用 CAFFE 预测输入

CAFFE 官方目前已经提供了一个 C++ 做预测的例子,目前大部分工作都转移到了 MXNet, 经常被问到怎么用 CAFFE 做预测,之前基于 CAFFE 的 v0.9999 版本写过一个预测。接口可能有变化,不过,基本思路应该是一样的,希望对各位有所帮助. 有时间的话希望能更新到最新的 CAFFE 接口。推荐参考 CAFFE 官方提供的 CAAFE 预测代码。贴出之前写的代码,希望能对理解 CAFFE 的工作过程有所帮助。代码已经详细注释了,不再赘述。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
int test() {
// 检查网络定义文件 (deploy) 和模型文件
CHECK_GT(FLAGS_model.size(), 0) << "Need a model definition to score.";
CHECK_GT(FLAGS_weights.size(), 0) << "Need model weights to score.";

// 使用 GPU 还是 CPU
if (FLAGS_gpu >= 0) {
LOG(INFO) << "Use GPU with device ID " << FLAGS_gpu;
Caffe::SetDevice(FLAGS_gpu);
Caffe::set_mode(Caffe::GPU);
} else {
LOG(INFO) << "Use CPU.";
Caffe::set_mode(Caffe::CPU);
}
// 初始化网络
Caffe::set_phase(Caffe::TEST);
Net<float> caffe_net(FLAGS_model);
caffe_net.CopyTrainedLayersFrom(FLAGS_weights);
// cv_img 存储 opencv 载入的图片信息
cv::Mat cv_img;
// 我需要一次预测好多张图片,所以,我把图片的地址放在了文件中,通过 img 这个命令行选项传进来
std::ifstream infile(FLAGS_img.c_str());
string image;
// 声明一个 Blob, 作用是存储一张图片数据
Blob < float >blob;
// Reshape 这个调用分配了内存空间,用来存放需要预测的图片数据,batch_size 一次预测的图片的数量
//优点是速度比较快,例如,一次预测 10 张的时间会远小于每次预测一张,预测 10 次的时间总和
blob.Reshape(batch_size, 1, img_width, img_height);
// dummy_blob_input_vec 是最终输入到神经网络中的数据
vector < Blob < float >*> dummy_blob_input_vec;
dummy_blob_input_vec.clear();
for(int i=0;i<batch_size;++i){
// 通过一个循环输入 batch_size 张图片
infile >> image;
// 我需要预测灰度图,所以 opencv 读取灰度图,如果要预测 RGB 图,需要注意下面 data 填充数据的方法也要对应调整
cv::Mat cv_img_origin = cv::imread(image, 0);
cv::resize(cv_img_origin, cv_img, cv::Size(img_width, img_height));
float *data = blob.mutable_cpu_data();
for (int h = 0; h < cv_img.rows; ++h) {
for (int w = 0; w < cv_img.cols; ++w) {
char v = cv_img.at < char >(h, w);
data[i*img_width*img_height+h * cv_img.cols + w] = static_cast < float >((uint8_t) v);
}
}
}
// 等待预测的数据填充到了 blob 中,把 blob push 到 dummy_blob_input_vec 中之后就可以 forward 了
dummy_blob_input_vec.push_back(&blob);
const vector < Blob < float >*>& result = caffe_net.Forward(dummy_blob_input_vec);
// 提取最后一层的数据,就是预测结果了
const float* argmaxs=result[0]->cpu_data();
for(int i=0;i<result[0]->num();++i){
LOG(INFO)<<" Image: "<< i << " class:" << argmaxs[i];
}
return 0;
}