首先需要配置环境。
【1】一定要保证libtorch和pytorch版本完全对应(包括对应的cuda版本,比如pytorch对应的是cuda版本11.3,那libtorch同版本的也要找对应cuda版本11.3的。)完全对应的意思是,pytorch是10.1.3,那libtorch也必须是10.1.3,不能是10.1.2,10.1.4。一定要保证完全对应!
这个链接是libtorch各版本的下载链接(windows版本):
https://blog.csdn.net/weixin_43742643/article/details/115218126
【2】也可以从用conda或者pip指令下载。记得配置好下载的镜像路径。
配置镜像参考链接:
https://blog.csdn.net/weixin_45465214/article/details/103605302
如果用指令下载不了,就直接去清华镜像官网找到想要的版本,然后直接下载压缩包,本地安装。清华镜像官网:
https://mirrors.tuna.tsinghua.edu.cn/
【3】要注意libtorch是debug版本还是release版本!这很重要,版本一定要和你的项目对应!
安装成功后参照下面的链接改一下项目的配置。
参考配置链接:
https://blog.csdn.net/weixin_45632168/article/details/114679263
【4】在 链接器>输入>附加依赖项 里面,保险起见,把所安装的libtorch的lib文件夹下所有的lib都写进去。(有的lib会有两个版本,名字+d.lib说明是debug版本的lib)。
【5】把lib文件夹下所有的dll文件拷贝到项目的exe文件夹下。
!!!代码部分!!!
【1】首先需要在pytorch项目里保存模型为.pt文件,官网提供了两种方式。
官网教程文档:
https://pytorch.org/tutorials/advanced/cpp_export.html
我的代码:
# 选择设备,有cuda用cuda,没有就用cpu
device = torch.device('cpu')#'cuda' if torch.cuda.is_available() else 'cpu')
# 加载网络,图片单通道,分类为1。
net = UNet(n_channels=1, n_classes=1)
# 将网络拷贝到deivce中
net.to(device=device)
# 加载模型参数
net.load_state_dict(torch.load('best_model.pth', map_location=device))
# 测试模式
net.eval()
#读取mat文件
img=h5py.File("C:\\Users\\user\\Desktop\\layer.mat")
x=img.get('Sinogram').value
# 转为灰度图
img =x.swapaxes(0,1)
# 转为batch为1,通道为1,大小为512*512的数组
img = img.reshape(1, 1, img.shape[0], img.shape[1])
# 转为tensor
img_tensor = torch.from_numpy(img)
# 将tensor拷贝到device中,只用cpu就是拷贝到cpu中,用cuda就是拷贝到cuda中。
img_tensor = img_tensor.to(device=device, dtype=torch.float32)
# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(net, img_tensor)
# save model
traced_script_module.save("traced_unet_model.pt")
【2】然后在c++项目里加载保存好的模型,也就是pt文件,然后就可以训练了。
//用float指针初始化mat
cv::Mat idonwantsee(512,2000, CV_32S, src_mat);
cv::Mat resultImg(2000, 512, CV_8UC1);
//加载模型
torch::jit::script::Module LY_Model;
LY_Model = torch::jit::load("C:\\Users\\user\\Desktop\\traced_unet_model_gpu.pt");
// put model to gpu
LY_Model.to(at::kCUDA);
//输入数据
auto input_tensor = torch::from_blob(idonwantsee.data, { 1,1,512,512}, torch::kFloat32);
//调整一下数据维度,保证与原模型一致
input_tensor = input_tensor.permute({ 0,1,3,2 });
vector<torch::jit::IValue>inputs;
inputs.push_back(input_tensor.to(at::kCUDA));
//训练模型,如果之前这个模型被调用过一次,第二次forward速度就会更快
auto output = LY_Model.forward(inputs).toTensor();
//cuda数据同步
cudaDeviceSynchronize();
//改一下数据维度
output = output.to(torch::kCPU).squeeze(0).detach();
output = output.to(torch::kCPU).squeeze(0).detach();
auto ress=(output > 0.5);
ress = ress.mul(255).to(torch::kU8);
//输出数据拷贝
memcpy((void*)resultImg.data, ress.data_ptr(), sizeof(torch::kU8) * ress.numel());
【3】在load模型那一步报错最有可能的原因:libtorch和pytorch版本不对应导致无法解析
【4】在模型to cuda那一步报错,先看一下pytorch的cuda是否可用,不可用的话重新配置一下。
如果还是报错,就加一下命令行。
命令行参考链接:
https://blog.csdn.net/qq_36038453/article/details/120278523
如果还是报错,有可能是因为是debug版本,改成release版本。
【5】输入数据的那一步,如果是直接传入float指针会出现数据对不上的情况,但是换成cv::mat就会解决这个问题。还要注意一下数据用的是什么格式,选择正确的类型。
【6】libtorch 报错:模糊符号
参考的解决链接:
https://github.com/pytorch/pytorch/pull/15697
一个一个手动把把std改成::std