Pytorch保存模型权重文件有两种方式:
1.保存整个模型及模型参数的方式:
torch.save(self_model, "unet.pth")
2.保存模型参数方式:
torch.save(self_model.state_dict(), "unet.pth")
由于写模型的时候,大家定义模型的方式不同,使用第二种方式的时候,偶尔会存在无效的参数(像博主这里会有.model的层),这样在转pt格式前就需要将这些无效层手动去除,比较麻烦。所以在里博主推荐使用第一种方式将权重和整个模型都保存下来,方便后续将xxx.pth格式转为xxx.pt格式。
import torch
1.model_weight_path = "使用上述第一种方式保存的pth模型文件路径"
2.temp_model = torch.load(model_weight_path, map_location="cpu")
3.device = torch.device("cpu")
4.model = temp_model.to(device )
5.traced_script_model = torch.jit.trace(model, torch.ones(Batch_Size, Channel, H, W))
6.traced_script_model.save("./xxx.pt")
这里需要注意以下几点:
1.这里需要留意一下自己的Pytorch的版本(博主是1.8.1)
2.由于后续C++部署后计算机无GPU,所以在上述代码的第二行和第三行,需要设
置"map_location"和"torch.device(“cpu”)",若是GPU版本,则将其改为gpu即可。
3.第五行代码中,torch.jit.trace()的第二个参数是自己模型输入部分,第一个batch_size设置为1即可,后序三个参数为图像的高、宽和通道数,这四个参数的顺序可根据自己的模型输入进行调整。
可以去Pytorch的官网下载所对应的libtorch,此处博主配置的是cpu版本的libtorch,下载选择选项如下图所示:
按照上图的1-5序号进行选择下载,选择对应的Debug和Release版本。有些同学用的可能不是最新版本的pytorch,但是官网上只能找到最新版本的libtorch,所以教大家一个方法,在序号6的箭头部分,将最新版本的1.10.1(以后新的版本不为1.10.1)改为自己的pytorch版本即可,博主的Pytorch为1.8.1版本,则Release下载链接就是https://download.pytorch.org/libtorch/cpu/libtorch-win-shared-with-deps-1.8.1%2Bcpu.zip。
将下载后的libtorch文件加压后为一个名为libtorch的文件夹,如下图所示:
打开Visual Studio20xx版本(博主使用的是vs 2017),点击菜单栏中的视图->
其他窗口->属性管理器中,选择对应的Release或Debug版本进行libtorch环境的添加;
以Release x64(博主使用的是Release x64版)为例,右键点击Release | x64文件夹,选择添加新项目属性表,构建新的props文件(名称随意)后,上述Release | x64文件夹中多出一个新建的props文件,如下图所示;
右键点击选择其文件夹的属性,这里需要配置三个部分:
1.VC++目录->包含目录:
选择编辑后,添加刚才解压出文件夹libtorch->include文件的绝对路径到包含目录;
2.VC++目录->库目录:
选择编辑后,添加libtorch->lib文件夹的绝对路径到库目录;
3.连接器->输入->附加依赖项:
添加torch.lib、c10.lib、caffe2_module_test_dynamic.lib和torch_cpu.lib的绝对路径到附加依赖项中即可。同时需要将上述三个所对应的xx.dll文件复制到C++路径下。
4.项目属性页->常规->SDL
将SDL检查设置成“否”,如下图所示:
5.项目属性页->语言->符合模式
将符合模式设置成"否",如下图所示:
♥上述4和5如果不设置,会报很多奇奇怪怪的错误无法解决。
以上就完成了C++ libtorch的所有环境的配置。
使用下述代码测试pt文件,不报错说明pt文件可以使用libtorch成功加载。
#include
#include
#include
using namespace std;
using torch::jit::script::Module;
int main()
{
string ptPath = "./xxx.pt";
Module module = torch::jit::load(ptPath );
assert(module != nullptr);
cout << "pt file load success~";
// Create a vector for inputs
vector inputs;
inputs.push_back(torch::ones({ 1, C, H, W }));
at::Tensor output = module.forward(inputs).toTensor();
cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';
while (1);
}
最后根据自己的语义分割模型进行图像预处理以及模型预测输出的工作即可。
1.https://blog.csdn.net/weixin_36114648/article/details/115918937
2.https://blog.csdn.net/weixin_44791964/article/details/120113686?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164053279716780265411875%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=164053279716780265411875&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-120113686.nonecase&utm_term=%E8%AF%AD%E4%B9%89%E5%88%86%E5%89%B2&spm=1018.2226.3001.4450