将pytorch张量转换为numpy并重塑形状

时间:2019-10-12 17:35:12

标签: python numpy tensorflow pytorch

我有一个pytorch张量import SwiftUI import Combine struct ContentView: View { @ObservedObject private var restrictInput = RestrictInput(5) var body: some View { Form { TextField("input text", text: $restrictInput.text) } } } // https://stackoverflow.com/questions/57922766/how-to-use-combine-on-a-swiftui-view class RestrictInput: ObservableObject { @Published var text = "" private var canc: AnyCancellable! init (_ maxLength: Int) { canc = $text .debounce(for: 0.5, scheduler: DispatchQueue.main) .map { String($0.prefix(maxLength)) } .assign(to: \.text, on: self) } deinit { canc.cancel() } } 对应于100张图像的批处理大小,1个通道,高度32和宽度32。我想将此张量重塑为尺寸[32 * 10、32 * 10],例如图像以10x10网格表示,前10个图像位于第1行,依此类推。如何实现呢?

3 个答案:

答案 0 :(得分:2)

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

  

您有一个形状为[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]的张量。最后,我们可以重塑形状以获得所需的张量。

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

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

答案 1 :(得分:2)

更新

更高效,更短的版本。为了避免使用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 :(得分:1)

您可以使用make_grid()

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