模型训练   用 python 来构建模型并用数据集进行训练(略).
需要注意的是,用于训练的 python 版本的 pytorch 需要和 CPP 版本的 libtorch 版本一致!这里统一用 Stable (1.7.0) 版本.
模型保存   用 TorchScript 将训练好的模型保存为 *.pt 文件,以便通过 CPP 调用.
1 2 3 4 5 6 7 import  torchfrom  torchvision.models import  resnet18model = resnet18() example = torch.rand(1 , 3 , 224 , 224 ) traced_script_module = torch.jit.trace(model, example) traced_script_module.save("./model/model1_resnet18.pt" ) 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import  torchimport  torchvision.models as  modelsfrom  PIL import  Imageimport  numpy as  npimage = Image.open ("./images/demo.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(image) max_index = torch.max (output, 1 )[1 ].item() print (max_index) resnet.save("./model/model2_resnet50.pt" ) 
 
VS2017+libtorch 在  官网   选择 Stable (1.7.0)+Windows+LibTorch+C++ / Java+10.2, 下载Release 版本和 Debug 版本.
Windows binaries do not support Java. Support is only available for Linux and MacOS. Download here for C++ (Release version):https://download.pytorch.org/libtorch/cu102/libtorch-win-shared-with-deps-1.7.0.zip  Download here for C++ (Debug version):https://download.pytorch.org/libtorch/cu102/libtorch-win-shared-with-deps-debug-1.7.0.zip 
 
配置   下载好 libtorch-win-shared-with-deps-1.7.0.zip 和libtorch-win-shared-with-deps-debug-1.7.0.zip两个文件之后,分别解压到 release 和debug两个文件夹下. 这里先仅使用 Debug 版本.
libtorch-win-shared-with-deps-debug-1.7.0.zip压缩包解压后得到如下文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 -  debug  -  libtorch    -  bin    -  cmake    -  include      -  ...    -  lib      -  *.lib       - * .pdb      -  *.dll     - share     - test     - build-hash - release   - ... 
 
LIB  在  解决方案资源管理器  右击项目名 ->属性 -> 链接器 -> 常规 -> 附加库目录 : 将 lib 文件夹路径添加到这里: …libtorch\lib  在解决方案资源管理器  右击项目名 ->属性 -> 链接器 -> 输入 -> 附加依赖项: 将 lib 文件名添加到这里: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 asmjit.lib clog.lib libprotobuf-lited.lib c10.lib cpuinfo.lib libprotocd.lib c10_cuda.lib dnnl.lib mkldnn.lib c10d.lib fbgemm.lib torch.lib caffe2_detectron_ops_gpu.lib gloo.lib torch_cpu.lib caffe2_module_test_dynamic.lib gloo_cuda.lib torch_cuda.lib caffe2_nvrtc.lib libprotobufd.lib 
 
 
INCLUDE  在  解决方案资源管理器  右击项目名 ->属性 ->C/C++-> 常规 -> 附加包含目录: 将 include 文件夹路径添加到这里: …libtorch\include …libtorch\include\torch\csrc\api\include
 
解决提醒 std 冲突问题    在解决方案资源管理器  右击项目名 ->属性 ->C/C++-> 常规 ->SDL 检查-> 否(/sdl-) 在  解决方案资源管理器  右击项目名 ->属性 ->C/C++-> 语言 -> 符合模式 -> 否
 
dll  将 libtorch\lib 文件夹下的所有 dll 文件都复制到解决方案生成的可执行文件 *.exe 文件所在路径. 此外,如果是 debug 模式,运行时会报错:找不到 vcruntime140_1d.dll. 其实系统里一定有vcruntime140_1.dll 文件,但是没有用于调试版本的 dll 文件,可以去 <www.dll-files.com> 网站下载 : https://www.dll-files.com/vcruntime140_1d.dll.html 
 
 
dll 文件可以直接放在 exe 文件相同路径下,也可以专门放在一个文件夹下,然后将这个文件夹添加到可搜索环境下: 在  解决方案资源管理器  右击项目名 ->属性 -> 调试 -> 环境->PATH=.\dll;%PATH%.
测试   测试 libtorch 1 2 3 4 5 6 7 #include <iostream>  #include <torch/script.h>  int  main ()   {    torch::Tensor t1 = torch::tensor ({ 10 ,1 ,2  });     std::cout << t1[0 ] << std::endl;     system ("pause" ); } 
 
1 2 3 4 5 6 7 8 9 10 11 12 #include <iostream>  #include <torch/script.h>  int  main ()   {        auto  t1 = torch::tensor ({ 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9  }).reshape ({ 3 ,3  });     auto  t2 = torch::tensor ({ 1 ,0 ,2 ,6 ,1 ,1 ,5 ,3 ,2  }).reshape ({ 3 ,3  });     auto  t3 = t1.mul (t2);     std::cout << t3 << std::endl;         system ("pause" ); } 
 
模型导入测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include  <torch/script.h>    #include  <iostream>  #include  <memory>  int  main ()   {	 	using  torch::jit::script::Module; 	Module module  = torch::jit::load ("./model/model1_resnet18.pt" ); 	std::cout << "model load success"  << std::endl; 	 	std::vector<torch::jit::IValue> inputs; 	inputs.push_back (torch::ones ({ 1 , 3 , 224 , 224  })); 	 	at::Tensor output = module .forward(inputs).toTensor (); 	std::cout << output.slice (1 , 0 , 5 ) << std::endl; 	return  0 ; } 
 
模型预测测试 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 #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 ("./model/model2_resnet50.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 ("./model/model2_resnet50.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 ("./images/demo.jpg" ); 	cv::resize (image, image, cv::Size (224 , 224 )); 	cv::imshow ("image" , image); 	cv::waitKey (100 ); 	std::cout << image.rows << " "  << image.cols << " "  << image.channels () 		<< std::endl; 	Classfier (image); 	return  0 ; } 
 
Reference