Caffe学习笔记5--deploy文件的修改与使用
2017-02-06 23:15
603 查看
deploy文件的修改目是为了我们能够真正使用训练好的模型进行预测,输出概率及最佳结果的重要过程。
问题背景:
如我们前面已经生成了一个预测手写体识别的模型,我们现在如何预测某个人写的数字是多少呢?预测的概率是多少呢?
最终解决的结果:
为了达到以上的结果,我们需要做3步骤
第一步,修改mnist_deploy.prorotxt文件
第二步,编写test_mnist.cpp文件
第三步,编译运行输出结果
在修改propotxt之前我们可以对之前的网络结构进行一个直观的认识:可以使用http://ethereon.github.io/netscope/#/editor 这个网址。将propotxt文件内容复制后会得到可视化模型,之前训练模型如图所示:
其实我们的目标就是使用模型的权重最后输出类别概率,所以loss,label我们都不要了。根据上面的图我们对原始结构进行修改,如下:
新的结构生成一下可视化图:
修改完propotxt后,我们命名为mnist_deploy.prototxt。
随后执行命令:
g++-o test_mnist test_mnist.cpp -lopencv_dnn -lopencv_highgui -lopencv_imgcodecs-lopencv_imgproc -lstdc++ -lopencv_core
./test_mnist
恭喜你就能看到最终结果
参考内容
------------------
《Dataguru课程-caffe学习与应用》
问题背景:
如我们前面已经生成了一个预测手写体识别的模型,我们现在如何预测某个人写的数字是多少呢?预测的概率是多少呢?
最终解决的结果:
为了达到以上的结果,我们需要做3步骤
第一步,修改mnist_deploy.prorotxt文件
第二步,编写test_mnist.cpp文件
第三步,编译运行输出结果
第一步,修改prorotxt文件:
我们首先要对之前propotxt进行修改,用来满足我们的需求。在修改propotxt之前我们可以对之前的网络结构进行一个直观的认识:可以使用http://ethereon.github.io/netscope/#/editor 这个网址。将propotxt文件内容复制后会得到可视化模型,之前训练模型如图所示:
其实我们的目标就是使用模型的权重最后输出类别概率,所以loss,label我们都不要了。根据上面的图我们对原始结构进行修改,如下:
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" }
新的结构生成一下可视化图:
修改完propotxt后,我们命名为mnist_deploy.prototxt。
第二步,编写运行代码 test_mnist.cpp:
#include "opencv2/dnn.hpp" #include "opencv2/imgproc.hpp" #include "opencv2/highgui.hpp" using namespace cv; using namespace cv::dnn; #include <fstream> #include <iostream> #include <cstdlib> 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<dnn::Importer> 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); //[<Important>] "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)); //[<Important>]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"); //[<Important>] 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样:5.jpg(测试数据) lenet_iter_10000.caffemodel(上一篇文章生成的模型) mnist_deploy.prototxt(这次修改的prototxt文件) test_mnist.cpp (编译文件)随后执行命令:
g++-o test_mnist test_mnist.cpp -lopencv_dnn -lopencv_highgui -lopencv_imgcodecs-lopencv_imgproc -lstdc++ -lopencv_core
./test_mnist
恭喜你就能看到最终结果
参考内容
------------------
《Dataguru课程-caffe学习与应用》
相关文章推荐
- WPF学习笔记--使用配置文件修改控件、面板颜色
- C#学习笔记(二十一):使用文件基础
- C#学习笔记(二十二):使用文件高级
- Vmware学习笔记之一:使用windows系统文件
- Spring学习笔记 通过PropertyPlaceholderConfigurer来使用properties文件初始化Map类型属性
- C#学习笔记(十六):使用打开保存文件对话框
- C#学习笔记(二十一):使用文件基础
- MonoRail学习笔记二十:资源文件的使用和多语言支持
- [Linux学习笔记]第1天:操作系统的发展史,linux诞生,Linux发行商,shell,terminal,shell使用技巧,文件目录,基本操作
- ORACLE DBA学习笔记--日志文件(使用LogMiner分析日志)
- VS下QT学习笔记-使用.qrc资源文件
- JSP学习笔记(二)-----使用Tomcat运行JSP文件
- MonoRail学习笔记二十:资源文件的使用和多语言支持
- Object-C学习笔记五-----使用跨文件依赖关系
- C#学习笔记(十六):使用打开保存文件对话框
- C#学习笔记(二十一):使用文件基础
- C#学习笔记(十六):使用打开保存文件对话框
- ITCAST视频-Spring学习笔记(使用Spring配置文件实现AOP)
- Perl学习笔记(8) -- 模块的使用和文件测试
- C++ 使用头文件 - 学习笔记(6)