TensorFlow的C++之路(3):使用一张图像导入模型获得预测结果

前一章我讲到了导入模型,现在自然是该用一张图片去做预测了,自然涉及到导入图像。Tensorflow的C++API有导入图片的函数,不过我这里介绍使用opencv的imread,再把Mat型变量转化为Tensorflow支持的Tensor型变量。

Mat转换为Tensor

Tensor t_in(DT_FLOAT, TensorShape({ 1,512,512,3 }));
cvmat_to_tensor(resized_img, &t_in);

首先需要定义一个Tensor类型,DT_FLOAT是数据类型,代表浮点型,后面的TensorShape是图像的大小,注意是四维的,格式为NHWC。
之后使用自定义的函数cvmat_to_tensor把Mat型的resized_img转化为Tensor类型的数据。该函数的作用看函数名称也能猜出意思。
下面就是cvmat_to_tensor的定义。大家可以直接复制粘贴使用。

void cvmat_to_tensor(const cv::Mat &img, Tensor* tensor) {
	float *p = tensor->flat<float>().data();
	int rows = img.rows;
	int cols = img.cols;
	cv::Mat imagePixels = Mat(rows, cols, CV_32FC3, p);
	img.convertTo(imagePixels, CV_32FC3);
}

定义一些必要的变量

在预测之前,我们需要两个很重要的变量,一个是指向Session类型的指针,还有一个是GraphDef类型。

Session * session = 0;
Status status = NewSession(SessionOptions(), &session);
GraphDef gdef;

其中gdef会送到自定义的readPb函数中去,让模型导入到我们的gdef图中,这是上一章的内容。
我们还需要定义保存输出的变量和需要送到feed dict中的变量。

vector<Tensor> outputs;
vector<std::pair<string, Tensor> > inputs = {
			{ "input/input_data", t_in }
		};

这里简单解释一下,outputs用来存输出节点的输出。inputs是一个vector类型,注意vector是pair结构。pair中的string是输入节点的名称,注意这里不需要像Python一样加“:0”。

开始预测

status = session->Run(inputs, { "post_processing/result" }, {}, &outputs);
if (!status.ok()) {
		cout << status.ToString() << "\n";
	}
Tensor t = outputs[0];  

注意,最后一行的[0]是必不可少的。至于原因,看最下面。
这样就完成预测了。至于这个输出tensor t是什么,作为模型的使用者,你应该知道啦。

我们还可以通过TensorShape查看输出的shape。

TensorShape shape = t.shape();
cout << shape.dims() << std::endl;  // 2 6 
cout << shape.dim_size(0) << " " << shape.dim_size(1) << std::endl;

笔者这里使用的是yolo,输出了两个框,每个框携带四个坐标值,一个score,一个类别,共6个值。所以输出是 [2,6]。

下一章我们将讲述怎么看输出tensor t 中的值。


update on 2019.7.21
当在sess->run的时候,有一个参数是输出参数,我们设置了几个节点输出,那么vector<Tensor> 的内容就有几个Tensor。我之前以为outputs[0]的含义是node的第0号输出,原来是理解错误的。
比如我们看下面的例子。

model.session->Run(inputs, { “prob”,“label” }, {}, &outputs);

我们想得到一张图的概率(prob)和标签(label),输出就不是一个了,而是两个。只要用相应的位置去取出来就行了,例如:

Tensor prob = outputs[0]; Tensor label = outputs[1];

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值