前言
填一个之前的坑啊,本篇的姊妹篇——利用Pytorch的C 前端(libtorch)读取预训练权重并进行预测 这篇文章中已经说明了如何在Ubuntu系统中使用libtorch做预测,当初也有朋友问我如何在Windows之下尝试使用libtorch,当时因为时间关系没有去看,后来就给忘了…现在有时间了当然要尝试一下~
当然先说结论哈,其实在Windows环境下的配置也是很简单的,因为官方已经替我们编译好的Windows版本的libtorch,这下就节省了我们编译Pytorch的时间,直接可以拿来使用,只要稍微配置一下就可以在Windows跑起libtorch了,没有想象中那么多的步骤,大可放心。
下文中使用的代码和之前在Ubuntu中使用的完全相同,我们不需要进行修改。
同样,首先,我们在官网下载适合于Windows的libtorch
,因为稳定版出来了,所以我们可以直接拿来使用。有CPU版本的和GPU版本的,这里我都进行了测试,都是可以的直接使用的,大家按照自己的需求进行下载即可。
个人环境:
- win10
- cuda9.0 cudnn7.0.5
- 1060-6G
正式开始
与之前实现的任务相同,我这里将libtorch和OpenCV一起编译,使用OpenCV的读取摄像头然后识别当前的手势,模型是我自己训练好的,对于大家来说可以自己随便挑一个模型来使用。
下图为在Visual Studio中使用libtorch和OpenCV来实现判断剪刀石头布手势,运行的平台是cpu端。当然GPU端也是可以运行的,之后也会进行详解。
不得不说下,Pytorch的部署端真的很好用啊,虽然说目前仅仅适合一些小型的任务,但是潜力还是很大地,libtorch端配套Pytorch真的是太方便了!
获取libtorch
之前在Ubuntu跑libtorch的时候,因为OpenCV的一些原因,如果需要libtorch和OpenCV一起编译的话,最好自己编译一边libtorch从而保证libtorch和OpenCV混合编译时不会发生冲突。但是在win10端,OpenCV可以直接从官网下载已经编译好的,既然OpenCV从官方直接下载了,那么libtorch当然也从官方直接下载了。
正如前言所说,打开官网点击下载即可,CPU和GPU按照自己来进行选择。
测试GPU端的libtorch
在Windows端,因为我们从官方下载的OpenCV预编译版本是利用MSVS编译的,也就是我们常说的Visual Studio编译工具,所以我们接下来使用的编译器就是Visual Studio自带的编译器,为此我们需要安装:
- Visual Studio 2015或者2017(两个都测试过,都是可以的!),之后简称VS
- windows端的CMake
大概流程就是我们使用cmake构建好libtorch工程,然后使用VS打开根据cmake配置好的信息进行编译,所以在进行之后的步骤前一定要提前安装好上述的两样东西。
好了,那么首先我们要配置CmakeList:
代码语言:javascript复制cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(simnet)
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(simnet main.cpp)
target_link_libraries(simnet ${TORCH_LIBRARIES} ${OpenCV_LIBS})
set_property(TARGET simnet PROPERTY CXX_STANDARD 11)
和之前的没有什么区别,主要我们需要找到libtorch和opencv库。
接下来使用cmake来进行配置吧,我们首先自己创建一个文件夹,存放我们的主程序main.cpp
还有CMakeLists.txt
,然后我们再创建一个build的空文件夹,之后我们编译好的文件都存放在build文件夹里头。
目录结构大概就是这样,假设这个文件夹存放在D盘:
- example — build — main.cpp — CMakeLists.txt
好了,我们打开Window的命令行界面,进入该目录,再进入build文件夹,然后我们设置我们的Cmake参数:
代码语言:javascript复制-DCMAKE_PREFIX_PATH=pathtoopencvbuildx64vc14lib;pathtolibtorch -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 14 Win64"
这里需要注意下OpenCV的路径,将上面的位置改成自己的安装位置修改即可,我们需要同时告诉cmake编译工具OpenCV和libtorch的位置信息,然后这里我选择-G"Visual Studio 14 Win64"
执行编译器是VS2015的编译工具,如果是2017的话就是-G"Visual Studio 15 Win64
这里根据自己的需要进行调整(如果使用VS2017别忘了修改OpenCV中的vc14为vc15)。
编译类型(-DCMAKE_BUILD_TYPE=Release)也要加上,要不然会报错:
代码语言:javascript复制Unknown cmake build type:
Call Stack (most recent call first):
D:/libtorch-gpu/share/cmake/Caffe2/Caffe2Config.cmake:88 (include)
D:/libtorch-gpu/share/cmake/Torch/TorchConfig.cmake:39 (find_package)
CMakeLists.txt:4 (find_package)
-- Configuring incomplete, errors occurred!
See also "E:/simnet-gpu/build/CMakeFiles/CMakeOutput.log".
See also "E:/simnet-gpu/build/CMakeFiles/CMakeError.log".
好了,上述具体步骤如下:
代码语言:javascript复制C:Usersdell>D:
D:>cd example
D:example>cd build
D:examplebuild>cmake -DCMAKE_PREFIX_PATH=D:opencv4opencvbuildx64vc15lib;D:libtorch-gpu -DCMAKE_BUILD_TYPE=Release -G "Visual Studio 14 Win64" ..
如果顺利的话应该是Cmake会输出:
代码语言:javascript复制-- The C compiler identification is MSVC 19.0.24215.1
-- The CXX compiler identification is MSVC 19.0.24215.1
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Looking for pthread.h
-- Looking for pthread.h - not found
-- Found Threads: TRUE
-- Found CUDA: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0 (found suitable version "9.0", minimum required is "7.0")
-- Caffe2: CUDA detected: 9.0
-- Caffe2: CUDA nvcc is: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0/bin/nvcc.exe
-- Caffe2: CUDA toolkit directory: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0
-- Caffe2: Header version is: 9.0
-- Found cuDNN: v7.0.4 (include: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0/include, library: C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0/lib/x64/cudnn.lib)
-- Autodetected CUDA architecture(s): 6.1
-- Added CUDA NVCC flags for: -gencode;arch=compute_61,code=sm_61
-- Found torch: D:/libtorch-gpu/lib/torch.lib
-- Pytorch status:
-- libraries: torch;caffe2_library;caffe2_gpu_library;C:/Program Files/NVIDIA Corporation/NvToolsExt/lib/x64/nvToolsExt64_1.lib;C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v9.0/lib/x64/cudart_static.lib
-- Found OpenCV: D:/opencv4/opencv/build (found version "4.0.0")
-- OpenCV library status:
-- version: 4.0.0
-- libraries: opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_world
-- include path: D:/opencv4/opencv/build/include
-- Configuring done
-- Generating done
-- Build files have been written to: E:/simnet-gpu/build
这时Cmake会在build文件夹中生成一些列项目信息,可以使用VS打开(打开下面箭头标注的文件)。
如果你的电脑装有两个版本以上的Visual Studio,那么这里要注意如果我们之前使用VS15编译的话那么就要使用VS15去打开这个文件,也就是之前编译使用的工具和之后打开工程的版本应该一致
打开后大概是这样子的:
这里simnet是我的项目名字,我们将该项目设为启动项(可以看到simnet字体比较粗)从而方便调试。
上述的代码在之前的那篇文章中已经提到过,这里简单展示下main函数部分,在这段代码中,我们利用OpenCV读取摄像头数据转化为Tensor,然后投入模型中进行判断:
代码语言:javascript复制...
cv::VideoCapture stream(0);
cv::namedWindow("Gesture Detect", cv::WINDOW_AUTOSIZE);
// 下面的 new-mobilenetv2-128_S-win.pt 是我在Window上利用Pytorch导出的trace后的模型
string model_path = "new-mobilenetv2-128_S-win.pt";
std::shared_ptr<torch::jit::script::Module> module = torch::jit::load(model_path);
...
关于模型
这里还有一点需要注意,使用libtorch导入的模型必须是和libtorch相匹配版本的Pytorch导出的模型,也就是说如果我拿我之前在linux端导出的模型(之前我在linux端导出的模型使用的Pytorch版本不是稳定版),在这里使用window下的libtorch读取是会发生错误的,所以我们需要利用正式版1.0版本的Pytorch去导出一个模型。
这里我直接在window下安装稳定版的Pytorch-1.0(官方已经有稳定版的win版的Pytorch了),然后利用以下代码导出traced后的模型。
代码语言:javascript复制# 读入之前训练好的.pth模型
state = torch.load('model/new-mobilenetv2-128_S.pth', map_location=device)
model.load_state_dict(state['model'], strict=True)
# example = torch.rand(1, 3, 128, 128).cuda()
# model.to(device)
# torch_out = torch.onnx.export(model,
# example,
# "new-mobilenetv2-128_S.onnx",
# verbose=True,
# export_params=True
# )
example = torch.ones(1, 3, 128, 128)
model = model.eval()
traced_script_module = torch.jit.trace(model, example)
output = traced_script_module(example)
print(traced_script_module)
# 导出trace后的模型
traced_script_module.save('new-mobilenetv2-128_S-win.pt')
开始编译
然后,我们直接点击VS中的调试器进行调试即可,这里我选择了Release(与之前cmake一致)进行编译。
点击后开始编译,可能会输出一堆警告,这里不用理会:
如果顺利的话,直接开始运行:
在VS中可以运行后,我们可以找到其单独的.exe文件,然后将必要的.dll文件(CPU和GPU的all不同)和模型与simnet.exe
放到一个文件夹中,这时,我们点击simnet.exe
就可以直接运行了:
后记
libtorch在WIndow端的使用也不是很复杂,我们根据运行环境不同下载不同版本的libtorch(CPU和GPU),然后使用cmake配置后,利用VS进行编译就可以直接使用,其中遇到的问题大部分时环境的问题,我们的代码并不需要修改,是可以跨平台的,我也在VS2015和VS2017中进行了测试,都是可以的。
可能会遇到的问题
我在其中遇到了两个小问题,稍微查下就解决了,现在贴出来,如果和我遇到同样的就不用去google了…
在Window下查看指定camke编译器的命令
在window中指定cmake的编译器构架:
代码语言:javascript复制cmake -G
CMake Error: No generator specified for -G
Generators
Visual Studio 15 2017 [arch] = Generates Visual Studio 2017 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 14 2015 [arch] = Generates Visual Studio 2015 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 12 2013 [arch] = Generates Visual Studio 2013 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 11 2012 [arch] = Generates Visual Studio 2012 project files.
Optional [arch] can be "Win64" or "ARM".
Visual Studio 10 2010 [arch] = Generates Visual Studio 2010 project files.
Optional [arch] can be "Win64" or "IA64".
Visual Studio 9 2008 [arch] = Generates Visual Studio 2008 project files.
Optional [arch] can be "Win64" or "IA64".
Borland Makefiles = Generates Borland makefiles.
NMake Makefiles = Generates NMake makefiles.
NMake Makefiles JOM = Generates JOM makefiles.
Green Hills MULTI = Generates Green Hills MULTI files
(experimental, work-in-progress).
MSYS Makefiles = Generates MSYS makefiles.
MinGW Makefiles = Generates a make file for use with
mingw32-make.
Unix Makefiles = Generates standard UNIX makefiles.
Ninja = Generates build.ninja files.
Watcom WMake = Generates Watcom WMake makefiles.
CodeBlocks - MinGW Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles = Generates CodeBlocks project files.
CodeBlocks - NMake Makefiles JOM
= Generates CodeBlocks project files.
CodeBlocks - Ninja = Generates CodeBlocks project files.
CodeBlocks - Unix Makefiles = Generates CodeBlocks project files.
CodeLite - MinGW Makefiles = Generates CodeLite project files.
CodeLite - NMake Makefiles = Generates CodeLite project files.
CodeLite - Ninja = Generates CodeLite project files.
CodeLite - Unix Makefiles = Generates CodeLite project files.
Sublime Text 2 - MinGW Makefiles
= Generates Sublime Text 2 project files.
Sublime Text 2 - NMake Makefiles
= Generates Sublime Text 2 project files.
Sublime Text 2 - Ninja = Generates Sublime Text 2 project files.
Sublime Text 2 - Unix Makefiles
= Generates Sublime Text 2 project files.
Kate - MinGW Makefiles = Generates Kate project files.
Kate - NMake Makefiles = Generates Kate project files.
Kate - Ninja = Generates Kate project files.
Kate - Unix Makefiles = Generates Kate project files.
Eclipse CDT4 - NMake Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - MinGW Makefiles
= Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Ninja = Generates Eclipse CDT 4.0 project files.
Eclipse CDT4 - Unix Makefiles= Generates Eclipse CDT 4.0 project files.
缺失nvToolsExt64_1.dll
如果在使用GPU版本的libtorch的时候遇到缺少nvToolsExt64_1.dll
,直接从网上下一个放到C:WindowsSystem32
目录下即可(win10)。