C++ 之 Opencv dnn推理 tensorflow pb模型 做预测

老师周末布置的作业,现在记录一下,方便以后学习。也为了帮助其他在学习遇到困难的小伙伴们。
接下来我们 以最简单的 神经网络手写体识别为例。

一、简单的流程图:

为X占位符添加name 为输出层h添加name 生成Pb文件 预测推理
  • 图片尺寸为 20*20
  • 类别为 10分类
  • 模型Tensorflow
  • C++ Opencv实现推理

二、name添加

----大致模型结构(只截取了一部分)
self.X = tf.placeholder(tf.float32, [None, 400],name='inputx')#这里做了添加
self.Y = tf.placeholder(tf.float32, [None, 10])

# 隐藏层 1
with tf.variable_scope('layer1') as scope:
    W1 = tf.Variable(tf.random_normal([400, hidden_one]))
    b1 = tf.Variable(tf.random_normal([hidden_one]))
    a1 = tf.sigmoid(tf.matmul(self.X, W1) + b1)

# 隐藏层 2
with tf.variable_scope('layer2') as scope:
    W2 = tf.Variable(tf.random_normal([hidden_one, hidden_two]))
    b2 = tf.Variable(tf.random_normal([hidden_two]))
    a2 = tf.sigmoid(tf.matmul(a1, W2) + b2)

# 隐藏层 3
with tf.variable_scope('layer3') as scope:
    W3 = tf.Variable(tf.random_normal([hidden_two, hidden_three]))
    b3 = tf.Variable(tf.random_normal([hidden_three]))
    a3 = tf.sigmoid(tf.matmul(a2, W3) + b3)

# 全连接
with tf.variable_scope('all_layer') as scope:
    W4 = tf.Variable(tf.random_normal([hidden_three, 10]))
    b4 = tf.Variable(tf.random_normal([10]))

#预测
self.logist = tf.sigmoid(tf.matmul(a3, W4) + b4,name='final_result') #这里做了添加
#代价
self.loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=self.logist,labels=self.Y))

三、生成pb

1、 导入包

from tensorflow.python.framework import graph_util

2、训练效果好时进行保存

#放入训练过程中 准确度大于一定阈值进行保存
constant_graph = graph_util.convert_variables_to_constants(sess, sess.graph_def,['final_result'])  #[这里只放最后的预测h的name就好]
with tf.gfile.FastGFile('model.pb', mode='wb') as f:
    f.write(constant_graph.SerializeToString())

四、Opencv DNN推理

新建一个类别文件 例如words.txt
C++ 之 Opencv dnn推理 tensorflow pb模型 做预测

完整代码

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/dnn.hpp>
#include<String>
#include <fstream>
using namespace cv;
using namespace cv::dnn;
using namespace std;
String labels_txt_file = "words.txt";//类别文件

vector<String> readLabels() {          //读取words.txt 文件 
	vector<String> classNames;		   // 创建一个名为classNames的容器
	ifstream fp(labels_txt_file);	   //读取文件 words.txt
	String name;
	while (!fp.eof()) {				   //判断文件是否读到末尾 是则停止循环
		getline(fp, name);			   //读取每行 将对应的值放入name中
		if (name.length()) {
			classNames.push_back(name);//添加到容器中
		}
	}
	fp.close();
	return classNames;
}
int main(int argc, char** argv) {
	//1、读取一张图片
	Mat src = imread("test.jpg", 0); 
	//2、加载模型
	vector<String> labels = readLabels(); //打印类别信息
	for (int i = 0; i < labels.size(); i++)
	{
		cout << labels[i] << endl;

	}
	//3、加载网络结构
	Net net = readNetFromTensorflow("model.pb");
	//4、 将图像数据转换成OpenCV DNN能用的blob形式   blobFromImage
	Mat inputBlob = blobFromImage(src, 1.0, Size(20,20)); //blobFromImage 参数(图片,缩放比例,缩放尺寸) 我的图片尺寸为20*20
	//5、将blob数据放入网络结构中 对应的 placeholder X中的占位符的name;
	Mat prob;
	net.setInput(inputBlob, "inputx");// 输入层 X 
	//6、前向传播
	prob = net.forward("final_result");//输出层 h 
	cout << prob << endl;

	Point Max_index;
	double classProb;//最大概率
	minMaxLoc(prob, NULL, &classProb, NULL, &Max_index);// 在一个数组中找到全局最小值和全局最大值 minMaxLoc 参数(图片数据,最小值,最大值,最小点的位置,最大点的位置)
	int classidx = Max_index.x;//概率最大的下标
	printf("\n 图片预测为: %s, 概率为 : %.2f", labels.at(classidx).c_str(), classProb);
	imshow("预测图片", src);
	waitKey(0);
	return 0;
}

五、测试

运行 ~~~ C++ 之 Opencv dnn推理 tensorflow pb模型 做预测
成功搞定。
C++ 之 Opencv dnn推理 tensorflow pb模型 做预测

上一篇:C Programming Test And Answer 04


下一篇:【ZJU-Machine Learning】卷积神经网络-LeNet