1、创建tensor张量

  1. //torch::rand
  2. torch::Tensor a = torch::rand({ 2,3 });
  3. //torch::empty
  4. torch::Tensor b = torch::empty({ 2,3 });
  5. //torch::ones
  6. torch::Tensor c = torch::ones({ 2,3 });
  7. //torch::zeros
  8. torch::Tensor d = torch::zeros({ 2,3 });
  9. //torch::full
  10. torch::Tensor e = torch::full({ 2,3 }, 5);
  11. //torch::full_like
  12. torch::Tensor f = torch::full_like(a, 5);

2、访问tensor中元素的值

  1. torch::Tensor a = torch::rand({ 3,4 });
  2. cout << a << endl;
  3. //int val = a[0][1]; 错误用法,类型不匹配
  4. cout << typeid(a[0][1]).name() << endl;//a[0][1]的数据类型依然为tensor
  5. float val = a[0][1].item().toFloat();
  6. cout << val << endl;

输出

  1. 0.8186 0.3430 0.0754 0.0491
  2. 0.7771 0.1150 0.9880 0.1210
  3. 0.0467 0.9136 0.5798 0.7235
  4. [ CPUFloatType{3,4} ]
  5. class at::Tensor
  6. 0.342993

3、打印数据及类型

  1. //.to(torch::kCUDA)指定是CPU还是GPU数据
  2. torch::Tensor box = torch::rand({ 2,3 }).to(torch::kCUDA);
  3. cout << box << endl; //打印box的数据及类型
  4. box.print(); //打印box的类型

输出

  1. 0.2017 0.6013 0.5738
  2. 0.1458 0.0477 0.9191
  3. [ CUDAFloatType{2,3} ]
  4. [CUDAFloatType [2, 3]]

4、获取tensor的维度信息

  1. torch::Tensor a = torch::rand({ 3,4 });
  2. a.print();
  3. cout << "维度:" << a.sizes() << endl;
  4. cout << "第一个维度:" << a.size(0) << endl;
  5. cout << "第二个维度:" << a.size(1) << endl;
  6. cout << "元素个数:" << a.numel() << endl;

输出

  1. [CPUFloatType [3, 4]]
  2. 维度:[3, 4]
  3. 第一个维度:3
  4. 第二个维度:4
  5. 元素个数:12

5、拼接 tensor torch::cat

按第一个维度进行拼接(二维时为按行拼接,两个张量列数需相等)

  1. torch::Tensor a = torch::rand({ 2,3 });
  2. torch::Tensor b = torch::rand({ 1,3 });
  3. torch::Tensor a_b = torch::cat({ a,b }, 0);
  4. std::cout << a << std::endl;
  5. std::cout << b << std::endl;
  6. std::cout << a_b << std::endl;

输出

  1. 0.1268 0.5906 0.4777
  2. 0.7290 0.0518 0.3197
  3. [ CPUFloatType{2,3} ]
  4. 0.4441 0.3615 0.4845
  5. [ CPUFloatType{1,3} ]
  6. 0.1268 0.5906 0.4777
  7. 0.7290 0.0518 0.3197
  8. 0.4441 0.3615 0.4845
  9. [ CPUFloatType{3,3} ]

按第二个维度进行拼接(二维时为按列拼接,两个张量行数需相等)

  1. torch::Tensor a = torch::rand({ 2,3 });
  2. torch::Tensor b = torch::rand({ 2,1 });
  3. torch::Tensor a_b = torch::cat({ a,b }, 1);
  4. std::cout << a << std::endl;
  5. std::cout << b << std::endl;
  6. std::cout << a_b << std::endl;

输出

  1. 0.5937 0.5077 0.6332
  2. 0.2676 0.3583 0.6229
  3. [ CPUFloatType{2,3} ]
  4. 0.2329
  5. 0.1592
  6. [ CPUFloatType{2,1} ]
  7. 0.5937 0.5077 0.6332 0.2329
  8. 0.2676 0.3583 0.6229 0.1592
  9. [ CPUFloatType{2,4} ]

6、torch 的切片操作

