【问题标题】:Convert pytorch tensor to numpy, and reshape将 pytorch 张量转换为 numpy,并重塑
【发布时间】:2020-02-09 21:31:03
【问题描述】:

我有一个 pytorch 张量 [100, 1, 32, 32] 对应于 100 张图像、1 个通道、高度 32 和宽度 32 的批量大小。我想将此张量重塑为具有尺寸 [32*10, 32*10],这样图像表示为 10x10 网格,前 10 个图像位于第 1 行,依此类推。如何做到这一点?

【问题讨论】:

    标签: python numpy tensorflow pytorch


    【解决方案1】:

    更新

    更高效、更短的版本。为了避免使用for循环,我们可以先置换a

    import torch
    a = torch.arange(9*2*2).view(9,1,2,2)
    b = a.permute([0,1,3,2])
    torch.cat(torch.split(b, 3),-1).view(6,6).t()
    # tensor([[ 0,  1,  4,  5,  8,  9],
    #         [ 2,  3,  6,  7, 10, 11],
    #         [12, 13, 16, 17, 20, 21],
    #         [14, 15, 18, 19, 22, 23],
    #         [24, 25, 28, 29, 32, 33],
    #         [26, 27, 30, 31, 34, 35]])
    

    原答案

    您可以使用torch.splittorch.cat 来实现它。

    import torch
    a = torch.arange(9*2*2).view(9,1,2,2)
    

    假设我们有 a 张量,它是原始张量的迷​​你版。而且看起来,

    tensor([[[[ 0,  1],
              [ 2,  3]]],
            [[[ 4,  5],
              [ 6,  7]]],
            [[[ 8,  9],
              [10, 11]]],
            [[[12, 13],
              [14, 15]]],
            [[[16, 17],
              [18, 19]]],
            [[[20, 21],
              [22, 23]]],
            [[[24, 25],
              [26, 27]]],
            [[[28, 29],
              [30, 31]]],
            [[[32, 33],
              [34, 35]]]])
    

    每个 2x2 子矩阵可以看作一个图像。您要做的是将前三个图像堆叠到一行,接下来的三个图像到第二行,最后三个图像到第三行。由于 2x2 子矩阵,“行”实际上有两个暗淡。

    three_parts = torch.split(a,3)
    
    torch.cat(torch.split(three_parts[0],1), dim=-1)
    
    #tensor([[[[ 0,  1,  4,  5,  8,  9],
    #          [ 2,  3,  6,  7, 10, 11]]]])
    

    这里我们只取第一部分。

    torch.cat([torch.cat(torch.split(three_parts[i],1),-1) for i in range(3)],0).view(6,6)
    # tensor([[ 0,  1,  4,  5,  8,  9],
    #         [ 2,  3,  6,  7, 10, 11],
    #         [12, 13, 16, 17, 20, 21],
    #         [14, 15, 18, 19, 22, 23],
    #         [24, 25, 28, 29, 32, 33],
    #         [26, 27, 30, 31, 34, 35]])
    

    【讨论】:

      【解决方案2】:

      你可以使用make_grid():

      x = torchvision.utils.make_grid(x, nrow=10, padding=0)
      

      【讨论】:

      • 有没有办法用 reshape() 做到这一点?
      • 我不确定,make_grid() 是否符合您的预期?我认为您可能还需要将它与 permute() 结合使用 - 从您的问题来看,您似乎有一个带有 reshape() 的 numpy 解决方案?
      • 有没有办法通过重塑和置换来做到这一点?
      • 做什么? make_grid() 是否符合您的预期?
      【解决方案3】:

      我没有完全理解您的问题,但试图解决一些问题。

      你有一个形状为[100, 1, 32, 32] 的张量,它代表了 100 个形状为[1, 32, 32] 的图像,其中num_channels = 1width = 32height = 32

      首先,由于图像只有一个通道,我们可以压缩通道维度。

      # image_tensor is of shape [100, 1, 32, 32]
      image_tensor = image_tensor.squeeze(1) # [100, 32, 32]
      

      我们可以按照您的描述将生成的张量组织成 10 行,每行 10 张图像。

      image_tensor = image_tensor.reshape(10, 10, 32, 32)
      

      现在,将生成的张量转换为形状为 [32*10, 32*10] 的张量听起来有些不对劲。但是,让我们做错事,看看结果如何。

      image_tensor = image_tensor.permute(2, 0, 3, 1) # [32, 10, 32, 10]
      

      置换后,我们得到一个形状为[width, num_rows, height, num_img_in_a_row] 的张量。最后我们可以reshape得到想要的张量。

      image_tensor = image_tensor.reshape(32*10, 32*10)
      

      所以,最终张量的形状为[width * num_rows, height * num_img_in_a_row]。你真的想要这个吗?我不确定如何解释生成的张量!!

      【讨论】:

      • 嗨 Wasi,我不认为最终的 image_tensor 是 @novice 想要的。请检查我的更新答案。
      猜你喜欢
      • 2018-10-27
      • 2020-06-27
      • 1970-01-01
      • 2019-06-13
      • 2021-02-24
      • 2022-10-17
      • 2019-04-27
      • 2017-09-05
      • 2019-07-29
      相关资源
      最近更新 更多