在使用模型的时候,不能直接调用该模型,还需要改写之前的训练网络,最后将更改之后的网络(deploy)和模型结合在一起使用
1.把数据层(Data Layer)和连接数据层的Layers去掉(即top:data的层),图左彩色部分删除
2. 去掉输出层和连接输出层的Layers(即bottom:label)图右彩色部分删除
3. 重新建立输入,将第一步删除的部分粘贴下面的代码
input: "data"
input_shape {
dim: 1 # batchsize,每次forward的时候输入的图片个数
dim: 3 # number of colour channels - rgb.如果是1,测试灰度值
dim: 28 # width
dim: 28 # height
}
4.重新建立输出,将第二部删除的部分粘贴下面的代码
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
* 修改后的mnist的deploy文件可以参考caffe/example/mnist/lenet_train.prototxt
修改后的deploy的文件如下:
name: "LeNet"
input: "data"
input_shape {
dim: 1 # batchsize
dim: 1 # number of colour channels - rgb
dim: 28 # width
dim: 28 # height
}
layer {
name: "conv1"
type: "Convolution"
bottom: "data"
top: "conv1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 20
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool1"
type: "Pooling"
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "conv2"
type: "Convolution"
bottom: "pool1"
top: "conv2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
convolution_param {
num_output: 50
kernel_size: 5
stride: 1
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "pool2"
type: "Pooling"
bottom: "conv2"
top: "pool2"
pooling_param {
pool: MAX
kernel_size: 2
stride: 2
}
}
layer {
name: "ip1"
type: "InnerProduct"
bottom: "pool2"
top: "ip1"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 500
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "relu1"
type: "ReLU"
bottom: "ip1"
top: "ip1"
}
layer {
name: "ip2"
type: "InnerProduct"
bottom: "ip1"
top: "ip2"
param {
lr_mult: 1
}
param {
lr_mult: 2
}
inner_product_param {
num_output: 10
weight_filler {
type: "xavier"
}
bias_filler {
type: "constant"
}
}
}
layer {
name: "prob"
type: "Softmax"
bottom: "ip2"
top: "prob"
}
建立一个test_mnist.cpp文件输入以下代码
#include "opencv2/dnn.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
using namespace cv;
using namespace cv::dnn;
#include
#include
#include
using namespace std;
/* Find best class for the blob (i. e. class with maximal probability) */
void getMaxClass(dnn::Blob &probBlob, int *classId, double *classProb)
{
Mat probMat = probBlob.matRefConst().reshape(1, 1); //reshape the blob to 1x1000 matrix
Point classNumber;
minMaxLoc(probMat, NULL, classProb, NULL, &classNumber);
*classId = classNumber.x;
}
int main(int argc,char* argv[]){
String modelTxt = "mnist_deploy.prototxt";
String modelBin = "lenet_iter_10000.caffemodel";
String imageFile = (argc > 1) ? argv[1] : "5.jpg";
//! [Create the importer of Caffe model] 导入一个caffe模型接口
Ptr importer;
importer = dnn::createCaffeImporter(modelTxt, modelBin);
if (!importer){
std::cerr << "Can't load network by using the following files: " << std::endl;
std::cerr << "prototxt: " << modelTxt << std::endl;
std::cerr << "caffemodel: " << modelBin << std::endl;
exit(-1);
}
//! [Initialize network] 通过接口创建和初始化网络
Net net;
importer->populateNet(net);
importer.release();
//! [Prepare blob] 读取一张图片并转换到blob数据存储
Mat img = imread(imageFile,0); //[] "0" for 1 channel, Mnist accepts 1 channel
if (img.empty())
{
std::cerr << "Can't read image from the file: " << imageFile << std::endl;
exit(-1);
}
resize(img, img, Size(28, 28)); //[]Mnist accepts only 28x28 RGB-images
dnn::Blob inputBlob = cv::dnn::Blob(img); //Convert Mat to dnn::Blob batch of images
//! [Set input blob] 将blob输入到网络
net.setBlob(".data", inputBlob); //set the network input
//! [Make forward pass] 进行前向传播
net.forward(); //compute output
//! [Gather output] 获取概率值
dnn::Blob prob = net.getBlob("prob"); //[] gather output of "prob" layer
int classId;
double classProb;
getMaxClass(prob, &classId, &classProb);//find the best class
//! [Print results] 输出结果
std::cout << "Best class: #" << classId << "'" << std::endl;
std::cout << "Probability: " << classProb * 100 << "%" << std::endl;
return 0;
}
4.使用修改后的mnist的deploy文件,输入一张图片,输出分类结果。将mnist训练好的模型放在一个文件夹下,该文件夹下有以下几个文件
执行
g++-o test_mnist test_mnist.cpp -lopencv_dnn -lopencv_highgui-lopencv_imgcodecs -lopencv_imgproc -lstdc++ -lopencv_core
出现了如下错误:
输入以下命令:
sudo apt-get autoremove libopencv-dev,选择y。再次执行g++-o test_mnist test_mnist.cpp -lopencv_dnn -lopencv_highgui-lopencv_imgcodecs -lopencv_imgproc -lstdc++ -lopencv_core。会在文件中生成test_mnist文件。
然后执行:./test_mnist
出现结果: