1、创建tensor张量
//torch::rand
torch::Tensor a = torch::rand({ 2,3 });
//torch::empty
torch::Tensor b = torch::empty({ 2,3 });
//torch::ones
torch::Tensor c = torch::ones({ 2,3 });
//torch::zeros
torch::Tensor d = torch::zeros({ 2,3 });
//torch::full
torch::Tensor e = torch::full({ 2,3 }, 5);
//torch::full_like
torch::Tensor f = torch::full_like(a, 5);
2、访问tensor中元素的值
torch::Tensor a = torch::rand({ 3,4 });
cout << a << endl;
//int val = a[0][1]; 错误用法,类型不匹配
cout << typeid(a[0][1]).name() << endl;//a[0][1]的数据类型依然为tensor
float val = a[0][1].item().toFloat();
cout << val << endl;
输出
0.8186 0.3430 0.0754 0.0491
0.7771 0.1150 0.9880 0.1210
0.0467 0.9136 0.5798 0.7235
[ CPUFloatType{3,4} ]
class at::Tensor
0.342993
3、打印数据及类型
//.to(torch::kCUDA)指定是CPU还是GPU数据
torch::Tensor box = torch::rand({ 2,3 }).to(torch::kCUDA);
cout << box << endl; //打印box的数据及类型
box.print(); //打印box的类型
输出
0.2017 0.6013 0.5738
0.1458 0.0477 0.9191
[ CUDAFloatType{2,3} ]
[CUDAFloatType [2, 3]]
4、获取tensor的维度信息
torch::Tensor a = torch::rand({ 3,4 });
a.print();
cout << "维度:" << a.sizes() << endl;
cout << "第一个维度:" << a.size(0) << endl;
cout << "第二个维度:" << a.size(1) << endl;
cout << "元素个数:" << a.numel() << endl;
输出
[CPUFloatType [3, 4]]
维度:[3, 4]
第一个维度:3
第二个维度:4
元素个数:12
5、拼接 tensor torch::cat
按第一个维度进行拼接(二维时为按行拼接,两个张量列数需相等)
torch::Tensor a = torch::rand({ 2,3 });
torch::Tensor b = torch::rand({ 1,3 });
torch::Tensor a_b = torch::cat({ a,b }, 0);
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << a_b << std::endl;
输出
0.1268 0.5906 0.4777
0.7290 0.0518 0.3197
[ CPUFloatType{2,3} ]
0.4441 0.3615 0.4845
[ CPUFloatType{1,3} ]
0.1268 0.5906 0.4777
0.7290 0.0518 0.3197
0.4441 0.3615 0.4845
[ CPUFloatType{3,3} ]
按第二个维度进行拼接(二维时为按列拼接,两个张量行数需相等)
torch::Tensor a = torch::rand({ 2,3 });
torch::Tensor b = torch::rand({ 2,1 });
torch::Tensor a_b = torch::cat({ a,b }, 1);
std::cout << a << std::endl;
std::cout << b << std::endl;
std::cout << a_b << std::endl;
输出
0.5937 0.5077 0.6332
0.2676 0.3583 0.6229
[ CPUFloatType{2,3} ]
0.2329
0.1592
[ CPUFloatType{2,1} ]
0.5937 0.5077 0.6332 0.2329
0.2676 0.3583 0.6229 0.1592
[ CPUFloatType{2,4} ]
6、torch 的切片操作
index浅拷贝。取多行或多列
torch::Tensor a = torch::rand({ 3,4 });
cout << a << endl;
torch::Tensor b = a.index({ "...", 2 });
cout << b << endl;
a[1][1] = 100;
cout << "after changed a" << endl;
cout << a << endl;
cout << b << endl;
0.2273 0.4347 0.0941 0.4216
0.3449 0.3092 0.5139 0.6308
0.0158 0.2166 0.6826 0.0597
[ CPUFloatType{3,4} ]
0.0941
0.5139
0.6826
[ CPUFloatType{3} ]
after changed a
0.2273 0.4347 0.0941 0.4216
0.3449 100.0000 0.5139 0.6308
0.0158 0.2166 0.6826 0.0597
[ CPUFloatType{3,4} ]
0.0941
0.5139
0.6826
[ CPUFloatType{3} ]
7、squeeze() unsqueeze()
squeeze(arg)表示若第arg维的维度值为1,则去掉该维度。否则tensor不变
torch::Tensor a = torch::rand({ 3,1,4 });
a.print();
torch::Tensor b = a.squeeze(1);
b.print();
输出
[CPUFloatType [3, 1, 4]]
[CPUFloatType [3, 4]]
unsqueeze(arg)与squeeze(arg)作用相反,表示在第arg维增加一个维度值为1的维度。
torch::Tensor a = torch::rand({ 3,4 });
a.print();
torch::Tensor b = a.unsqueeze(1);
b.print();
输出
[CPUFloatType [3, 4]]
[CPUFloatType [3, 1, 4]]
8、cv::Mat 转tensor
void detectClass::mat2tensor(const Mat& frame, torch::Tensor& imgTensor)
{
Mat img;
cv::resize(frame, img, cv::Size(640, 384)); //缩放到合适的大小
cv::cvtColor(img, img, cv::COLOR_BGR2RGB); //BGR->RGB
//Mat 转tensor并传递到device
imgTensor = torch::from_blob(img.data, { img.rows, img.cols,3 }, torch::kByte).to(device);
//调整数组维度顺序,{height,width,channels}to{channels,height,width}
imgTensor = imgTensor.permute({ 2,0,1 });
imgTensor = imgTensor.toType(torch::kFloat);//转为浮点类型
imgTensor = imgTensor.div(255);//归一化
imgTensor = imgTensor.unsqueeze(0);//扩展第一个维度{1,channels,height,width}
}
9、排序torch::sort
torch::Tensor a = torch::rand({ 10 });
cout << "before sort:\n" << a << endl;
std::tuple<torch::Tensor, torch::Tensor> b = a.sort(0, 1);
cout << "after sort:\n" << std::get<0>(b) << endl;
输出
before sort:
0.9401
0.6829
0.1528
0.3947
0.2390
0.5201
0.8390
0.4659
0.6646
0.9344
[ CPUFloatType{10} ]
after sort:
0.9401
0.9344
0.8390
0.6829
0.6646
0.5201
0.4659
0.3947
0.2390
0.1528
[ CPUFloatType{10} ]
10、clamp 把数值控制在 min max 之间
torch::Tensor a = torch::rand({ 2,3 });
a[0][0] = 20;
a[0][1] = 21;
a[0][2] = 22;
a[1][0] = 23;
a[1][1] = 24;
cout << a << endl;
torch::Tensor b = a.clamp(21, 22);
cout << b << endl;
输出
20.0000 21.0000 22.0000
23.0000 24.0000 0.1455
[ CPUFloatType{2,3} ]
21 21 22
22 22 21
[ CPUFloatType{2,3} ]
11、判断张量中每个值是否大于指定值
torch::Tensor a = torch::rand({ 2,3 });
std::cout << a << std::endl;
torch::Tensor b = a > 0.5;
std::cout << b << std::endl;
输出
0.3014 0.0964 0.6515
0.4000 0.6095 0.7024
[ CPUFloatType{2,3} ]
0 0 1
0 1 1
[ CPUBoolType{2,3} ]
12、转置 Tensor::transpose
torch::Tensor a = torch::rand({2,3});
std::cout<<a<<std::endl;
torch::Tensor b = a.transpose(1,0);
std::cout<<b<<std::endl;
输出
0.0411 0.1815 0.8453
0.3202 0.9694 0.3321
[ CPUFloatType{2,3} ]
0.0411 0.3202
0.1815 0.9694
0.8453 0.3321
[ CPUFloatType{3,2} ]
13、加载模型
torch::Device m_device(torch::kCUDA);
torch::jit::script::Module m_model = torch::jit::load(path_pt);
m_model.to(m_device);