vs2015编译错误解决:/jit/pickler.h(34): error C2059: 语法错误:“常量” ;error C3805: “常量”: 意外标记,应输入“}”或者“,
libtorch环境搭建、生成库文件、测试
利用Pytorch的C++前端(libtorch)读取预训练权重并进行预测
tensorFromBlob”: 不是“at::DeprecatedTypeProperties”的成员
(1)libtorch找不到GPU
通过python import torch时,返回为True。所以cuda、cudnn和torch都没问题。
在“属性 --> 链接器 --> 命令行 --> 其他选项”中添加:
/INCLUDE:?warp_size@cuda@at@@YAHXZ
(2)tensor、mat互转
方法一:
cv::Mat resultImg(960, 960, CV_8U , out_byte.data_ptr());#这里遇到过报错,out_byte前面数据处理完,在这里处理可以会报错,512尺寸没问题,1024不知为何报错了
方法二:
std::memcpy((void*)resultImg.data, out_byte.data_ptr(), out_byte.numel());
torch::Tensor tensor_image = torch::from_blob(image.data, { 1, image_h, image_w, 3 }, torch::kByte).to(device_type);
tensor_image = tensor_image.permute({ 0, 3, 1, 2 }).toType(torch::kFloat);
module.eval();
torch::NoGradGuard no_grad;
torch::Tensor out_tensor = module.forward({ tensor_image }).toTensor();
矩阵和tensor相互转换
(3)返回三通道用到contiguous()
torch::Tensor out = out_tensor.squeeze().detach().to(torch::kCPU);
torch::Tensor out_byte = out.clamp(0, 255).toType(torch::kUInt8).permute({ 1, 2, 0 }).contiguous();
cv::Mat resultImg(960, 960, CV_8UC3, out_byte.data_ptr());
cv::Mat resultImg_(960, 960, CV_8UC3);
cv::cvtColor(resultImg, resultImg_, CV_RGB2BGR);
返回三通道tensor不用contiguous()会出现下面的重复图像
(4)C++不通过libtorch调用pytorch模型
关键是Mat图像转化为PyObject对象
Windows下C++调用Python版的Pytorch模型
(5)tensor类型转换
# tensor转float
auto x = at::tensor(1.0);
float x_val = x.item().toFloat();#法一
float fmax_1 = max_1.item<float>();#法二
# float转tensor
torch::Tensor b = torch::tensor(0.33 )
cx.toType(torch::kFloat);
(6)libtorch教程
c++ 部署libtorch时常用操作API6.libtorch张量的切片与索引c++ 部署libtorch 时对Tensor块的常用操作API libtorch (pytorch c++) 教程(二)libtorch 常用api函数示例(史上最全、最详细)
(7)libtorch切片
torch::select()只可以取一个索引,内存共享
torch::index_select()可以取好几个索引,没有内存共享。
torch::slice()获取tensor数据块中roi区域的数据,不复制,内存共享。
torch::index通过索引获取张量的值
torch::index_put_通过切片或索引改变张量的值
torch::masked_select根据条件选出指定的元素值
a[2,2]等价 a.index({ 2, 2 })
a[…,2]等价 a.index({ “…”, 2 })
a[:,::2]等价 a.index({ Slice(None), Slice(None,None,2)})
a[1::2,:]等价 a.index({ Slice(1,None, 2),Slice(None) })
a[1:3,:]等价 a.index({ Slice(1,3),Slice(None) })
(8)libtorch张量的合并与拆分
(9) libtorch张量基本数值类型
#include <torch/torch.h>
#include <torch/script.h>
#include <opencv2/opencv.hpp>
int main() {
auto a = torch::tensor({ {1,2,3},{-4,-5,-6} }, torch::kI8);
auto b = torch::tensor({ {1,2,3},{4,5,6} }, torch::kU8);
auto c = torch::tensor({ 1.2,1.3,20.159 }, torch::kF32); //kF32是kFloat32缩写
auto d = torch::tensor({ 0,1,2 }, torch::kBool);
std::cout << "a:\n" << a << std::endl;
std::cout << "b:\n" << b << std::endl;
std::cout << "c:\n" << c << std::endl;
std::cout << "d:\n" << d << std::endl;
return 0;
}
(10)模型转换
pytorch转libtorch,全网最全资料
- 方法一:Tracing
缺点是如果模型中存在控制流比如if-else语句,一组输入只能遍历一个分支,这种情况下就没办法完整的把模型信息记录下来。 - 方法二:Scripting
(11)libtorch组成
三大命名空间:at,torch与c10。at(ATen)负责声明和定义Tensor运算,是最常用到的命名空间,c10是 ATen 的基础,包含了PyTorch的核心抽象、Tensor和Storage数据结构的实际实现。torch命名空间下定义的 Tensor 相比于ATen 增加自动求导功能。
- C10,来自于Caffe Tensor Library的缩写。这里存放的都是最基础的Tensor库的代码,可以运行在服务端和移动端。PyTorch目前正在将代码从ATen/core目录下迁移到C10中。
- ATen,来自于 A TENsor library for C++11的缩写,ATen部分有大量的代码是来声明和定义Tensor运算相关的逻辑的
- Torch
(12) .mul()和.mul_(),.exp()和.exp_()区别
所有带"——"都是inplace的 意思就是操作后 原数也会改动
不带 “——” 的 只在操作适时候改变数据,操作结束后数据变回原状