Q : Libtorch是什么及为什么用Libtorch?
A : Libtorch是pytorch的C++版本,现在的很多大型项目都是用C++写的,想使用训练好的模型,需要通过caffe等方式去集成,比较麻烦。这里pytorch官方提出了Libtorch,我们就可以把pytorch训练好的模型,打包起来,直接在C++工程中去用就好了,相比较caffe等,非常方便!
使用Libtorch的大体流程:
- 将训练好的模型打包,保存为.pt格式
- 使用Libtorch去加载.pt格式模型
1. Libtorch安装
- pytorch官网上下载libtorch各个版本的url(1.0 - 1.4)
- 1.5版本官网下载就好
注:安装时尽量pytorch版本和libtorch版本保持一致
2. 转换模型
import torch
import torchvision
# An instance of your model.
model = torchvision.models.resnet18(pretrained=True)
# 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("traced_resnet18_model.pt")
# test module
output = traced_script_module(torch.ones(1, 3, 224, 224))
print(output[0, :5])
3. C ++中使用模型
- 新建一个C++工程 example-app
- 新建main.cpp,编写如下:
#include <torch/script.h> // One-stop header.
#include <iostream>
#include <memory>
int main(int argc, const char* argv[]) {
if (argc != 2) {
std::cerr << "usage: example-app <path-to-exported-script-module>\n";
return -1;
}
torch::jit::script::Module module;
try {
// Deserialize the ScriptModule from a file using torch::jit::load().
module = torch::jit::load(argv[1]);
}
catch (const c10::Error& e) {
std::cerr << "error loading the model\n";
return -1;
}
std::cout << "ok\n";
}
- 新建Cmakelists.txt,编写如下:
cmake_minimum_required(VERSION 3.14.5)
project(example-app)
list(APPEND CMAKE_PREFIX_PATH "/data/home/depwang/source/libtorch")
list(APPEND CMAKE_PREFIX_PATH "/data/home/depwang/opencv3")
find_package(Torch REQUIRED)
find_package(OpenCV REQUIRED)
set(CMAKE_CXX_STANDARD 14)
add_executable(example-app main.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
target_link_libraries(example-app "${OpenCV_LIBS}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
- 编译
mkdir build && cd build #创建并进入build文件夹
cmake .. #根据CMakeLists.txt编译生成makefile文件
make #根据makefile编译项目
- 将2中的"traced_resnet18_model.pt"复制到build下,执行
./example-app traced_resnet18_model.pt
; 会打印出ok,代表配置成功 - 修改main.cpp,如下:
#include <torch/script.h> // One-stop header.
#include <iostream>
#include <memory>
int main(int argc, const char* argv[]) {
if (argc != 2) {
std::cerr << "usage: example-app <path-to-exported-script-module>\n";
return -1;
}
torch::jit::script::Module module;
try {
// Deserialize the ScriptModule from a file using torch::jit::load().
module = torch::jit::load(argv[1]);
}
catch (const c10::Error& e) {
std::cerr << "error loading the model\n";
return -1;
}
// 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';
std::cout << "ok\n";
}
- 重新编译,执行
#在build文件夹下
cmake ..
make
./example-app traced_resnet18_model.pt
参考:https://blog.csdn.net/guilutian0541/article/details/104729895