PyTorch【2】PyTorch的张量

本文详细介绍了PyTorch中的张量概念,包括张量的定义、生成方法,如torch.tensor()和torch.Tensor()。讨论了张量的数据类型、转换以及与numpy的互转。此外,还涵盖了张量的形状操作、计算和比较,如张量的求梯度、基本运算、统计计算等。通过实例解析,帮助读者深入理解PyTorch张量的使用。
摘要由CSDN通过智能技术生成

一.张量的定义

在 PyTorch 中,张量可以是一个标量、一个向量、一个矩阵及更高维的数组,可以用阶来表示张量的维数。

  • 标量:0 阶的数值,一个单独的数,如 135。
  • 向量:1 阶的数值,一列或一行数组,如 [1, 3, 5]。
  • 矩阵:2 阶的数值,二维数组 ,如 [[1, 2, 3], [4, 5, 6]]。
  • 张量:超过 2 阶的数值,高维数组,如 [[[xxx]]]。

在 PyTorch0.4 版本之前,Tensor 不能计算梯度,所以在需要深度学习网络中,需要计算梯度的 Tensor 都需要使用 Variable(Tensor)进行封装,然后构建计算图。在 0.4 之后,合并了 Tensor 类和 Variable类,可以直接计算 Tensor 的梯度,因此 Variable() 逐渐消失。

二.张量的生成

PyTorch 生成张量有多种方式,有一半主要使用以下 5 种。

1.torch.tensor()函数

tensor(data [,dtype [,device [,requires_grad]]])

  • data:数值或布尔类型的 Python 列表或元组。
  • dtype:数据类型,默认为 torch.int64 或 torch.float32。
  • device:tensor 被分配的设备,默认为 cpu。
  • requires_grad:是否需要计算每个元素梯度,默认为 False,注意 data 或 dtype 必须是浮点数才可以修改为 True。

(1).创建

# 一般张量
A = torch.tensor([[1,2,],[3,4]])

# 可求梯度的张量
B = torch.tensor([[1,2,],[3,4]],dtype=torch.float32,requires_grad=True)

'''
tensor([[1, 2],
        [3, 4]])
tensor([[1., 2.],
        [3., 4.]], requires_grad=True)
'''

(2).属性

A = torch.tensor([[1,2,],[3,4]])

A.data			# 张量的数据
A.dtype			# 张量的 dtype
A.device		# 张量的所在设备
A.requires_grad	# 张量是否可以求导
A.shape			# 张量的维度:torch.size([2,2])
A.size()		# 张量的形状:torch.size([2,2])
A.numel()		# 张量的元素数量:4
A.item()		# 张量的 python 数值,注意必须是 0 维张量,即标量才行

(3).张量求梯度

x = torch.tensor([[1.0,2],[3,4]],requires_grad=True)
y = torch.tensor([[2.3,4],[30,14]],requires_grad=True)
z = torch.sum(x**2+2*y**2+1)
# 固定 torch.sum 形式,因为 z.backward()求导时z必须时一个浮点类型标量,sum()的作用就是标量化
# 逐元素求导
# 如果写成 torch.max 或 median,每个元素位置的数将会是所有元素对应的 max、median 值或 0.0
    
print(x.requires_grad)				# x是否可以求导
print(y.requires_grad)
print(z.requires_grad)
z.backward()						# z对包含的张量求导(本例为x和y)
print(x.grad)						# z对x求导后的结果
print(y.grad)						# z对y求导后的结果
'''
tensor([[2., 4.],
		[6., 8.]])
tensor([[  9.2000,  16.0000],
		[120.0000,  56.0000]])
'''

2.torch.Tensor()类

(1).普通创建

A = torch.Tensor([[1,2,],[3,4]])		# 根据已有的数据创建张量,dtype 为 torch.float32
A = torch.Tensor(2,3)					# 创建特定形状的张量,数值是随机的
B = torch.ones_like(A)					# 创建与 A 维度相同、性质相似的全 1 张量
B = torch.zeros_like(A)					# 创建与 A 维度相同、性质相似的全 0 张量
B = torch.rand_like(A)					# 创建与指定张量A维度、性质相似的随机张量

(2).随机生成张量

