windows+VS2019+PyTorchLib配置使用攻略

2020-07-20  本文已影响0人  有事没事扯扯淡

最近做东西想要早windows下用C++调用训练好的网络模型,达到高速pridict。PyTorch火的一塌糊涂,兼容性也不错,发现有个C++ 的lib,好挺好用,不过windows就是各种坑,记录一下,以供参考。

PyTorchLib下载

https://pytorch.org/get-started/locally/
!!!务必根据自己的硬件配置选择版本!!!

VS属性表配置

下载后只要解压即可。打开vs -> 新建工程 -> 打开属性管理器(在哪就不用我说了吧)

  1. 与Opencv配置类似,对包含路径 / 库目录等进行配置

Attention!!包含目录有两个

  1. 链接器 -> 输入, 添加对应lib

这里有个小trick, 可以利用dir *.lib命令进行快速搜索

  1. dll配置
    有时候调用dll文件是直接拷贝过来,如果文件很多就很麻烦,可以通过添加依赖项目的环境变量。PATH=D:\........\libtorch\lib;%PATH%

模型调用(直接上代码!)

实际调用过程的问题可以参考我的另一篇C++ windows调用ubuntu训练的PyTorch模型

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <torch/torch.h>
#include <torch/script.h>
// 有人说调用的顺序有关系,我这好像没啥用~~

int main()
{
    torch::DeviceType device_type;
    if (torch::cuda::is_available()) {
        std::cout << "CUDA available! Predicting on GPU." << std::endl;
        device_type = torch::kCUDA;
    }
    else {
        std::cout << "Predicting on CPU." << std::endl;
        device_type = torch::kCPU;
    }
    torch::Device device(device_type);

    //Init model
    std::string model_pb = "D:/......./resnet.pt";
    auto module = torch::jit::load(model_pb);
    module.to(at::kCUDA);

    cv::Mat image=cv::imread("........./xxx.jpg") ;
    cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
    cv::resize(image, image, cv::Size(100, 150));

    // convert to tensort
    torch::Tensor img_tensor = ToTensor(image).to(at::kCUDA);  //ToTensor是自定义函数,下面有

    torch::Tensor output = module.forward({ image }).toTensor();
    auto max_result = output.max(1, true);
    auto max_index = std::get<1>(max_result).item<float>();  //找出最大值的索引

    return max_index;

}

相关报错

1. TORCH::CUDA::IS_AVAILABLE()返回为FALSE

在链接器中 -> 命令行 -> 其他选项, 添加 /INCLUDE:?warp_size@cuda@at@@YAHXZ,根本不知道这是啥东西,反正有效ㄟ( ▔, ▔ )ㄏ

2. ToTensor(image).to(at::kCUDA)报错

再GPU上运行模型需注意,image数据和模型必须都在GPU上,不能在CPU上,容易报错。

3.批量输入报错

上面只写了个单个输入数据(1,3,100,150),很多时候要批量输入,单个输入费时费力,几经周折终于弄懂了,torch::cat一下就行了(其实跟python是一样的~~)

 img_tensor = torch::cat({ img_tensor, img_tensor }, 0);

4.cv::Mat转Tensor

torch::Tensor toTensor(cv::Mat& image)
{
    torch::Tensor img_tensor = torch::from_blob(image.data, { image.rows, image.cols, 3 }, torch::kByte);
    img_tensor = img_tensor.permute({ 2, 0, 1 }).toType(torch::kFloat).div(255);
    img_tensor = torch::data::transforms::Normalize<torch::Tensor>({ 0.485, 0.456, 0.406 }, { 0.229, 0.224, 0.225 })(img_tensor);
    img_tensor = img_tensor.unsqueeze(0);
    return img_tensor;
}

[参考文献]
https://www.freesion.com/article/78001002599/

上一篇下一篇

猜你喜欢

热点阅读