pytorch 学习之 Tensor 基础

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))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万俟淋曦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值