torch.manual_seed(123)					# 随机数的种子,保证生成的随机数是可重复出现的
A = torch.arange(n)						# 0到n-1的一维序列
A = torch.arange(2,n)					# 2到n-1的一维序列
A = torch.arange(start,end,step)	    # 一维序列
A = torch.randperm(n)					# 0到n-1的一维整数序列,元素位置随机打乱
A = torch.linspace(start,end,num)		# 生成固定等间隔的num个数,包含start和end
A = torch.logspace(start,end,num)		# 生成以对数为间隔的num个数,包含start和end
A = torch.normal(mean=num,std=num)		# mean和std都可以多个,对应每个随机数分布的均值和标准差的二维数据
A = torch.eye(3,4)					    # 生成3行4列的单位矩阵(注意只能生成二维的单位矩阵)
# 以下为多维数据,括号里几个参数就是几维数据
A = torch.rand(3,4)						# 生成3行4列的均匀分布,区间[0,1)
A = torch.ones(3,4)						# 生成3行4列的全1
A = torch.zeros(3,4)					# 生成3行4列的全0
A = torch.empty(3,4)					# 生成3行4列的全无穷小矩阵
A = torch.full((3,4),fill_value=num)	# 生成3行4列的全num矩阵

三.张量的数据类型

数据类型dtypeCPU tensorGPU tensor
16位浮点型torch.float16 torch.halftorch.HalfTensortorch.cuda.HalfTensor
32位浮点型(默认)torch.float32 torch.floattorch.FloatTensortorch.cuda.FloatTensor
64位浮点型torch.float64 torch.doubletorch.DoubleTensortorch.cuda.DoubleTensor
8位无符号整型torch.uint8torch.ByteTensortorch.cuda.ByteTensor
8位有符号整型torch.int8torch.CharTensortorch.cuda.CharTensor
16位有符号整型torch.int16 torch.shorttorch.ShortTensortorch.cuda.ShortTensor
32位有符号整型torch.int32 torch.inttorch.IntTensortorch.cuda.IntTensor
64位有符号整型(默认)torch.int64 torch.longtorch.LongTensortorch.cuda.LongTensor

1.获取张量的默认数据类型

torch.get_default_dtype()

2.修改张量的默认数据类型

torch.set_default_tensor_type(torch.half)

3.张量数据类型转换

A = torch.tensor([[1,2,],[3,4]])
B = A.to(torch.float32)				# 括号中必须是dtype格式
C = A.type(torch.DoubleTensor)		# 括号中必须是CPU tensor格式或GPU tensor格式

4.torch和numpy转换

(1).numpy 转 torch

np_a = np.ones((2,3))
torch_a = torch.as_tensor(np_a)
torch_a = torch.from_numpy(np_a)

(2).torch 转 numpy

np_a = torch_a.numpy()

四.张量的操作

1.改变形状

A = torch.arange(n).reshape(m,n)
B = torch.reshape(input=A,shape=(m,n))
A.resize_(m,n)
A.resize_as_(B)
A = A.view(A.shape[0],-1)	# 通常用在卷积层与全连接层中间
A = A.view(A.size(0),-1)

2.改变维度

# 维度提升
A = torch.arange(12).reshape(2,6)
B = torch.unsqueeze(A,dim=0)			# 在0维前面插入一个维度
B = A.unsqueeze(dim=0)
B.shape	#[1,2,6]

# 维度减小
C = torch.squeeze(B)					# 移除所有维度为1的维度
C = torch.squeeze(B,dim=0)				# 移除指定维度为1的维度
C = B.squeeze()
C = B.squeeze(dim=0)

# 维度提升并改变内容(广播机制)
A = torch.arange(l)
B = A.expand(m, n, k)
C = A.expand_as(B)
# 注意 expand 的参数
	# 当 A 标量时,expand 中的 m,n,k 可以是任意非负整数
   	# 当 A 一维数组时,expand 中的 m,n 可以是任意非负整数,k必须和 A 的长度相等,或者直接写成-1
   	# 当 A 多维数组时,expand 中的 后几个数值形状必须和 A 的 shape 相同

2.获取元素

