【colab pytorch】张量操作

时间:2022-07-23
本文章向大家介绍【colab pytorch】张量操作,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

1、在pytorch中,有以下9种张量类型

2、查看张量的基本信息

tensor=torch.randn(3,4,5)
print(tensor.size())
print(tensor.type())
print(tensor.dim())

torch.Size([3, 4, 5])

torch.FloatTensor

3

3、命名张量

张量命名是一个非常有用的方法,这样可以方便地使用维度的名字来做索引或其他操作,大大提高了可读性、易用性,防止出错。

# 在PyTorch 1.3之前,需要使用注释
# Tensor[N, C, H, W]
images = torch.randn(32, 3, 56, 56)
images.sum(dim=1)
images.select(dim=1, index=0)
# PyTorch 1.3之后
NCHW = [‘N’, ‘C’, ‘H’, ‘W’]
images = torch.randn(32, 3, 56, 56, names=NCHW)
images.sum('C').size()#按通道相加

torch.Size([32, 32, 32])

不过需要注意:1.4版本中该特性正在处于测试阶段,因此就不要随便的使用了。

#选择第0个通道
images.select('C',index=0).size()

torch.Size([32, 32, 32])

# 也可以这么设置
tensor = torch.rand(3,4,1,2,names=('C', 'N', 'H', 'W'))
# 使用align_to可以对维度方便地排序
tensor = tensor.align_to('N', 'C', 'H', 'W')

4、数据类型转换

# 设置默认类型,pytorch中的FloatTensor远远快于DoubleTensor
torch.set_default_tensor_type(torch.FloatTensor)

# 类型转换
tensor = tensor.cuda()
tensor = tensor.cpu()
tensor = tensor.float()
tensor = tensor.long()

5、tensor和numpy.ndarray转换

除了CharTensor,其他所有CPU上的张量都支持转换为numpy格式然后再转换回来。

ndarray = tensor.cpu().numpy()
tensor = torch.from_numpy(ndarray).float()
tensor = torch.from_numpy(ndarray.copy()).float() # If ndarray has negative stride.

6、tensor和PIL.Image转换

pytorch中的张量默认采用[N, C, H, W]的顺序,并且数据范围在[0,1],需要进行转置和规范化

PIL.Image转换为tensor

from PIL import Image
import numpy as np
image=r'/content/drive/My Drive/colab notebooks/image/test.jpg'
tensor=torch.from_numpy(np.asarray(Image.open(image))).permute(2,0,1).float()/255.0
tensor.size()

torch.Size([3, 300, 200])

另一种方式:

import torchvision
tensor=torchvision.transforms.functional.to_tensor(PIL.Image.open(path))
tensor.size()

torch.Size([3, 300, 200])

tensor转换为PIL.Image

img=Image.fromarray(torch.clamp(tensor*255,min=0,max=255).byte().permute(1,2,0).cpu().numpy())
print(type(img))

<class 'PIL.Image.Image'>

另一种方式:

image = torchvision.transforms.functional.to_pil_image(tensor)

7、np.ndarray和PIL.Image进行转换

np.ndarray转换为PIL.Image

image = PIL.Image.fromarray(ndarray.astype(np.uint8))

PIL.Image转换为np.ndarray

ndarray = np.asarray(PIL.Image.open(path))

8、从只包含一个元素的tensor中取出值

value = torch.rand(1)
print(value)
print(value.item())

tensor([0.2959])

0.2958560585975647

9、改变张量的形状

# 在将卷积层输入全连接层的情况下通常需要对张量做形变处理,
# 相比torch.view,torch.reshape可以自动处理输入张量不连续的情况。
tensor = torch.rand(2,3,4)
shape = (6, 4)
tensor = torch.reshape(tensor, shape)

10、打乱顺序

tensor = tensor[torch.randperm(tensor.size(0))]  # 打乱第一个维度

11、水平翻转

# pytorch不支持tensor[::-1]这样的负步长操作,水平翻转可以通过张量索引实现
# 假设张量的维度为[N, C, H, W].
tensor = tensor[:,:,:,torch.arange(tensor.size(3) - 1, -1, -1).long()]

12、复制张量

# Operation                 |  New/Shared memory | Still in computation graph |
tensor.clone()            # |        New         |          Yes               |
tensor.detach()           # |      Shared        |          No                |
tensor.detach.clone()()   # |        New         |          No                |

13、张量拼接

'''
注意torch.cat和torch.stack的区别在于torch.cat沿着给定的维度拼接,
而torch.stack会新增一维。例如当参数是3个10x5的张量,torch.cat的结果是30x5的张量,
而torch.stack的结果是3x10x5的张量。
'''
tensor = torch.cat(list_of_tensors, dim=0)
tensor = torch.stack(list_of_tensors, dim=0)
t1=torch.randn(10,5)
t2=torch.randn(10,5)
t3=torch.randn(10,5)
s1=torch.cat([t1,t2,t3],dim=0)
s2=torch.stack([t1,t2,t3],dim=0)
print(s1.size())
print(s2.size())

torch.Size([30, 5])

torch.Size([3, 10, 5])

14、将整数标签转换为ont-hot码

tensor=torch.tensor([0,2,1,3])
N=tensor.size(0)
num_classes=4
one_hot=torch.zeros(N,num_classes).long()
one_hot.scatter_(dim=1, index=torch.unsqueeze(tensor, dim=1), src=torch.ones(N, num_classes).long())

tensor([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])

15、得到非零元素

torch.nonzero(tensor)               # index of non-zero elements
torch.nonzero(tensor==0)            # index of zero elements
torch.nonzero(tensor).size(0)       # number of non-zero elements
torch.nonzero(tensor == 0).size(0)  # number of zero elements

16、判断两个张量相等

torch.allclose(tensor1, tensor2)  # float tensor
torch.equal(tensor1, tensor2)     # int tensor

17、张量扩展

# Expand tensor of shape 64*512 to shape 64*512*7*7.
tensor = torch.rand(64,512)
torch.reshape(tensor, (64, 512, 1, 1)).expand(64, 512, 7, 7).size()

torch.Size([64, 512, 7, 7])

18、矩阵乘法

# Matrix multiplcation: (m*n) * (n*p) * -> (m*p).
result = torch.mm(tensor1, tensor2)

# Batch matrix multiplication: (b*m*n) * (b*n*p) -> (b*m*p)
result = torch.bmm(tensor1, tensor2)

# Element-wise multiplication.
result = tensor1 * tensor2

19、计算两组数据之间的两两欧式距离

利用广播机制

dist = torch.sqrt(torch.sum((X1[:,None,:] - X2) ** 2, dim=2))