Numpy.transpose 与 tensor.permute

1. Numpy.transpose

如图,通过Print(three.shape), 可知原始的 original three :
在这里插入图片描述

1.1 原始numpy 中每个维度上意义

three.shape = (2, 4, 3)

第一个数,代表矩阵个数 Num_matrix = 2,
第二个数,代表单个矩阵中的行数 row = 4;
第三个数,代表单个矩阵中的列数 col = 3;
那么当使用numpy.transpose(x1,x2,x3),x1, x2, x3 没有使用正常顺序排列时,则代表各个逆序的位置上的数值改变, 也就是说该位置上元素代表的意义没有改变,只不过的数值上发生改变。

1.2 transpose 中每个维度上意义

而当出现 transpose 时, 代表的是需要进行置换的维度;

Numpy.transpose(2,1,0):
使用以上transpose之后,想要改变两部分的内容,即矩阵的个数 和 单个矩阵中的列数
改变后矩阵的个数 = 原始 Original three 中列数
改变后 单个矩阵中的列数 = 原始original three 中矩阵的个数。

明白的说,
1:原来的 original three(2,4,3)代表的是有2 个 4 * 3 的矩阵,
2:通过numpy.transpose (2, 1, 0) 想要将原始的第0个位置上的数 和第2个位置上的数互换. 将变成 three(3,4,0);
3:变换之后,得到 3 个 4 * 2 的矩阵;

有人可能会问,由2个4 * 3 的矩阵,变换成 3个4 * 2 的矩阵时候,在组成第一新的矩阵时, 为什么不直接取原始第一个矩阵中的连续两列,来形成一个新矩阵。
答: 由2个4*3 的矩阵,变换成 3个4 * 2 的矩阵时, 单个矩阵的行数是没有变的,又想从两个矩阵变成三个矩阵, 而原始单个矩阵中只有3列,如果每次取2列,取三次是不够的,所以从每个矩阵取一列。

同理,numpy.transpose(1, 0 , 2) 想要达到的目的是:将原始总矩阵的数目 和 原始单个矩阵的行数, 这两个数值进行互换。

在这里插入图片描述

2. tensor.permute

将tensor的维度换位。

参数: - dims (int …*) - 换位顺序

2.1 实例

>>> x = torch.randn(2, 3, 5) 
>>> x.size() 
torch.Size([2, 3, 5]) 
>>> x.permute(2, 0, 1).size() 
torch.Size([5, 2, 3])

2.2 transpose 与permute 的区别

permute相当于可以同时操作于tensor的若干维度,transpose只能同时作用于tensor的两个维度;

  1. torch.transpose(Tensor, a,b):transpose只能操作2D矩阵的转置,有两种调用方式;

另:连续使用transpose也可实现permute的效果:


>>torch.randn(2,3,4,5).transpose(3,0).transpose(2,1).transpose(3,2).shape
torch.Size([5, 4, 2, 3])
>>torch.randn(2,3,4,5).transpose(1,0).transpose(2,1).transpose(3,1).shape
torch.Size([3, 5, 2, 4])

  1. Tensor.permute(a,b,c,d, …):permute函数可以对任意高维矩阵进行转置,但没有 torch.permute() 这个调用方式, 只能 Tensor.permute():
>>> torch.randn(2,3,4,5).permute(3,2,0,1).shape
torch.Size([5, 4, 2, 3])

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
from skimage.segmentation import slic, mark_boundaries import torchvision.transforms as transforms import numpy as np from PIL import Image import matplotlib.pyplot as plt import torch.nn as nn import torch # 定义超像素池化层 class SuperpixelPooling(nn.Module): def init(self, n_segments): super(SuperpixelPooling, self).init() self.n_segments = n_segments def forward(self, x): # 使用 SLIC 算法生成超像素标记图 segments = slic(x.numpy().transpose(1, 2, 0), n_segments=self.n_segments, compactness=10) # 将超像素标记图转换为张量 segments_tensor = torch.from_numpy(segments).unsqueeze(0).unsqueeze(0) # 将张量 x 与超像素标记图张量 segments_tensor 进行逐元素相乘 pooled = x * segments_tensor.float() # 在超像素维度上进行最大池化 pooled = nn.AdaptiveMaxPool2d((self.n_segments, 1))(pooled) # 压缩超像素维度 pooled = pooled.squeeze(3) # 返回池化后的特征图 return pooled # 加载图像 image = Image.open('3.jpg') # 转换为 PyTorch 张量 transform = transforms.ToTensor() img_tensor = transform(image).unsqueeze(0) # 将 PyTorch 张量转换为 Numpy 数组 img_np = img_tensor.numpy().transpose(0, 2, 3, 1)[0] # 使用 SLIC 算法生成超像素标记图 segments = slic(img_np, n_segments=60, compactness=10) # 将超像素标记图转换为张量 segments_tensor = torch.from_numpy(segments).unsqueeze(0).float() # 将超像素索引映射可视化 plt.imshow(segments, cmap='gray') plt.show() # 将 Numpy 数组转换为 PIL 图像 segment_img = Image.fromarray((mark_boundaries(img_np, segments) * 255).astype(np.uint8)) # 保存超像素索引映射可视化 segment_img.save('segment_map.jpg') # 使用超像素池化层进行池化 pooling_layer = SuperpixelPooling(n_segments=60) pooled_tensor = pooling_layer(img_tensor) # 将超像素池化后的特征图可视化 plt.imshow(pooled_tensor.squeeze().numpy().transpose(1, 0), cmap='gray') plt.show() ,上述代码出现问题:segments = slic(x.numpy().transpose(1, 2, 0), n_segments=self.n_segments, compactness=10) ValueError: axes don't match array,如何修改
06-09
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值