当作一个笔记,发现新的会更新
返回张量各个维度的尺度
at::Tensor.sizes() :返回张量所有维度的尺度
at::Tensor.size(int num) :返回第num维度的尺度(从下标0开始)
at::Tensor a = torch::ones({2, 2, 3}); //a维度{2, 2, 3)
//a.size() = {2, 2, 3};
//a.size(0) = 2;
//a.size(1) = 2;
//a.size(2) = 3'
取随机数
//4张照片,每张3个通道,每个通道28行28列的像素
at::Tensor a = torch.rand(4,3,28,28);
//torch.size([4, 3, 28, 28])
//在第一个维度上取0和1,在第二个维度上取1,2,
//等同于取第一、第二张图片中的第二个通道与第三个通道
print(a[:2, -2:, :, :].shape) //[前两个,后两个,,]左开右闭
//torch.Size([2, 2, 28, 28])
切片
参数input(Tensor):表示被选择的tensor
参数dim(int):表示是在哪个维度做选择。为1表示,在列上做选择。为0表示在行上做选择。
参数index(LongTensor):表示需要选择出的行或者列。 它是一个数组为Long形的tensor。(举一个列子,如果被选择的tensor是一个二维的。index是一维的[1,4,8],dim=0,那么就是选出第2行,第5行,第9行,下标从0开始。当然输入的tensor可能是多维的)
参数out(Tensor, optional):表示的输出到到哪个tensor上去,该参数可选。
两个张量点乘运算,即对应位置相乘再相加
//1.
torch.dot(torch::tensor({2, 3}), torch::tensor({2, 1}));
//tensor(7)
//2.
at::tensor a = torch::tensor({2, 3});
a.dot(torch.tensor({2, 1});
两个张量点乘运算,例子和dot()差不多。
两个二维矩阵做矩阵乘法运算,例子和dot()差不多。
两个高维矩阵做矩阵乘法运算,与mm区别是mm()只能是二维,matmul()可以是二维及以上维度做矩阵乘法运算
高维tensor相乘要求
· 2维以上"的尺寸必须完全对应相等;
· 2维"具有实际意义的单位,只要满足矩阵相乘的尺寸规律即可。
1.相同维度的张量
at::Tensor A.shape =(b,m,n), B.shape = (b,n,k);
torch::matmul(A,B).shape = (b,m,k)
2.不同维数的张量
at::Tensor A.shape =(m,n), B.shape = (b,n,k), C.shape=(k,l);
torch::matmul(A, B).shape = (b, m, k)
torch::matmul(B, C).shape = (b, n, l)
将张量重排维度,相当于resize_()功能。把原先tensor中的数据按照行优先的顺序排成一个一维的数据(这里应该是因为要求地址是连续存储的),然后按照参数组合成其他维度的tensor。
//初始化一个a
at::tensor a = torch::arange(0, 6);
//a : tensor([0, 1, 2, 3, 4, 5])
a.view(2, 3);
//a : tensor([[0, 1, 2],
// [3, 4, 5]])
解压缩/压缩,或者说增加维度/减少维度
unsqueeze():增加维度
at::tensor a = torch::tensor({{0, 1, 2}, {3, 4, 5}});
//当前维度(2, 3)
//a : tensor([[0, 1, 2],
// [3, 4, 5]])
//在第一维增加一个维度
a.unsqueeze(1) //增加第一维度,注意:第1维(下标从0开始)增加“1”,倒数第二个就是unsqueeze(-2)
//当前维度(2, 1, 3)
//a : tensor([[[0, 1, 2]],
// [[3, 4, 5]]])
squeeze():减少维度
squeeze()与unsqueeze()操作相反,继续上面的例子
//当前维度(2, 1, 3)
//a : tensor([[[0, 1, 2]],
// [[3, 4, 5]]])
a.squeeze(1) //降低第一维度,index和unsqueeze()相同规则
//当前维度(2, 3)
//a : tensor([[0, 1, 2],
// [3, 4, 5]])
将张量tensor的维度换位
//一个维度为(3, 28, 28)的照片
at::Tensor a = torch::ones({3, 28, 28});
a.purmute(1, 2, 0); //根据原维度的维度下标(从0开始)指定新维度
//维度变为(28, 28, 3)
一个实用程序类,它接受一个包含多个值的容器,或者一个在内部重复“D”次的值。这对于表示多维参数很有用,但通常在所有维度上大小相同。例如,二维卷积的核大小有x和y长度,但x和y通常相等。在这种情况下,只需将’3’传递给一个’ExpandingArray<2>',它就会“扩展”到`{3,3}。(API注释)
其实质就是一个大小为D的std::array
需要注意的一点是使用容器初始化时,传入的容器如vector等的大小须与ExpandingArray的大小D相同,否则会报错。
用于卷积类初始化时的卷积模块
ConvOptions(
int64_t in_channels, //输入通道数
int64_t out_channels, //输出通道数
ExpandingArray<D> kernel_size) :
in_channels_(in_channels),
out_channels_(out_channels),
kernel_size_(std::move(kernel_size)) {}
使用宏创建一个类
源码:
#define TORCH_MODULE_IMPL(Name, ImplType) \
class Name : public torch::nn::ModuleHolder<ImplType> { /* NOLINT */ \
public: \
using torch::nn::ModuleHolder<ImplType>::ModuleHolder; \
using Impl = ImplType; \
}
/// Like `TORCH_MODULE_IMPL`, but defaults the `ImplType` name to `Impl`.
#define TORCH_MODULE(Name) TORCH_MODULE_IMPL(Name, Name##Impl)
表示张量所在的计算设备。一个设备由一个类型和一个设备索引或序号来唯一标识,该类型指定了它所属的机器类型(例如CPU或CUDA GPU),该设备索引或序号在有多个特定类型时标识特定的计算设备。设备索引是可选的,在默认状态下(抽象地)表示“当前设备”。此外,如果显式存储了设备索引的值,则有两个约束:
1.负指数代表当前设备,非负指数代表具体设备,
2.当设备类型为CPU时,设备索引必须为零。
torch::Device devive(torch::kCPU):