pytorch常用线性代数操作
numpy中数据类型的转换
类似于ndarray.astype(np.float32)
import numpy as np
a = np.array([1,2,3,4,5,6,7,8,9],dtype='float32');
c = c.astype(np.float32)
tensor和numpy,list转换
## ndarray ---> tensor
tensor = torch.from_numpy(ndarray)
## tensor ---> ndarray
ndarray = tensor.numpy()
## numpy ---> list
list = ndarray.tolist()
## list --> tensor
x = list([[1,2], [3,4]])
y = torch.tensor(x) # torch.tensor
pytorch创建随机矩阵
random_mat1 = torch.rand(1,2,3) #torch.Size([1, 2, 3])
print(random_mat1)
# 正态分布的随机矩阵
random_mat2 = torch.randn(1,2,3)
print(random_mat2)
# 创建3*4的int类型的矩阵,矩阵中的元素范围在[1,100]
random_mat3=torch.randint(1,100,(3,4))
print(random_mat3)
'''
tensor([[[0.8587, 0.1558, 0.1336],
[0.5678, 0.1590, 0.4319]]])
tensor([[[-0.0806, 0.1978, 0.2190],
[-0.1154, 1.0449, -1.4108]]])
tensor([[96, 77, 51, 52],
[32, 73, 56, 18],
[47, 21, 51, 70]])
'''
pytorch中对维度的操作
tensor.cat() 和tensor.stack()
tensor.cat() 指定维度进行合并,tensor.stack()在合并时候创建一个新的维度
x = torch.randn(1, 2, 3, 4)
y = torch.cat([x, x],dim=-1)
print(y.shape) #[1,2,3,8]
z = torch.stack([x,x])
print(z.shape) #[2,1,2,3,4]
tensor.repeat()和tensor.expend()
tensor.squeeze()和tensor.unsqueeze()
unsqueeze()就是增加一个维度
a=torch.rand(2,2,3)
print(a)
print(a.unsqueeze(1).shape)
print(a.unsqueeze(-1).shape)
'''
tensor([[[0.8325, 0.8406, 0.6417],
[0.3599, 0.7227, 0.2923]],
[[0.4084, 0.5286, 0.0736],
[0.4206, 0.5559, 0.5645]]])
torch.Size([2, 1, 2, 3])
torch.Size([2, 2, 3, 1])
'''
squeeze()就是将一个维度进行压缩,只有维度为 1 的那一维才能去掉
a=torch.rand(1,2,3)
a = a.unsqueeze(1).unsqueeze(-1)
print(a.shape)
a = a.squeeze(0).squeeze(0).squeeze(0)
print(a.shape)
'''
torch.Size([1, 1, 2, 3, 1])
torch.Size([2, 3, 1])
'''
第三次squeeze时,因为此时的维度不1,所以实际上没有压缩,所以维度没变
pytorch的一些基础操作
- tensor.ceil()
- tensor.round()
- tensor.floor()
- tensor.trunc()
a = torch.tensor([1.12,2.47,5.72,6.55,7.87])
print(a.ceil()) # 上取整
print(a.round()) # 四舍五入
print(a.floor()) # 下取整
print(a.trunc()) # 只保留整数
#out:
#tensor([2., 3., 6., 7., 8.])
#tensor([1., 2., 6., 7., 8.])
#tensor([1., 2., 5., 6., 7.])
#tensor([1., 2., 5., 6., 7.])
- torch.clamp(input, min, max, out=None)
对tensor中的元素进行操作,大于max的替换为max,小于min的替换为min
a=torch.randint(1,10,(3,4))
print(a)
b = torch.clamp(a, min=3,max=5)
print(b)
'''
tensor([[3, 7, 8, 6],
[6, 1, 6, 9],
[8, 4, 7, 5]])
tensor([[3, 5, 5, 5],
[5, 3, 5, 5],
[5, 4, 5, 5]])
'''
- torch.abs(input, out=None) 求绝对值
- torch.sqrt(input, out=None) 开方
- torch.exp(input, out=None) e指数,注意只支持浮点型
- torch.log(input, out=None) 以e为底
pytorch中的索引
参考:pytorch中的索引
# 譬如:4张图片,每张三个通道,每个通道28行28列的像素
a = torch.rand(4, 3, 28, 28)
# 在第一个维度上取后0和1,等同于取第一、第二张图片
print(a[:2].shape)
# 在第一个维度上取0和1,在第二个维度上取0,
# 等同于取第一、第二张图片中的第一个通道
print(a[:2, :1, :, :].shape)
# 在第一个维度上取0和1,在第二个维度上取1,2,
# 等同于取第一、第二张图片中的第二个通道与第三个通道
print(a[:2, 1:, :, :].shape)
# 在第一个维度上取0和1,在第二个维度上取1,2,
# 等同于取第一、第二张图片中的第二个通道与第三个通道
print(a[:2, -2:, :, :].shape)
# 使用step隔行采样
# 在第一、第二维度取所有元素,在第三、第四维度隔行采样
# 等同于所有图片所有通道的行列每个一行或者一列采样
# 注意:下面的代码不包括28
print(a[:, :, 0:28:2, 0:28:2].shape)
print(a[:, :, ::2, ::2].shape) # 等同于上面语句
'''
torch.Size([2, 3, 28, 28])
torch.Size([2, 1, 28, 28])
torch.Size([2, 2, 28, 28])
torch.Size([2, 2, 28, 28])
torch.Size([4, 3, 14, 14])
torch.Size([4, 3, 14, 14])
'''
使用...
索引任意多的维度
a = torch.rand(4, 3, 28, 28)
# 等与a torch.Size([4, 3, 28, 28])
print(a[...].shape)
print(a[:,:,:,:].shape)
# 第一张图片的所有维度 torch.Size([3, 28, 28])
print(a[0, ...].shape)
print(a[0,:,:,:].shape)
# 所有图片第二通道的所有维度 torch.Size([4, 28, 28])
print(a[:, 1, ...].shape)
print(a[:,1,:,:].shape)
# 所有图像所有通道所有行的第一、第二列 torch.Size([4, 3, 28, 2])
print(a[..., :2].shape)
print(a[:,:,:,:2].shape)
index_select(dim,index)
在PyTorch中,我们还可以使用index_select
函数指定index来对张量进行索引,index的类型必须为Tensor。第一个参数表示你对哪个维度进行操作;第二个参数是index(必须是tensor类型)
a = torch.rand(4, 3, 28, 28)
# 选择第一张和第三张图 #torch.Size([2, 3, 28, 28])
indices = torch.tensor([0, 1])
print(a.index_select(0, indices).shape)
# 选择R通道和B通道 #torch.Size([4, 2, 28, 28])
indices = torch.tensor([0, 2])
print(a.index_select(1, indices).shape)
# 选择图像的0~8行
indices = torch.arange(8) #torch.Size([4, 3, 8, 28])
print(a.index_select(2, indices).shape)
# 选择图像第二列,两次 #torch.Size([4, 3, 28, 2])
indices = torch.tensor([1,1])
torch.masked_select()
使用掩码来筛选出符合条件的元素,但是筛选出的元素会被拉成一维的
x = torch.randn(2,3)
print(x)
mask = x.ge(0.3)#大于等于0.5的元素
print(mask)
z = torch.masked_select(x,mask)
print(z)
'''
tensor([[-0.4030, 0.0113, -0.5428],
[ 0.7808, 1.5398, 0.3370]])
tensor([[False, False, False],
[ True, True, True]])
tensor([0.7808, 1.5398, 0.3370])
'''
或者直接使用bool索引
a = torch.randint(0,10,(3,4))
print(a)
print(a[a>5])
'''
tensor([[9, 0, 0, 0],
[9, 3, 2, 2],
[0, 5, 9, 6]])
tensor([9, 9, 9, 6])
'''
用torch.take()函数进行索引
先将张量数据打平为一个dim=1的张量数据(依次排序下来成为一个数据列),然后按照索引进行取数据
a=torch.tensor([[1,2,3],[4,5,6]])
print(a)
print(a.shape)
idx = torch.tensor([1,2,5])
print(torch.take(a,idx))
'''
tensor([[1, 2, 3],
[4, 5, 6]])
torch.Size([2, 3])
tensor([2, 3, 6])
'''
F.interpolate()
这个函数常被用来做上采样或者下采样,科学合理地改变数组的尺寸大小,尽量保持数据完整。
参考:F.interpolate()