MNN
MNN copied to clipboard
tensorflow模型转为mnn格式,用fastTestTf.py工具测试是success,但是用c++跑每次结果都不一样
平台(如果交叉编译请再附上交叉编译目标平台):
ubuntu x86 cpu:
Github版本:
Github Version: 1.2和 master, master 的commit id 是 344629419f710b39559e616f1af7bb7bd29617db
编译方式:
Compiling cmake
tensorflow模型转为mnn格式,用fastTestTf.py工具测试是success,但是用c++跑每次结果都不一样
因为模型是tf 1.6写的,所以我对fastTestTf.py脚本做了一些修改,对结果没影响
模型地址 链接:https://pan.baidu.com/s/11Eip1A2kRamT4n_G5q40dA 提取码:9i0g
c++测试代码
#include "Backend.hpp"
#include "Interpreter.hpp"
#include "MNNDefine.h"
#include "Interpreter.hpp"
#include "Tensor.hpp"
#include <math.h>
#include <opencv2/opencv.hpp>
#include <iostream>
#include <stdio.h>
#include <math.h>
#include "tic_toc.h"
using namespace MNN;
using namespace cv;
int main()
{
cv::Mat src=cv::imread("/home/zwz/place_recognition/code_reference/netvlad_tf_open-master/demo/query/query1.jpg", 1);
//cv::Mat src=cv::imread("/home/zwz/place_recognition/data/lenovo_data_simple/query/09/599160053306.png", 1);
cv::cvtColor(src, src, cv::COLOR_BGR2GRAY);
if(src.empty()) return -1;
int forward = MNN_FORWARD_CPU;
int precision = 1;
int power = 1;
int memory = 1;
////int threads = 1;
////int INPUT_SIZE = 28;
// 1. 创建Interpreter, 通过磁盘文件创建: static Interpreter* createFromFile(const char* file);
std::shared_ptr<Interpreter> net(Interpreter::createFromFile("/home/zwz/Downloads/MNN_1_2_0/build/freeze.mnn"));
MNN::ScheduleConfig config;
// 2. 调度配置,
// numThread决定并发数的多少,但具体线程数和并发效率,不完全取决于numThread
// 推理时,主选后端由type指定,默认为CPU。在主选后端不支持模型中的算子时,启用由backupType指定的备选后端。
////config.numThread = threads;
config.type = static_cast<MNNForwardType>(forward);
MNN::BackendConfig backendConfig;
// 3. 后端配置
// memory、power、precision分别为内存、功耗和精度偏好
backendConfig.precision = (MNN::BackendConfig::PrecisionMode)precision;
backendConfig.power = (MNN::BackendConfig::PowerMode) power;
backendConfig.memory = (MNN::BackendConfig::MemoryMode) memory;
config.backendConfig = &backendConfig;
// 4. 创建session
auto session = net->createSession(config);
// preprocessing
int raw_image_height = src.rows;
int raw_image_width = src.cols;
// 5. 输入数据
// wrapping input tensor, convert nhwc to nchw
TicToc time_1;
time_1.tic();
std::vector<int> dims{1, raw_image_height, raw_image_width, 1};
auto nhwc_Tensor = MNN::Tensor::create<float>(dims, NULL, MNN::Tensor::TENSORFLOW);
auto nhwc_data = nhwc_Tensor->host<float>();
auto nhwc_size = nhwc_Tensor->size();
::memcpy(nhwc_data, src.data, nhwc_size);
std::string input_tensor = "image";
// 获取输入tensor
// 拷贝数据, 通过这类拷贝数据的方式,用户只需要关注自己创建的tensor的数据布局,
// copyFromHostTensor会负责处理数据布局上的转换(如需)和后端间的数据拷贝(如需)。
auto inputTensor = net->getSessionInput(session, nullptr);
inputTensor->copyFromHostTensor(nhwc_Tensor);
net->resizeTensor(inputTensor, dims);
net->resizeSession(session);
net->releaseModel();
// 6. 运行会话
net->runSession(session);
// 7. 获取输出
std::string output_tensor_name0 = "pred/l2_normalize";
// 获取输出tensor
MNN::Tensor *tensor_scores = net->getSessionOutput(session, output_tensor_name0.c_str());
MNN::Tensor tensor_scores_host(tensor_scores, tensor_scores->getDimensionType());
// 拷贝数据
tensor_scores->copyToHostTensor(&tensor_scores_host);
std::cout<<time_1.toc()<<std::endl;
// post processing steps
auto scores_dataPtr = tensor_scores_host.host<float>();
for (int i = 0; i < 4096; ++i)
{
float val = scores_dataPtr[i];
}
std::cout<<scores_dataPtr[0]<<std::endl;
std::cout<<scores_dataPtr[1]<<std::endl;
std::cout<<scores_dataPtr[2]<<std::endl;
return 0;
}