深度学习工程实践 3. Window+Qt使用libtorch+opencv4.1 实践

深度学习工程实践 3. Window+Qt使用libtorch+opencv4.1 实践

  • 1.概述
    • 1.1 坑来的原因
    • 1.2 解决
    • 1.3 用最新的opencv
  • 2. 目标
  • 3. 工程实践
    • 3.1 下载最新的libtorch和Opencv4.1
    • 3.2 配置Qt的pro工程文件
    • 3.3 代码验证
  • 4. 总结

1.概述

这篇主要记录一下在Window下使用libtorch的一些坑。

1.1 坑来的原因

这里踩坑主要来自于笔者自己的偏执,一直以来做window下的桌面应用,都非常偏向于使用Qt的mingw编译器,使用mingw编译器,我编译过VTK的库,最新的Opencv4.1的库,CGAL计算机图形库等等。 Qt 的mingw编译器是一个非常不主流的编译器,只有32位的,mingw64和Qt的mingw完全是两会事,所以,很多大型的库,使用cmake+mingw来编译,都需要对源码进行一定的修改。 之所以选择mingw的原因是,在这个的基础上写出来的代码,会强制要求你去考虑跨平台的问题,写完的代码直接可以在mac,linux,win上编译,像树莓派等这样的小板子上编译也是没有问题。

1.2 解决

但是,使用libtorch不行,包括基于darknet实现的yolov3,在minggw下也是不行的。 即使能编译通过,在运行的过程中,也是一大堆未知的错误。 在了解了mingw的尿性之后,我决定彻底放弃用他来开发深度学习相关的开发,windows下就专心的用mscv来编译。 这为工程部署节约了大量的时间。

1.3 用最新的opencv

为什么用最新的Opencv4.1?
因为笔者一直没有成功的用mingw编译出libtorch,所以我就查找,Pytorch训练出来的模型,是否能够直接被Opencv识别并使用? 笔者看到Opencv4已经开始支持Onnx了,那么,我只需要将pytorch训练的结果先转换成onnx,再用opencv的dnn模块直接导入onnx的model,这样理论上是行得通的。 但是,经过了很长时间的google搜索,都没有发现这方面的实践。 主要原因可能是直到最新发布的opencv4.1版本,才支持了onnx格式。opencv直接使用pytorch的model这条路死了,最终还是决定直接使用libtorch的window库。 后面的实践证明,这是一个非常明智的转折。

2. 目标

在Window下,使用Qt开发一个libtorch+opencv4.1的demo演示程序

3. 工程实践

3.1 下载最新的libtorch和Opencv4.1

到pytorch的官网下载libtorch,笔者下载的版本是:libtorch-win-shared-with-deps-latest.zip
下载之后,解压文件,不需要编译源码,直接使用(笔者的Qt配置的编译器是msvc2017)!
同样,下载最新的Opencv4.1安装包,也不需要编译源码,直接使用!

3.2 配置Qt的pro工程文件

INCLUDEPATH += D:\libtorch\include
DEPENDPATH += D:\libtorch\include

LIBS += -LD:\libtorch\lib\ -lc10 \
-lcaffe2 -lcaffe2_detectron_ops \
-lcaffe2_module_test_dynamic \
-lclog -lcpuinfo -lfoxi_dummy \
-llibprotobuf -llibprotobuf-lite \
-llibprotoc -lonnx -lonnx_proto \
-lonnxifi_loader -lonnxifi_dummy \
-ltorch

INCLUDEPATH += D:\Opencv4.1-vs\include
DEPENDPATH += D:\Opencv4.1-vs

LIBS += -LD:\Opencv4.1-vs\x64\vc15\lib -lopencv_world411

opencv4.1之后,简化了dll和相关的lib文件,所有的依赖都集成在一个巨大的opencv_world.dll文件中,很惊喜。

3.3 代码验证

到了代码验证阶段。 首先,要切换到ubuntu的环境下,打开jupyter notebook,用如下代码来生成一个测试的训练模型(来自于pytorch官方的实践指南):

import torch 
import torchvision 

# An instance of your model. 
model = torchvision.models.resnet18() 

# An example input you would normally provide to your model's forward() method. 
example = torch.rand(1, 3, 224, 224) 

# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing. 
traced_script_module = torch.jit.trace(model, example) 
traced_script_module.save("model.pt")

上述代码生成了一个resnet的模型,model.pt,用U盘将这个模型拷贝下来。
切换到window下,创建一个c++工程,测试内容如下:

int main()
{
  // Deserialize the ScriptModule from a file using torch::jit::load().
  std::shared_ptr module = torch::jit::load("model.pt");

  assert(module != nullptr);
  std::cout << "ok\n";
  // Create a vector of inputs.
  std::vector 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);
}

如果你得到了下面类似的结果,恭喜!

ok
-0.1690 0.1106 0.0009 -0.3272 0.0228

4. 总结

本篇主要总结了libtorch在windows下的编译以及配置使用,就一点: 使用官方编译的文件。

你可能感兴趣的:(深度学习,C/C++,深度学习,libtorch,编译)