Pytorch

一、张量的基本操作

1.1 张量的维度操作

1.1.1 squeeze和unsqueeze
squeeze
torch.squeeze(input,dim=None,out=None)

除去输入张量input中数值为1的维度,并返回新的张量。如果输入张量的形状为( A × 1 × B × C × 1 × D ) ,那么输出张量的形状为( A × B × C × D ) 当通过dim参数指定维度时,维度压缩操作只会在指定的维度上进行。如果输入向量的形状为( A × 1 × B ) ,squeeze(input, 0)会保持张量的维度不变,只有在执行squeeze(input, 1)时,输入张量的形状会被压缩至( A × B ) 如果一个张量只有1个维度,那么它不会受到上述方法的影响。输出的张量与原张量共享内存,如果改变其中的一个,另一个也会改变。Note:只能除去输入张量input中数值为1的维度。如果指定的维度不是1,那么不改变形状。

note :只能除去输入张量input中数值为1的维度。如果指定的维度不是1,那么不改变形状。

#	squeeze参数:
input (Tensor) – 输入张量
dim (int, optional) – 如果给定,则只会在给定维度压缩
out (Tensor, optional) – 输出张量

示例代码:

x = torch.zeros(2, 1, 2, 1, 2)
print(x.size())			---->torch.Size([2, 1, 2, 1, 2])
y = torch.squeeze(x)
print(y.size())			---->torch.Size([2,2,2])
y = torch.squeeze(x, 0)
print(y.size())			---->torch.Size([2, 1, 2,1,2])
y = torch.squeeze(x, 1)
print(y.size())			---->torch.Size([2, 2,1,2])
unsqueeze
torch.unsqueeze(input, dim) → Tensor
#dim的范围[-a.dim()-1,a.dim()+1)    eg.a的维度=4,范围是[-5,5)

新增加的这一个维度不会改变数据本身,只是为数据新增加了一个组别,这个组别是什么由我们自己定义。

参数:
input(tensor) -输入张量
dim(int) -在给定维度上插入一维

示例代码:

a = torch.rand(4,1,28,28)
print(a.unsqueeze(0).shape)	#torch.Size([1,4,1,28,28])
b = torch.tensor([1.2,2.3])			#torch.Size([2])
print(b.unsqueeze(0))		#变成二维 #tensor([[1.2000,2.3000]])	torch.Size([2,1])
print(b.unsqueeze(-1))		#tensor([[1.2000],
									 [2.3000]])

x = torch.rand(3)
y = torch.rand(4,32,14,14)
print(x)			#tensor([0.0527, 0.8367, 0.1623])
print(x.unsqueeze(1))		#tensor([[0.0527],
									[0.8367],
									[0.1623]])
x = x.unsqueeze(1).unsqueeze(2).unsqueeze(0)	#[32]->[32,1]->[32,1,1]->[1,32,1,1]
print(x.shape)			#torch.Size([1,32,1,1])再进行扩展即可计算x+y
torch.Size([1, 3, 1, 1])
1.1.2 reshape/view

reshape和view可以调整tensor的shape,返回一个新的shape的tensor

相同点:都可以重新调整tensor的形状

不同点:view只能用于内存中连续存储的tensor。如果对tensor做了transpose,permute等操作,则tensor在内存中会不连续,此时不能调用view函数。此时先调用.contiguous()方法,使tensor的元素再内存空间中连续,然后调用.view()

示例代码:

a = torch.rand(4,1,28,28)
print(a.view(4,2,-1).shape)			#torch.Size([4, 2, 392])
print(a.reshape(4,-1).shape)		#torch.Size([4, 784])
1.1.3 expand维度扩展
torch.Tensor.expand(*sizes)		->Tensor

将现有张量沿着值为1的维度扩展到新的维度。张量可以同时沿着任意一维或多维展开。如果不想沿着一个特定的维度展开张量,可以设置它的参数值为-1。

#参数:
sizes(torch.size or int....)	--想要扩展的维度

示例代码:

x = torch.Tensor([3])
print(x.size())				#torch.Size([1])
print(x.expand(3,2))		#tensor([[3., 3.],
	·								[3., 3.],
									[3., 3.]])

