赞
踩
- D:\Code_Lib\libtorch\include
- D:\Code_Lib\libtorch\include\torch\csrc\api\include
前者对应 #include <torch/script.h>
,后者对应 #include <torch/torch.h>
。
D:\Code_Lib\libtorch\lib
- asmjit.lib
- c10.lib
- c10_cuda.lib
- caffe2_detectron_ops_gpu.lib
- caffe2_module_test_dynamic.lib
- caffe2_nvrtc.lib
- clog.lib
- cpuinfo.lib
- dnnl.lib
- fbgemm.lib
- libprotobuf.lib
- libprotobuf-lite.lib
- libprotoc.lib
- mkldnn.lib
- torch.lib
- torch_cuda.lib
- torch_cpu.lib
PATH=D:\Code_Lib\libtorch\lib;%PATH%
11. 将 C/C++ => 语言 => 符合模式,改为否;C/C++ => 常规=> SDL检查,改为否。
至此,在C++中部署Libtorch完成。可以通过运行测试程序进行测试。
如果过程中有踩坑的可以参考我的踩坑总结:
C++部署Pytorch(Libtorch)出现问题、错误汇总
转载自 https://www.pythonf.cn/read/152618
实际上,从Pytorch得到的网络模型接口的到C++就是通过Torch脚本(.pt文件)实现的。因此,需要先在Python中用Pytorch生成Torch脚本。
有两种将PyTorch模型转换为Torch脚本的方法。
第一种称为 跟踪 ,一种机制,通过使用示例输入对模型的结构进行一次评估,并记录这些输入在模型中的流动,从而捕获模型的结构。这适用于有限使用控制流的模型。
第二种方法是在模型中添加 显式批注 ,以告知Torch Script编译器可以根据Torch Script语言施加的约束直接解析和编译模型代码。
关于如何得到Torch脚本这里就不过多叙述了,想了解的可以参考以下资料:
在C++ 中加载 TorchScript 模型
官方TorchScript文档
这里放两个我用于测试的代码,第一个用于只用libtorch库的简单测试,输入为随机的向量。最终在工作目录中生成resnet18.pt文件。
- import torch
- from torchvision.models import resnet18
- model =resnet18()
- example = torch.rand(1, 3, 224, 224)
- traced_script_module = torch.jit.trace(model, example)
-
- traced_script_module.save("resnet18.pt")
-
第二个是用于libtorch+OpenCV库测试,之后需要在C++中用OpenCV读取输入图像。采用torchvision.models中的Resnet50网络模型,实现图像的分类,分类结果说明参考: ImageNet图像库1000个类别名称(中文注释不断更新) 。最终生成resnet50.pt于工作目录中。
- import torch
- import torchvision.models as models
- from PIL import Image
- import numpy as np
-
- image = Image.open("E:/HM_DL/torch_test/torch_py/test1.jpg")
- image = image.resize((224, 224),Image.ANTIALIAS)
- image = np.asarray(image)
- image = image / 255
- image = torch.Tensor(image).unsqueeze_(dim=0)
- image = image.permute((0, 3, 1, 2)).float()
-
- model = models.resnet50(pretrained=True)
- model = model.eval()
- resnet = torch.jit.trace(model, torch.rand(1,3,224,224))
- # output=resnet(torch.ones(1,3,224,224))
- output = resnet(image)
- max_index = torch.max(output, 1)[1].item()
- print(max_index) # ImageNet1000类的类别序
-
- resnet.save('resnet50.pt')
最终,通过将脚本模块序列化为文件,得到模型的.pt文件,这个文件就将作为C++的输入,用于实现在C++中部署Pytorch。
利用VS在C++中部署Pytorch模型的配置方法大致有两种: 基于CMake自动配置 , 手动在VS中配置 。
以我自己为例,首先在E:\torch_test下创建名为Example的文件夹,然后在该文件夹下分别创建C++测试代码(example-app.cpp)和CMakeLists.txt,以及一个名为build的文件夹。
example-app.cpp示例:
配合第一个Python程序,测试libtorch库是否可用。
- #include <torch/script.h> // One-stop header.
- #include <iostream>
- #include <memory>
-
- int main() {
- // Deserialize the ScriptModule from a file using torch::jit::load().
- //std::shared_ptr<torch::jit::script::Module> module =
- // torch::jit::load("E:/HM_DL/torch_test/traced_resnet_model.pt");
-
- using torch::jit::script::Module;
- Module module =
- torch::jit::load("E:/HM_DL/torch_test/traced_resnet_model.pt");
-
- std::cout << "ok\n";
- // Create a vector of inputs.
- std::vector<torch::jit::IValue> inputs;
- inputs.push_back(torch::ones({1, 3, 224, 224}));
-
- // Execute the model and turn its output into a tensor.
- at::Tensor output = module.forward(inputs).toTensor();
-
- std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';
- while (1)
- ;
- }
配合第二个Python程序,同时测试libtorch库和OpenCV库。
- #include <torch/script.h>
- #include <torch/torch.h>
- #include <iostream>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui.hpp>
- #include <opencv2/opencv.hpp>
- #include <vector>
-
- void TorchTest() {
- torch::jit::script::Module module =
- torch::jit::load("E:/HM_DL/torch_test/torch_py/resnet.pt");
-
- std::cout << "Load model successful!" << std::endl;
- std::vector<torch::jit::IValue> inputs;
- inputs.push_back(torch::zeros({1, 3, 224, 224}));
- at::Tensor output = module.forward(inputs).toTensor();
- auto max_result = output.max(1, true);
- auto max_index = std::get<1>(max_result).item<float>();
- std::cout << max_index << std::endl;
- }
-
- void Classfier(cv::Mat &image) {
- torch::Tensor img_tensor = torch::from_blob(
- image.data, {1, image.rows, image.cols, 3}, torch::kByte);
- img_tensor = img_tensor.permute({0, 3, 1, 2});
- img_tensor = img_tensor.toType(torch::kFloat);
- img_tensor = img_tensor.div(255);
- torch::jit::script::Module module =
- torch::jit::load("E:/HM_DL/torch_test/torch_py/resnet.pt");
- torch::Tensor output = module.forward({img_tensor}).toTensor();
- auto max_result = output.max(1, true);
- auto max_index = std::get<1>(max_result).item<float>();
- std::cout << max_index << std::endl;
- }
-
- int main() {
- // TorchTest();
- cv::Mat image = cv::imread("E:/HM_DL/torch_test/torch_py/test1.jpg");
- cv::resize(image, image, cv::Size(224, 224));
- cv::imshow("image", image);
- cv::waitKey(0);
- std::cout << image.rows << " " << image.cols << " " << image.channels()
- << std::endl;
- Classfier(image);
- return 0;
- }
CMakeLists.txt示例:
- cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
- project(example-app)
-
- find_package(Torch REQUIRED)
- find_package(OpenCV REQUIRED)
-
- if(NOT Torch_FOUND)
- message(FATAL_ERROR "Pytorch Not Found!")
- endif(NOT Torch_FOUND)
-
- message(STATUS "Pytorch status:")
- message(STATUS " libraries: ${TORCH_LIBRARIES}")
-
- message(STATUS "OpenCV library status:")
- message(STATUS " version: ${OpenCV_VERSION}")
- message(STATUS " libraries: ${OpenCV_LIBS}")
- message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
-
-
- add_executable(example-app example-app.cpp)
- target_link_libraries(example-app ${TORCH_LIBRARIES} ${OpenCV_LIBS})
- set_property(TARGET example-app PROPERTY CXX_STANDARD 11)
然后打开cmd终端,进入build文件夹,输入:
cmake -DCMAKE_PREFIX_PATH=D:\Opencv\opencv\build\x64\vc14\lib;D:\Code_Lib\libtorch -G "Visual Studio 15 Win64" ..
其中,-DCMAKE_PREFIX_PATH后要写你下载的libtorch库的绝对路径和opencv库下\build\x64\vc14\lib的绝对路径。"Visual Studio 15 Win64"表示用VS2017 x64编译。另外注意,一定不要忘了最后的 ..
,这表示采用上一级目录下的cmake文件,否则会报错说build下没找到cmake文件。
运行成功的话会生成解决方案,选择合适的编译方式,生成可执行文件,然后运行。如有报错,参考我的 C++部署Pytorch(Libtorch)出现问题、错误汇总
除了采用CMake的方式,也可以直接在一个已建项目里通过配置环境属性来将项目连接到libtorch库。
下面以一个新建空项目为例,展示一下具体步骤。
PATH=D:\Code_Lib\libtorch\lib;%PATH%
11. 将 C/C++ => 语言 => 符合模式,改为否;C/C++ => 常规=> SDL检查,改为否。
至此,在C++中部署Libtorch完成。可以通过运行测试程序进行测试。
如果过程中有踩坑的可以参考我的踩坑总结:
C++部署Pytorch(Libtorch)出现问题、错误汇总
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。