基于Windows平台在C++中调用Pytorch模型

基于Windows平台在C++中调用Pytorch模型

本教程将完整的记录使用pytorch从模型训练到模型调用(基于Python),再通过libtorch转成C++调用(基于win32 C++控制台程序),最终集成到MFC程序中来,这样就可以完整的在Windows下走通 AI 算法建模到生产级部署的全部流程。

Python版本:Python 3.8.12

Pytorch版本:1.2.0

CUDA:version 10.0.130

Libtorch:1.6.0+cpu

操作系统:Win10

编译器:VS 2019

1.C++调用—使用libtorch导出序列化模型

从Pytorch-1.0开始其最瞩目的功能就是生产的大力支持,推出了C++版本的生态端,包括C++前端和C++模型编译工具。对于我们来说,在想要部署深度学习应用的时候,只需要在Python端利用Pytorch进行训练,然后使用torch.jit导出我们训练好的模型,再利用C++端的Pytorch接口读取进行预测即可。由于这种方式是官方推荐和支持的,因此,相比于其它方式这种模式更加稳定可靠。官方已经替我们编译好Windows版本的libtorch,这下就节省了我们编译Pytorch的时间,可以直接拿来使用,只要稍微配置一下就可以在Windows上运行libtorch了。

2.1导出序列化模型
首先我们需要将算法模型进行序列化导出,基本原理与测试单组数据,输入一组数据,然后利用训练好的模型对数据进行一次推理。稍微不同的就是,才推理的过程中使用了torch.jit函数来记录了整个推理的一个路径流,最后由torch.jit来保存这个路径流。完整代码如下(我这里是已经把网络保存成了.pth类型):

import torch
import dataread
from network import Activation_Net
import numpy as np
x = [ 5 ,134.86179 , 93.929331 , 2 , 5 ,35.2067 , 93.385617,  2 , 0, 0, 0, 0, 0, 0, 0,0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0,0,0]
z=torch.Tensor(x)
if __name__ == '__main__':

    model = torch.load('/home/wnjia/model/deep_value/deep_value.pth')  # 加载模型
    device = torch.device('cpu')  # 使用cpu进行推理
    model = model.to(device)
    model.eval()  # 把模型转为test模式

#    z =torch.rand(1,40)

    traced_net = torch.jit.trace(model,z.view(1,-1))
 #   print(z.shape)
  #  print(z.view(1,-1).shape)
    output1 = model(z.view(1,-1))
    output2 = traced_net(z.view(1,-1))
    # 对比模型输出结果
    print('output1', output1)
    print('output2', output2)
    torch.jit.save(traced_net, "resnet18.pt")
    print("->>模型转换成功!")
    traced_net.save("/home/wnjia/model/deep_value/deep_value.pt")

这里需要注意,由于我们后面安装的libtorch是cpu版本的,因此,在序列化过程中只使用cpu进行推理,否则序列化出来的模型后面C++没办法正确读取。

2安装libtorch

首先去官网下载libtorch:https://pytorch.org/get-started/locally/。按下面的配置下载(下载release 版本):

下载完成后解压,其中,include文件夹包含了我们需要的libtorch头文件;lib文件夹中包含了libtorch的库文件(lib和dll)。我们需要将头文件和lib文件引入到本项目中。

在项目“VC++目录”的“包含目录”中添加相关路径,包含目录中添加:

.\nettext\libtorch\include

库目录中加入:

.\nettext\libtorch\lib

然后在“链接器”->“输入”->“附加依赖项”中添加:
asmjit.lib
c10.lib
caffe2_detectron_ops.lib
caffe2_module_test_dynamic.lib
cpuinfo.lib
clog.lib
dnnl.lib
fbgemm.lib
libprotobuf.lib
libprotobuf-lite.lib
libprotoc.lib
mkldnn.lib
torch.lib
torch_cpu.lib

然后保存配置即可。最后将libtorch包中的所有文件文件拷贝到我们项目的x64/Release文件夹下面。注意,我们所有第三方库都是使用的release版。

3 C++中调用模型进行推理

将前面序列化导出的model.pt文件拷贝到项目的x64/Release文件夹下面,这个文件就是我们最终项目进行推理需要的参数文件。完整的c++代码如下:

#include 
#include 
#include 

int main(void)

{	torch::jit::script::Module module = torch::jit::load("D:/desktop/nettext/nettext/x64/Release/deep_value.pt");
	//assert(module != nullptr);           

	std::cout << "Model is loaded!" << std::endl;
	// Create a vector of inputs.
	std::vector inputs;
	std::vector scales;
	float temp[] = { 5 ,134.86179 , 93.929331 , 2 , 5 ,35.2067 , 93.385617,  2 , 0, 0, 0, 0, 0, 0, 0,0,0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0,0,0 };
	for (int i = 0; i < 40; i++)
	{
		scales.push_back(temp[i]);
	}
	torch::Tensor scales_ = torch::tensor(scales);
	inputs.push_back(scales_); //torch::ones({ 40 })

//	inputs.push_back(5);
	torch::Tensor result = module.forward({ torch::stack(scales_, 0) }).toTensor();//推理
	//log(output);
	std::cout << result << std::endl;

	system("pause");
	
	return 0;

}

重新生成解决方案,就完成啦!

你可能感兴趣的:(神经网络学习,深度学习,pytorch,神经网络,c++)