a = torch.tensor([[[1,2,3],[4,5,6]]])
print(a)					#tensor([[[1, 2, 3],
									[4, 5, 6]]])
print(a.size()) 			#torch.Size([1, 2, 3])
print(a.expand(3,2,3)) #只能沿着1的维度扩展到新的维度		#tensor([[[1, 2, 3],
															   [4, 5, 6]],
    															[[1, 2, 3],
                                                                [4, 5, 6]],
        														[[1, 2, 3],
																[4, 5, 6]]])
1.1.4 transpose和permute
"""torch.transpose 
只能交换两个维度 permute可以自由交换位置
"""
import torch
x = torch.rand(5,1,2,1)
print(x.size())
c = x.transpose(1,2) # 交换1和2维度
print(x.size())
b = x.permute(0,3,1,2) #可以直接变换
print(b.size())
print("***************")
"""
For example:四个维度表示的[batch,channel,h,w] ,如果想把channel放到最后去,形成[batch,h,w,channel],那么如果使用前面的维度交换,至少要交换两次(先13交换再12交换)。而使用permute可以直接指定维度新的所处位置,更加方便。
"""
b=torch.rand(4,3,28,32)
print(b.transpose(1, 3).shape)                      #torch.Size([4, 32, 28, 3])
print(b.transpose(1, 3).transpose(1, 2).shape)      #torch.Size([4, 28, 32, 3]) print(b.permute(0,2,3,1).shape)                     #torch.Size([4, 28, 32, 3]

输出:

torch.Size([5, 1, 2, 1])
torch.Size([5, 1, 2, 1])
torch.Size([5, 1, 1, 2])

torch.Size([4, 32, 28, 3])
torch.Size([4, 28, 32, 3])
torch.Size([4, 28, 32, 3])

1.1.5 转置操作
"""
.t操作指适用于矩阵
"""
a=torch.rand(3, 4)
print(a.t().shape)

输出:torch.Size([4, 3])

1.1.6 repeat维度重复:memory copied(增加了数据)
"""
repeat会重新申请内存空间,repeat()参数表示各个维度指定的重复次数。
"""
a=torch.rand(1,32,1,1)
print(a.repeat(4,32,1,1).shape)                 #torch.Size([4, 1024, 1, 1])
print(a.repeat(4,1,1,1,1).shape)                  #torch.Size([4, 32, 1, 1])

输出:
torch.Size([4, 1024, 1, 1])
torch.Size([4, 1, 32, 1, 1])

1.1.7 张量拼接 cat & stack
"""
torch.cat(a_tuple, dim)#tuple 是一个张量或者元组,在指定维度上进行拼接
torch.stack(a_tuple, dim)#与cat不同的在于,cat只能在原有的某一维度上进行连接,stack可以创建一个新的维度,将原有维度在这个维度上进行顺序排列
#比如说,有2个4x4的张量,用cat就只能把它们变成一个8x4或4x8的张量,用stack可以变成2x4x4.
"""
x = torch.randn(2, 3)
print(x)
y = torch.cat((x, x, x), 0)#从行方向进行拼接
print(y)
y1 = torch.cat((x, x, x), 1)#从列方向进行拼接print(y1)print("***********")
"""
下面例子说明torch.cat()与torch.stack()区别。可以看出,stack()是增加新的维度来完成拼接,不改变原维度上的数据大小。cat()是在现有维度上进行数据的增加(改变了现有维度大小),不增加新的维度。
"""
x = torch.rand(2,3)
ytorch.rand(2,3)
print(x)
print(y)
print(torch.stack((x,y),1))
print(torch.stack((x,y),1).size())
print(torch.cat((x,y),1))
print(torch.cat((x,y),1).size())
1.1.8 缩小张量
"""
torch.Tensor.narrow(dimension, start, length) → Tensor
返回一个经过缩小后的张量。操作的维度由dimension指定。缩小范围是从start开始到start+length。
执行本方法的张量与返回的张量共享相同的底层内存。
参数:dimension (int) – 要进行缩小的维度
start (int) – 开始维度索引
length (int) – 缩小持续的长度
"""
x = torch.Tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(x)m=x.narrow(0, 0, 2)#从行维度缩减,从0开始,缩小2的长度
print(m)n=x.narrow(1, 1, 2)#从列维度缩减,从1开始,缩小2的长度print(n)

