PyTorch基本使用-张量的形状操作

文章目录


学习目标:掌握reshape()、squeze()、unsqueeze()、transpose()、permute()、view()、contiguous()等函数使用

  • reshape() 函数

    reshape 函数可以在保证张量数据不变的前提下改版数据维度,将其转换成指定的形状。

    data = torch.tensor([[1,2,3],[4,5,6]])
    print('data ---> ',data)
    # 使用 shape属性或者size方法都可以获取张量的形状
    print(data.shape,data.shape[0],data.shape[1])
    print(data.size(),data.size(0),data.size(1))
    # 使用 reshape 修改张量的形状
    new_data = data.reshape(1,6)
    print(new_data.shape)
    

    输出结果:

    data --->  tensor([[1, 2, 3],
            [4, 5, 6]])
    torch.Size([2, 3]) 2 3
    torch.Size([2, 3]) 2 3
    torch.Size([1, 6])
    
  • squeeze()和unsqueeze()函数

    squeeze 函数删除形状为 1 的维度(降维),unsqueeze 函数添加形状为1的维度(升维)。

    data1 = torch.tensor([1,2,3,4,5,6])
    print('普通的1维数组 ---> ',data1.shape,data1)
    data2 = data1.unsqueeze(dim=0)
    print('在0维上拓展维度',data2.shape,data2) # 1*6
    data3 = data1.unsqueeze(dim=1)
    print('在1维上拓展维度',data3.shape,data3) # 6*1
    data4 = data1.unsqueeze(dim=-1)
    print('在-1维上拓展维度',data4.shape,data4) # 6*1
    data5 = data4.squeeze()
    print('压缩维度',data5.shape,data5) # 1*6
    

    输出结果:

    普通的1维数组 --->  torch.Size([6]) tensor([1, 2, 3, 4, 5, 6])
    在0维上拓展维度 torch.Size([1, 6]) tensor([[1, 2, 3, 4, 5, 6]])
    在1维上拓展维度 torch.Size([6, 1]) tensor([[1],
            [2],
            [3],
            [4],
            [5],
            [6]])
    在-1维上拓展维度 torch.Size([6, 1]) tensor([[1],
            [2],
            [3],
            [4],
            [5],
            [6]])
    压缩维度 torch.Size([6]) tensor([1, 2, 3, 4, 5, 6])
    
  • transpose()和permute()函数

    transpose 函数可以实现交换张量形状的指定维度, 例如: 一个张量的形状为 (2, 3, 4) 可以通过 transpose 函数把 3 和 4
    进行交换, 将张量的形状变为 (2, 4, 3) 。 permute 函数可以一次交换更多的维度。

    data = torch.tensor(np.random.randint(0,10,[3,4,5]))
    print('data.shape ---> ',data.shape)
    # 1. 交换1和2维度
    data2 = torch.transpose(data,1,2)
    print('data2.shape ---> ',data2.shape)
    # 2. 将形状换成 4,5,3 需要多次
    data3 = torch.transpose(data,0,1)
    data4 = torch.transpose(data3,1,2)
    print('data4.shape ---> ',data4.shape)
    # 使用permute将形状换成 4,5,3
    # 方法-1
    data5 = torch.permute(data,[1,2,0])
    print('data5.shape ---> ',data5.shape)
    # 方法-2
    data6 = data.permute([1,2,0])
    print('data6.shape ---> ',data6.shape)
    

    输出结果:

    data.shape --->  torch.Size([3, 4, 5])
    data2.shape --->  torch.Size([3, 5, 4])
    data4.shape --->  torch.Size([4, 5, 3])
    data5.shape --->  torch.Size([4, 5, 3])
    data6.shape --->  torch.Size([4, 5, 3])
    
  • view()和contiguous()函数

    view 函数也可以用于修改张量的形状,只能用于存储在整块内存中的张量。在 PyTorch 中,有些张量是由不同的数据
    块组成的,它们并没有存储在整块的内存中,view 函数无法对这样的张量进行变形处理,例如: 一个张量经过了
    transpose 或者 permute 函数的处理之后,就无法使用 view 函数进行形状操作。

    # 1. 一个张量经过了 transpose 或者 permute 函数的处理之后,就无法使用view 函数进行形状操作
    # 若要使用view函数, 需要使用contiguous() 变成连续以后再使用view函数
    # 2. 判断张量是否使用整块内存
    data1 = torch.tensor([[1,2,3],[4,5,6]])
    print('data1 ---> ',data1.shape,data1)
    # 3. 判断是否使用整块内存
    print(data1.is_contiguous())
    data2 = data1.view(3,2)
    print('data2 ---> ',data2.shape,data2)
    # 4. 判断是否使用整块内存
    print(data2.is_contiguous())
    # 5. 使用 transpose 函数修改形状
    data3 = torch.transpose(data1,0,1)
    print('data3 ---> ',data3.shape,data3)
    # 6. 判断是否使用整块内存
    print(data3.is_contiguous())
    # 7. 需要先使用 contiguous 函数转换为整块内存的张量,再使用 view 函数
    data4 = data3.contiguous().view(2,3)
    print('data4 ---> ',data4.shape,data4)
    # 8. 判断是否使用整块内存
    print(data4.is_contiguous())
    

    输出结果:

    data1 --->  torch.Size([2, 3]) tensor([[1, 2, 3],
            [4, 5, 6]])
    True
    data2 --->  torch.Size([3, 2]) tensor([[1, 2],
            [3, 4],
            [5, 6]])
    True
    data3 --->  torch.Size([3, 2]) tensor([[1, 4],
            [2, 5],
            [3, 6]])
    False
    data4 --->  torch.Size([2, 3]) tensor([[1, 4, 2],
            [5, 3, 6]])
    True
    