# 切片方式
A[:,:,]
# 索引设置
torch.where(condition,x,y)				# 满足条件时返回x对应索引的位置值,否则返回y对应的位置的值(并不是返回x或y)
torch.tril(A,diagonal=0)				# 返回张量的下三角部分的内容,上三角用0填充,diagonal为对角线的偏移位置,正数向上偏移,负数向下
torch.triu(A,diagonal=0)				# 返回张量的上三角部分的内容,下三角用0填充
torch.diag(A,diagonal=0)				# 返回对角线的元素
torch.diag(torch.tensor([1,2,3]))		# 提供对角线的元素生成矩阵

3.拼接和拆分

#使用cat拼接
A = torch.tensor([[0,1,2],[3,4,5]])
B = torch.tensor([[0,2,4],[6,8,10]])
torch.cat((A,B),dim=0)					# 在0维拼接
torch.cat((A,B),dim=1)					# 在1维拼接

# 使用stack方式会多出来一个维度,所以可以dim=2
torch.stack((A,B),dim=0)
torch.stack((A,B),dim=1)
torch.stack((A,B),dim=2)

#使用chunk分割,沿着dim维度切分,不能被整数切割时,最后一个块最小,但不能为0
B1,B2 = torch.chunk(A,2,dim=0)
B1,B2 = torch.chunk(A,2,dim=1)
B1,B2,B3 = torch.chunk(A,3,dim=0)
B1,B2,B3 = torch.chunk(A,3,dim=1)

#使用split分割,沿着dim维度切分,[指定每个块的大小]
B1,B2 = torch.chunk(A,[1,2],dim=0)
B1,B2 = torch.chunk(A,[1,2],dim=1)
B1,B2,B3 = torch.chunk(A,[1,2,3],dim=0)
B1,B2,B3 = torch.chunk(A,[1,2,3],dim=1)

五.张量的计算

1.比较大小

torch.allclose(A,B,rtol=1e-5,atol=1e-8,equal_nan=False)		
	# 比较两个元素是否接近;公式:|A-B|≤atol+rtolx|B|;
	# equal_nan=False时两个NaN不接近,为True时两个NaN接近
torch.eq(A,B)						# 逐元素比较是否相等(返回一堆bool)
torch.equal(A,B)					# 比较两个张量的形状和元素是否都相同
torch.ge(A,B)						# 逐元素比较 ≥
torch.gt(A,B)						# 逐元素比较 >
torch.le(A,B)						# 逐元素比较 ≤
torch.lt(A,B)						# 逐元素比较 <
torch.ne(A,B)						# 逐元素比较 !=
torch.isnan(A)						# 逐元素判断是否为缺失值

2.基本运算

(1) 逐元素运算

A*B
A/B
A+B
A-B
A//B
A**2
A.pow(2)
torch.pow(A,2)
torch.exp(A)	# A各元素的e次方
torch.log(A)
torch.sqrt(A)
torch.rsqrt(A)  # 平方根倒数
torch.clamp_max(A,4)				# A中超过4的值变为4
torch.clamp_min(A,4)				# A中小于4的值变为4
torch.clamp(A,2.5,4)				# A中小于2.5的值变为2.5,大于4的值变为4

(2) 矩阵之间的运算

torch.t(A)							# A的转置
A.matmul(B)							# 矩阵相乘
torch.matmul(A,B)					# 矩阵相乘
torch.inverse(A)					# 求A的逆矩阵

3.统计相关的计算

torch.max(tensor=,dim=)	A.max(dim=)	# A中dim维度的最大值
torch.max(A)						# A中的最大值
torch.min(A)						# A中的最小值
torch.argmax(A)						# A中的最大值的位置
torch.argmin(A)						# A中的最小值的位置
torch.sort(A,descending=Fasle,dim=-1)# 对一维张量排序或高维指定维度进行排序,默认升序
torch.topk(A,K,dim)					# 获取张量中前K个最大的数及其位置 
torch.kthvalue(A,K,dim)				# 获取张量中第K个最小的数及其位置 

torch.mean(A,dim)					# 张量指定维度的均值		(不加dim时是所有元素的)
torch.sum(A,dim)					# 张量指定维度的求和		(不加dim时是所有元素的)
torch.cumsum(A,dim)					# 张量指定维度的计算累加和
torch.median(A,dim)					# 张量指定维度的计算中位数(不加dim时是所有元素的)
torch.cumprod(A,dim)				# 张量指定维度的计算累乘积
torch.std(A,dim)	    			# 张量指定维度的标准差	(不加dim时是所有元素的)
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值