输出:

tensor([[1., 2., 3.],
[4., 5., 6.],
[7., 8., 9.]])
tensor([[1., 2., 3.],
[4., 5., 6.]])
tensor([[2., 3.],
[5., 6.],
[8., 9.]])

1.1.9Tensor运行设备(GPU,CPU)转换
#查看当前gpu的信息
print(torch.cuda.current_device())
print(torch.cuda.device(0))
print(torch.cuda.device_count())
print(torch.cuda.get_device_name())
print(torch.cuda.is_available())print("_____________________")
def get_device(ordinal):
# Use GPU ? 
	if ordinal < 0:
		print("Computation on CPU")
		device = torch.device('cpu')
	elif torch.cuda.is_available():        
		print("Computation on CUDA GPU device {}".format(ordinal))        
		device = torch.device('cuda:{}'.format(ordinal))    
	else:        
		print("/!\\ CUDA was requested but is not available! Computation will go on CPU. /!\\")        
		device = torch.device('cpu')    
		return device
		"""
更改get_device()的参数即可,
0表示用GPU(由于本机只有一块gpu,只能为0时,才调用GPU), -1表示CPU .
"""
device = get_device(0)
print(device)
x = torch.randn(5,6)
y= torch.randn(6,5)
x,y = x.to(device), y.to(device) #将数据转到GPU上xy = torch.mm(x,y)print(xy)
"""
或者直接指定device的值
"""x = torch.randn(2,3)
y = torch.randn(3,2)
x,y = x.to(device='cuda'), y.to(device='cuda') #将数据转到GPU上
xy = torch.mm(x,y)print(xy)
x,y = x.to(device='cpu'), y.to(device='cpu') #将数据转到CPU上xy = torch.mm(x,y)print(xy)
1.1.10 pytorch的tensor与numpy的NDArray转换
"""
pytorch的numpy()函数:tensor-->NDArray
pytorch的from_numpy()函数:NDArray-->tensor
"""
import numpy as np
x = torch.rand(2,3)
print(x)
ndarray = x.numpy() #x本身就是tensor,直接调用numpy()函数
print(ndarray)
print('___________________')
ndarray1 = np.random.randn(2,3)
print(ndarray1)
x1 = torch.from_numpy(ndarray1) #要使用torch.from_numpy()print(x1)
1.1.11 张量的创建与运算

pytorch中,张量是最基础的运算单位,与numpy的NDArray类似,张量表示的是一个多维矩阵。不同的是,pytorch中的tensor可以运行在GPU上,基于numpy的计算只能再CPU上。

"""
		Tensor常用的基本数据类型:
		32位浮点型:torch.FloatTensor.	Tensor的默认类型
		64位浮点型:torch.DoubleTensor
		64位整型:torch.LongTensor
		32位整型:torch.IntTensor
		16位整型:torch.ShortTensor
		此外,tensor还可以是byte或chart类型
"""
x = torch.tensor([3.145640])
print(x.float())		#tensor([3.1456])
print(x.double())		#tensor([3.1456], dtype=torch.float64)
print(x.long())			#tensor([3])
print(x.int())			#tensor([3], dtype=torch.int32)
print(x.short())		#tensor([3], dtype=torch.int16)
x=x.short()			#更改数据类型。x.long(),x.int(),x.double(),x.float
print(x)				#tensor([3], dtype=torch.int16)
"""
tensor初始化:
1. rand():生成一个[0,1]简单的张量,例如2行3列的【0,1】的随机数tensor
2. randn():初始化一个均值为0,方差为1的随机数tensor
3. ones():初始化一个全为1的tensor
4. zeros():初始化一个全为0的tensor
5. eye():初始化一个主对角线为1,其余都为0的tensor(只能是二维矩阵)
6. full(input,x):创建指定数值的张量,input是张量shape,x是填充数值
7. arange():创建指定数值区间的张量
8. linspace():创建等分-数列(等距)张量
9. randint(begin,end,n):从给定的范围 [begin,end) 内生成n个随机整数以上都可加_like(a),表示生成size和a一样的tensor
10. normal():正太分布张量, 参数:(均值,标准差,张量尺寸)
查看张量的大小:x.shape等同于x.size()
查看张量的维度:x.dim()
查看张量的元素个数:x.numel()
"""
x = torch.rand(2,3)
print(x)					#tensor([[0.1791, 0.7192, 0.7621],
									[0.8878, 0.5164, 0.2992]])
