pytorch 学习之 Tensor 基础
程序员文章站
2022-06-12 10:05:35
...
tensor作为pytorch的基本操作对象,是首先要了解的。
一、tensor的8个属性:
# 数据相关
t.data # tensor的数据
t.dtype # tensor的数据类型
t.shape # tensor的形状
t.device # tensor所在的设备
# 梯度相关
t.grad # data的梯度
t.grad_fn # 创建tensor的function
t.requires_grad # 是否需要求导
t.is_leaf # 是否是叶子结点
二、tensor的创建:
1. 直接创建
t = torch.tensor([[0, 5, 4, 5, 8, 9], [2, 7, 5, 8, 8, 6]])
2. 从ndarray创建(ndarray转tensor)
# 创建的tensor和原来的ndarray共享内存
arr = np.array([[1, 3, 3], [4, 5, 6]])
t = torch.from_numpy(arr)
3. 创建全0张量(可用于对张量初始化)
# 创建3*3的全0张量
t = torch.zeros((3, 3))
# 按照input的形状创建全0张量
t1 = torch.zeros_like(input)
4. 创建全1张量
# 创建3*3的全1张量
t = torch.ones((3, 3))
# 按照input的形状创建全1张量
t1 = torch.ones_like(input)
5. 创建自定义全值张量
# 创建3*3的全5张量,需是float,int会报warning
t = torch.full((3, 3), 5.)
# 按照input的形状创建全6张量
t1 = torch.full_like(input, 6)
6. 创建等差1维张量
# 步长为2的等差数列1维张量,范围[0,10)
t = torch.arange(0, 10, 2)
7. 创建均分1维张量
# 创建均分1维张量,范围[0,10],长度默认100
t = torch.linspace(0, 10)
# 创建均分1维张量,范围[0,10],长度5
t1 = torch.linspace(0, 10, steps=5)
---------------------- output ----------------------
tensor([ 0.0000, 0.1010, 0.2020, 0.3030, 0.4040, 0.5051, 0.6061, 0.7071,
0.8081, 0.9091, 1.0101, 1.1111, 1.2121, 1.3131, 1.4141, 1.5152,
1.6162, 1.7172, 1.8182, 1.9192, 2.0202, 2.1212, 2.2222, 2.3232,
2.4242, 2.5253, 2.6263, 2.7273, 2.8283, 2.9293, 3.0303, 3.1313,
3.2323, 3.3333, 3.4343, 3.5354, 3.6364, 3.7374, 3.8384, 3.9394,
4.0404, 4.1414, 4.2424, 4.3434, 4.4444, 4.5455, 4.6465, 4.7475,
4.8485, 4.9495, 5.0505, 5.1515, 5.2525, 5.3535, 5.4545, 5.5556,
5.6566, 5.7576, 5.8586, 5.9596, 6.0606, 6.1616, 6.2626, 6.3636,
6.4646, 6.5657, 6.6667, 6.7677, 6.8687, 6.9697, 7.0707, 7.1717,
7.2727, 7.3737, 7.4747, 7.5758, 7.6768, 7.7778, 7.8788, 7.9798,
8.0808, 8.1818, 8.2828, 8.3838, 8.4848, 8.5859, 8.6869, 8.7879,
8.8889, 8.9899, 9.0909, 9.1919, 9.2929, 9.3939, 9.4949, 9.5960,
9.6970, 9.7980, 9.8990, 10.0000])
tensor([ 0.0000, 2.5000, 5.0000, 7.5000, 10.0000])
8. 创建对数均分1维张量
# 创建对数均分1维张量,范围[0,10],长度默认100,底默认10
# 在区间 base^(start)和 base^(end) 上按照 [start,end] 均分的 steps 个点
t = torch.logspace(0, 4, steps=2, base=2)
---------------------- output ----------------------
tensor([1., 16.])
9. 创建单位对角阵张量
t = torch.eye(3)
t = torch.eye(2, 3)
依概率分布创建张量
10. 正态分布(高斯分布)
# mean:张量 std:张量
# 此时mean和std维数(n)要相等,由他们生成n个正态分布,
# 从每个分布随机抽取一个数,组成一个1维张量
mean = torch.arange(1, 5, dtype=torch.float)
std = torch.arange(1, 5, dtype=torch.float)
t_normal = torch.normal(mean, std)
print(t_normal)
---------------------- output ----------------------
tensor([1.2151, 1.2076, 3.8062, 9.3667])
-------------------- end output --------------------
# mean:标量 std:标量
# 生成1个分布,随机取size大小的数
# 1维
t_normal = torch.normal(0, 1, size=(4,))
# 4*2维
t_normal1 = torch.normal(0, 1, size=(4, 2))
print(t_normal)
print(t_normal1)
---------------------- output ----------------------
tensor([0.2177, 0.1591, 1.2840, 0.8412])
tensor([[ 0.9582, 1.6487],
[-1.0021, 2.0398],
[ 0.2099, 0.9041],
[ 2.0284, -0.2725]])
-------------------- end output --------------------
# mean:张量 std:标量
# 生成同mean大小个分布,所有分布的std相同
# 从每个分布随机抽取一个数,组成一个1维张量
# mean:标量 std:张量 同理
mean = torch.arange(1, 5, dtype=torch.float)
# 1维
t_normal = torch.normal(mean, 1)
print(t_normal)
---------------------- output ----------------------
tensor([ 1.0105, -0.4155, 3.2346, 2.8099])
-------------------- end output --------------------
11. 标准正态分布(mean=0, std=1)
# 由于均值和标准差都确定了,所以只需size就可以创建
t_normal = torch.randn(2, 3)
12. 均匀分布
# 默认在区间[0,1)上,生成标准均匀分布
# 以下两个是等效的
# 生成2*3的tensor
t_normal = torch.rand(2, 3)
t_normal1 = torch.rand(size=(2, 3))
# torch.rand_like()
# 在区间[low,high)上,生成整数均匀分布
t_normal_int = torch.randint(2, 13, size=(5,))
# output: tensor([4, 3, 9, 5, 5])
# torch.randint_like()
13. 创建0到n-1的整数随机排列
# 常用来生成乱序索引
# 返回1维张量
t_normal = torch.randperm(5)
---------------------- output ----------------------
tensor([1, 4, 2, 3, 0])
14. 伯努利分布/0-1分布/两点分布
input = torch.rand(1, 6)
t_normal = torch.bernoulli(input)
# p 为概率,此时input的概率作用失效
t_normal1 = torch.bernoulli(input, p=0)
---------------------- output ----------------------
tensor([[0., 1., 1., 1., 0., 0.]])
tensor([[0., 0., 0., 0., 0., 0.]])
三、tensor的操作方法:
拼接
1. 将tensor按维度进行拼接 torch.cat()
import torch
# torch.cat(tensors, # 张量序列
# dim=0, # 要拼接的维度
# out=None)
t = torch.ones((2, 3))
t_0 = torch.cat([t, t], dim=0)
t_1 = torch.cat([t, t], dim=1)
---------------------- output ----------------------
t:tensor([[1., 1., 1.],
[1., 1., 1.]]) shape:torch.Size([2, 3])
t_0:tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]) shape:torch.Size([4, 3])
t_1:tensor([[1., 1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1., 1.]]) shape:torch.Size([2, 6])
2. 在新创建的维度上进行拼接 torch.stack()
import torch
# torch.stack(tensors, # 张量序列
# dim=0, # 要拼接的维度
# out=None)
t = torch.ones((3, 4))
t_stack_0 = torch.stack([t, t], dim=0)
t_stack_1 = torch.stack([t, t], dim=2)
---------------------- output ----------------------
t:tensor([[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]) shape:torch.Size([3, 4])
t_stack_0:tensor([[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]],
[[1., 1., 1., 1.],
[1., 1., 1., 1.],
[1., 1., 1., 1.]]]) shape:torch.Size([2, 3, 4])
t_stack_1:tensor([[[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.],
[1., 1.]]]) shape:torch.Size([3, 4, 2])
分割
1. 将tensor按维度进行平均切分 torch.chunk()
# torch.chunk(input, # 要切分的张量
# chunks, # 要切分的分数
# dim=0) # 要切分的维度
# 返回张量列表
# 若不能整除,最后一份小于其他张量
a = torch.ones((2, 5))
list_of_tensors = torch.chunk(a, chunks=3, dim=1)
print(a)
for idx, t in enumerate(list_of_tensors):
print("第{}个张量:{},shape is {}".format(idx + 1, t, t.shape))
---------------------- output ----------------------
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
第1个张量:tensor([[1., 1.],
[1., 1.]]),shape is torch.Size([2, 2])
第2个张量:tensor([[1., 1.],
[1., 1.]]),shape is torch.Size([2, 2])
第3个张量:tensor([[1.],
[1.]]),shape is torch.Size([2, 1])
2. 将tensor按维度进行切分,可指定切分的长度 torch.split()
# torch.split(tensor,
# split_size_or_sections, # 为int时,表示每一份的长度;为list时,按list元素切分
# dim=0)
a = torch.ones((2, 5))
print(a)
# 为 int
# list_of_tensors = torch.split(a, 3, dim=1)
# 为 list, list各项和,需等于原tensor的长度,否则报错
list_of_tensors = torch.split(a, [1, 3, 1], dim=1)
for idx, t in enumerate(list_of_tensors):
print("第{}个张量:{},shape is {}".format(idx + 1, t, t.shape))
---------------------- output ----------------------
tensor([[1., 1., 1., 1., 1.],
[1., 1., 1., 1., 1.]])
第1个张量:tensor([[1.],
[1.]]),shape is torch.Size([2, 1])
第2个张量:tensor([[1., 1., 1.],
[1., 1., 1.]]),shape is torch.Size([2, 3])
第3个张量:tensor([[1.],
[1.]]),shape is torch.Size([2, 1])
索引
1. 根据 index
# torch.index_select(input, # 要操作的tensor
# dim, # 要索引的维度
# index, # 索引,int或list
# out=None)
a = torch.randint(0, 9, size=(3, 3))
# 按行索引,0行和2行
# index_select的index必须是long(int64)类型
inx = torch.tensor([0, 2], dtype=torch.long)
t_select = torch.index_select(a, dim=0, index=inx)
print("{}\n{}".format(a, t_select))
---------------------- output ----------------------
tensor([[8, 4, 5],
[5, 3, 5],
[5, 0, 7]])
tensor([[8, 4, 5],
[5, 0, 7]])
2. 根据 mask
# torch.masked_select(input,
# mask, # 与input同形状的布尔类型张量
# out=None)
# 通常用来筛选数据,找出所有符合要求的项,返回1维张量
a = torch.randint(0, 9, size=(3, 3))
# 对a中数据进行判断,大于等于5为True
# ge means greater than or equal, gt:greater than. le lt
mask = a.ge(5)
t_select = torch.masked_select(a, mask)
print("a:{}\nmask:{}\nt_select:{}".format(a, mask, t_select))
下一篇: CIO观点:*要为云计算做的三件事