码迷,mamicode.com
首页 > 编程语言 > 详细

c++调用pytorch模型踩坑记录

时间:2021-02-06 12:02:56      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:失败   角度   pat   包含   cout   打开文件   打开   换行符   输入   

博主曾经在试过用C++调用tensorflow模型失败后弃坑,选择了C++调用Pytorch模型,虽然也是一路踩坑,但是最终结果还是成功了,固在此记录一下。

step1:

下载pytorch:可以根据官网自行选择符合自己电脑和环境的pytorch版本

下载libtorch(一个让pytorch模型能被C++调用的库):最好选择和pytorch版本一样的libtorch,否则好像也会也版本兼容问题(但是博主torch版本1.0.0,libtorch1.7.1也能用= = )

step2:

训练pytorch模型,博主这儿训练了一个简单的二分类模型,输入是一个float类型的一维数据,输出是一个二维的tensor张量,分别代表该数据为类型0/1的概率

导出对应的torch script:

traced_script_module = torch.jit.trace(net, text)
# 保存模型
traced_script_module.save("D:/***/torch_script_eval.pt")

step3:

在clion中,调用torch_script_eval.pt,这儿来了第一个坑

在使用如下语句调用模型时报错找不到路径:

string path ="D:/***/torch_script_eval.pt";
torch::jit::Module module = torch::jit::load(path);

博主的代码和模型都是放在D盘中,但是我通过Clion的wsl功能,链接到了windows的Ubuntu子系统下,用了子系统的环境,包括libtorch都是放在子系统中的,

所以这里的访问路径并不能直接从D盘访问,而是应该站在子系统的角度去访问,改为如下就能成功找到模型了:

string path ="/mnt/d/***/torch_script_eval.pt";
torch::jit::Module module = torch::jit::load(path);

step4:

博主想使用我训练时候的数据,进行测试,看看在c++中调用和python调用结果是否一样,于是我从csv文件中访问我的数据,并且进行测试

 // 加载数据
    string pos_path="/mnt/d/***/data/pos_test1.csv";
    string neg_path="/mnt/d/***/data/neg_test1.csv";
    ifstream fin(neg_path); //打开文件流操作
    string line = "";
    vector<torch::jit::IValue> inputs;
    while (getline(fin, line))   //整行读取,换行符“\n”区分,遇到文件尾标志eof终止读取
    {
        // line 中格式为string,且末尾带一个‘\r‘
        istringstream sin(line); //将整行字符串line读入到字符串流istringstream中
        getline(sin,line,‘\r‘);
        //第一行是id,跳过
        if( strcmp(line.c_str(),"id") == 0)
            continue;
        float tmp;
        tmp = atof(line.c_str());
        torch::Tensor test = torch::ones({1, 1});
        at::Tensor t =  test.variable_data();
        t[0][0] = tmp; //将一个数字改为一个1*1的tensor矩阵
        inputs.clear();
        inputs.push_back(test);
        at::Tensor output = module.forward(inputs).toTensor();//输出两个数字,分别对应类别0/1的分数
        cout << output<<endl;
    }

  这是最终成功的代码,其中的重点在于,我需要向module.forward()方法中输入一个vector,且vector中的数据结构应该是一个1*1的tensor张量(没错,坑在这儿,要如何将自己的一个一维float数据转换为1*1的tensor张量,博主在坑里躺了很久)

  最终采用的方法如下:

float tmp;
tmp = atof(line.c_str());
torch::Tensor test = torch::ones({1, 1});
at::Tensor t =  test.variable_data();
t[0][0] = tmp; //将一个数字改为一个1*1的tensor矩阵

  这个方法可能不是最优的,但是确实是有效地

  先用torch::ones({1,1})方法,生成一个1*1的tensor张量,当然,里面的数据是1

  然后将test.variable_data()赋值给一个at::Tensor类,据说at::Tensor类才可以修改里面的数据,torch::Tensor不可以

  然后at::Tensor支持随机访问,此时用t[0][0]=tmp,就成功构造了一个1*1的一维张量,且里面包含的数据是自己定义的数据啦

c++调用pytorch模型踩坑记录

标签:失败   角度   pat   包含   cout   打开文件   打开   换行符   输入   

原文地址:https://www.cnblogs.com/massami1999/p/14379854.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!