### PyTorch 中修改量化模型中张量形状的方法 在 PyTorch 中,修改量化模型中的张量形状可以通过多种方式进行处理。以下是详细的说明: #### 1. **理解量化模型** 量化模型是指通过对浮点数权重和激活值进行近似表示来减少内存占用并加速推理的过程[^4]。然而,在某些情况下可能需要调整张量形状以适应特定的需求。 #### 2. **使用 `view` 和 `reshape` 方法** 对于未量化的张量,可以使用 `.view()` 或 `.reshape()` 来改变形状而不复制数据。这些方法同样适用于量化张量,但需要注意的是,它们不会影响量化属性(如比例因子和零点偏移)[^2]。 ```python import torch # 创建一个量化张量 q_tensor = torch.quantize_per_tensor(torch.randn(4, 4), scale=0.1, zero_point=10, dtype=torch.quint8) # 使用 view 改变形状 reshaped_q_tensor_view = q_tensor.view(-1) # 将张量展平为一维 # 使用 reshape 改变形状 reshaped_q_tensor_reshape = q_tensor.reshape(2, 8) # 调整为 (2, 8) 的形状 ``` 上述代码展示了如何通过 `.view()` 和 `.reshape()` 对量化张量进行形状变换。 #### 3. **利用 `permute` 进行维度重排** 如果目标是对张量的维度顺序进行调整,则可以使用 `.permute()` 函数。此函数允许重新排列多维数组的轴次序,这对于高维张量尤其有用。 ```python # 假设有一个三维量化张量 q_tensor_3d = torch.rand(2, 3, 4).to(torch.float32) q_tensor_quantized = torch.quantize_per_tensor(q_tensor_3d, scale=0.1, zero_point=10, dtype=torch.quint8) # 使用 permute 更改维度顺序 permuted_q_tensor = q_tensor_quantized.permute(2, 0, 1) # 新的形状为 (4, 2, 3) ``` #### 4. **注意剪枝的影响** 当涉及已剪枝的模块时,需特别小心。因为剪枝会更改部分参数的实际存储形式,可能导致形状不一致的情况发生。此时可考虑调用 `torch.nn.utils.prune.remove` 移除剪枝标记后再执行形状转换操作[^3]。 ```python from torch import nn import torch.nn.utils.prune as prune module = nn.Linear(4, 2) prune.random_unstructured(module, name="weight", amount=0.5) # 如果需要恢复原始形状以便进一步操作 prune.remove(module, 'weight') ``` #### 5. **确保兼容性** 为了使量化后的模型能够正常运行,建议始终验证所使用的 ONNX 导出工具链支持的操作集版本是否满足要求。例如,只有 opset 版本大于等于 10 才能正确导出带有量化的模型。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值