print(x.shape)				#torch.Size([2, 3])
print(x.size())				#torch.Size([2, 3])
x1 = torch.randn(2,3)
print(x1)					#tensor([[ 0.1528, 1.2768, 0.3342],
									[-0.3932, -1.1190, -0.8035]])
x2 = torch.ones(2,3)
print(x2)					#tensor([[1., 1., 1.],
									[1., 1., 1.]])
x3 = torch.zeros(2,3)
print(x3)					#tensor([[0., 0., 0.],
									[0., 0., 0.]])
x4 = torch.eye(2,2)	
print(x4)					#tensor([[1., 0.],
									[0., 1.]])
x5 = torch.full((3,3),2)#矩阵尺寸3*3,填充数字为2
print(x5)					#tensor([[2, 2, 2],
									[2, 2, 2],
									[2, 2, 2]])
x6 = torch.arange(2,10,2) #数值区间[2,10),间隔2
print(x6)					#tensor([2, 4, 6, 8])
x7 = torch.linspace(2,10,6) #数值区间[2,10),创建元素个数6
print(x7)					#tensor([ 2.0000, 3.6000, 5.2000, 6.8000, 8.4000, 10.0000])
x8 = torch.normal(0,1,size=(4,))
print(x8)					#tensor([-0.2591, -0.3908, 2.2048, 1.4832])
x9 = torch.ones_like(x1)
print(x9)					#tensor([[1., 1., 1.],
									[1., 1., 1.]])
print(x9.numel())			#6
"""
tensor基本运算:
NOTE: torch.max(x,dim)等同于x.max(dim)
max():沿着行或列取最大值,参数dim=0表示沿着列,dim=1沿着行,返回value和idx.       
      idx是取出的值在的每行或每列的位置 
min():沿着行或列取最小值,参数dim=0表示沿着列,dim=1沿着行,返回value和idx
sum():沿着行或列求和 基本四则运算:+-*/ ,两个tensor必须大小一致,对应位置计算
add():加和,add_(),以_为结尾的会改变调用值本身
mm():矩阵乘法
"""
x = torch.randn(2,3)
print(x)
max_value, max_idx = torch.max(x,dim=0)
print(max_value,max_idx)

min_value,min_idx=torch.min(x,dim=1)
print(min_value,min_idx)
print("________________")
print(torch.sum(x,dim=0))
print(x.sum(dim=0))
print("________________")
y = torch.randn(2,3)
print(y)
print(x.add(y))#仅仅x+y,但不会改变x的值
print(x)
print(x.add_(y))#执行x+y,结果保存到x
print(x)
print("________________")
z = torch.randn(3,2)
xy = torch.mm(x,z)
print(xy)
print(xy.shape)
1.1.12 索引与切片
a=torch.rand(4,3,28,28) #生成四维数据
print(a[0].shape)               #torch.Size([3, 28, 28])
print(a[0,0].shape)             #torch.Size([28, 28])
print(a[0,0,2,4])               #tensor(0.7309)
print(a[:2,:1].shape)           #torch.Size([2, 1, 28, 28])  等价于a[:2,:1,:,:].shape
print(a[:,:,::2,::2].shape)     #torch.Size([4, 3, 14, 14])
print("________________")
"""
使用掩码索引masked_select,根据mask取值
"""
#select by mask
x=torch.randn(3,4)
print(x)
mask=x.ge(0.5)                  #greater equal大于等于
print(mask)
y = torch.masked_select(x, mask)    
print(y)

-----------------此学习笔记根据公众号“人工智能前沿讲习”中“他山之石”整理编辑而成-------------------------

---------------------------------------未经同意,禁止转发----------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嗌三嗮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值