index浅拷贝。取多行或多列

  1. torch::Tensor a = torch::rand({ 3,4 });
  2. cout << a << endl;
  3. torch::Tensor b = a.index({ "...", 2 });
  4. cout << b << endl;
  5. a[1][1] = 100;
  6. cout << "after changed a" << endl;
  7. cout << a << endl;
  8. cout << b << endl;
  1. 0.2273 0.4347 0.0941 0.4216
  2. 0.3449 0.3092 0.5139 0.6308
  3. 0.0158 0.2166 0.6826 0.0597
  4. [ CPUFloatType{3,4} ]
  5. 0.0941
  6. 0.5139
  7. 0.6826
  8. [ CPUFloatType{3} ]
  9. after changed a
  10. 0.2273 0.4347 0.0941 0.4216
  11. 0.3449 100.0000 0.5139 0.6308
  12. 0.0158 0.2166 0.6826 0.0597
  13. [ CPUFloatType{3,4} ]
  14. 0.0941
  15. 0.5139
  16. 0.6826
  17. [ CPUFloatType{3} ]

7、squeeze() unsqueeze()

squeeze(arg)表示若第arg维的维度值为1,则去掉该维度。否则tensor不变

  1. torch::Tensor a = torch::rand({ 3,1,4 });
  2. a.print();
  3. torch::Tensor b = a.squeeze(1);
  4. b.print();

输出

  1. [CPUFloatType [3, 1, 4]]
  2. [CPUFloatType [3, 4]]

unsqueeze(arg)与squeeze(arg)作用相反,表示在第arg维增加一个维度值为1的维度。

  1. torch::Tensor a = torch::rand({ 3,4 });
  2. a.print();
  3. torch::Tensor b = a.unsqueeze(1);
  4. b.print();

输出

  1. [CPUFloatType [3, 4]]
  2. [CPUFloatType [3, 1, 4]]

8、cv::Mat 转tensor

  1. void detectClass::mat2tensor(const Mat& frame, torch::Tensor& imgTensor)
  2. {
  3. Mat img;
  4. cv::resize(frame, img, cv::Size(640, 384)); //缩放到合适的大小
  5. cv::cvtColor(img, img, cv::COLOR_BGR2RGB); //BGR->RGB
  6. //Mat 转tensor并传递到device
  7. imgTensor = torch::from_blob(img.data, { img.rows, img.cols,3 }, torch::kByte).to(device);
  8. //调整数组维度顺序,{height,width,channels}to{channels,height,width}
  9. imgTensor = imgTensor.permute({ 2,0,1 });
  10. imgTensor = imgTensor.toType(torch::kFloat);//转为浮点类型
  11. imgTensor = imgTensor.div(255);//归一化
  12. imgTensor = imgTensor.unsqueeze(0);//扩展第一个维度{1,channels,height,width}
  13. }

9、排序torch::sort

  1. torch::Tensor a = torch::rand({ 10 });
  2. cout << "before sort:\n" << a << endl;
  3. std::tuple<torch::Tensor, torch::Tensor> b = a.sort(0, 1);
  4. cout << "after sort:\n" << std::get<0>(b) << endl;

输出

  1. before sort:
  2. 0.9401
  3. 0.6829
  4. 0.1528
  5. 0.3947
  6. 0.2390
  7. 0.5201
  8. 0.8390
  9. 0.4659
  10. 0.6646
  11. 0.9344
  12. [ CPUFloatType{10} ]
  13. after sort:
  14. 0.9401
  15. 0.9344
  16. 0.8390
  17. 0.6829
  18. 0.6646
  19. 0.5201
  20. 0.4659
  21. 0.3947
  22. 0.2390
  23. 0.1528
  24. [ CPUFloatType{10} ]

10、clamp 把数值控制在 min max 之间

  1. torch::Tensor a = torch::rand({ 2,3 });
  2. a[0][0] = 20;
  3. a[0][1] = 21;
  4. a[0][2] = 22;
  5. a[1][0] = 23;
  6. a[1][1] = 24;
  7. cout << a << endl;
  8. torch::Tensor b = a.clamp(21, 22);
  9. cout << b << endl;

输出

  1. 20.0000 21.0000 22.0000
  2. 23.0000 24.0000 0.1455
  3. [ CPUFloatType{2,3} ]
  4. 21 21 22
  5. 22 22 21
  6. [ CPUFloatType{2,3} ]

11、判断张量中每个值是否大于指定值

  1. torch::Tensor a = torch::rand({ 2,3 });
  2. std::cout << a << std::endl;
  3. torch::Tensor b = a > 0.5;
  4. std::cout << b << std::endl;

输出

  1. 0.3014 0.0964 0.6515
  2. 0.4000 0.6095 0.7024
  3. [ CPUFloatType{2,3} ]
  4. 0 0 1
  5. 0 1 1
  6. [ CPUBoolType{2,3} ]

12、转置 Tensor::transpose

  1. torch::Tensor a = torch::rand({2,3});
  2. std::cout<<a<<std::endl;
  3. torch::Tensor b = a.transpose(1,0);
  4. 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);