libtorch(pytorch c++)的大多数api和pytorch保持一致。
使用之前要导入torch
#include <torch/torch.h>
#include <torch/script.h>
1. 张量初始化
1.1 固定的值与尺寸
在C++中,使用{}来表示尺寸
zeros()
zeros()产生值全为0的张量。
// 得到一个三维的全0
auto x=torch::zeros({2,3,4});
cout<<x;
ones()
ones()产生值全为1的张量。
auto x = torch::ones({2,3,4});
std::cout<<x;
eye()
eye()产生单位矩阵张量,传入行数与列数即可
x=torch::eye(4,5);
full()
full()产生使用指定数值填充的张量。
x=torch::full({2,3,4},10);
tensor()
tensor()使用指定的值来创建张量,每一位的都要指定。
x = torch::tensor({ {{1,2,3},{4,5,6},{7,8,9} }, {{1,2,3},{4,5,6},{7,8,9} }});
固定大小,任意值
rand()
rand产生0-1之间的随机值来填充
x=torch::rand({2,3,4});
randn()
randn取**正态分布N(0,1)**的随机值
x=torch::randn({2,3,4});
randint()
randint取 [min,max) 的随机整型数值。
// 前两个参数为min与max
x=torch::randint(0,4,{2,3,4})
从c++的其他数据类型转换而来
libtorch可以接受其他数据指针,通过from_blob函数即可转换。
如果图像是opencv加载的,那么可以通过from_blob将图像指针转成张量。
格式:
from_blob(其他数据,尺寸,元素的数据类型)
int a[6]={1,2,3,4,5,6};
std::vector<float> b={1,2,3,4};
auto x=torch::from_blob(a,{2,3},torch::kFloat);
auto y=torch::from_blob(b,{2,2},torch:kFloat);
使用已有张量
Tensor()
Tensor()需要传入已有张量。
auto d = torch::Tensor(b)等价于auto d = b。这种拷贝是浅拷贝,两个张量会互相影响。
b中的值发生改变,d也将发生改变;但是b如果只是张量变形,d却不会跟着变形,仍旧保持初始化时的形状
auto x=torch::fully({2,3,4},10);
auto y=torch::Tensor(x);
zeros_like()、ones_like()、rand_like()、full_like()等等 xxx_like()
顾名思义将产生和原张量b相同形状的0张量、1张量与随机张量。注意是形状相同。
x=torch::fully({3,4},10);
y=torch::zeros_like(x);
y=torch::ones_like(x);
y=torch::rand_like(x);
y=torch::full_like(x)
clone()
完全拷贝成一个新的张量,原张量不是同一个张量,不会互相影响,也就是深拷贝。
y=torch::clone(x);
张量变形
torch改变张量形状,不改变张量存储的data指针指向的内容,只改变张量的取数方式。
libtorch的变形方式和pytorch一致,有view,reshape等常用变形。
view
调用view函数得到的张量,虽然形状改变了,但是其与原张量是共用内存的,并没有开辟新的内存,二者会相互影响
x = torch::full({10},1);
auto a = x.view({2,5});
cout<<a<<endl;
reshape
调用reshape得到的张量开辟了新的内存,传入一个尺寸。
auto b = x.reshape({5,2});
cout<<b<<endl;
permute
实现多个维度之间的转置,也就是实现数组数据的重新映射,张量有多少个维度就需要传入多少个参数。
参数dims用矩阵的维数代入,一般默认从0开始。即第0维,第1维等等。
permute({dim0,dim1...})
如果是两维,dim分别为0与1。
permute({0,1})这里不做任何变化
permute({1,0})得到的就是矩阵的转置
如果是三维,dim分别为0,1,2
0代表共有几块,1代表每一块中有多少行,2代表每一块中有多少列。
例如: x[2][3][4]
permute({0,2,1}):1与2交换
在原数据中,将**x[a][b][c]映射到第三维与第二维的索引交换的x[a][c][b]**中
size变为{2,4,3}
x[0][0][0]=x[0][0][0]
x[0][1][0]=x[0][0][1] #第二维与第三维交换
permute({1,0,2}):0与1交换
在原数据中,将 x[a][b][c] 映射到第三维与第二维的索引交换的 x[b][a][c] 中
size变为{4,2,3}
permute({1,2,0})
在原数据中,将 x[a][b][c] 映射到第三维与第二维的索引交换的 x[b][c][a] 中
size变为{3,4,2}
例子:
x = torch::arange(24).view({2,3,4});
auto c=x.permute({0,2,1});
cout<<c<<endl;