【问题标题】:How to convert a list of different-sized tensors to a single tensor?如何将不同大小的张量列表转换为单个张量?
【发布时间】:2020-07-15 03:01:30
【问题描述】:

我想将不同大小的张量列表转换为单个张量。

我试过torch.stack,但它显示错误。

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-237-76c3ff6f157f> in <module>
----> 1 torch.stack(t)

RuntimeError: invalid argument 0: Sizes of tensors must match except in dimension 0. Got 5 and 6 in dimension 1 at C:\w\1\s\tmp_conda_3.7_105232\conda\conda-bld\pytorch_1579085620499\work\aten\src\TH/generic/THTensor.cpp:612

我的张量列表:

[tensor([-0.1873, -0.6180, -0.3918, -0.5849, -0.3607]),
 tensor([-0.6873, -0.3918, -0.5849, -0.9768, -0.7590, -0.6707]),
 tensor([-0.6686, -0.7022, -0.7436, -0.8231, -0.6348, -0.4040, -0.6074, -0.6921])]

我也以不同的方式尝试过这个,而不是张量,我使用了这些单独张量的列表,并尝试从中创建一个张量。这也显示了一个错误。

list: [[-0.18729999661445618, -0.6179999709129333, -0.3917999863624573, -0.5849000215530396, -0.36070001125335693], [-0.6873000264167786, -0.3917999863624573, -0.5849000215530396, -0.9768000245094299, -0.7590000033378601, -0.6707000136375427], [-0.6686000227928162, -0.7021999955177307, -0.7436000108718872, -0.8230999708175659, -0.6348000168800354, -0.40400001406669617, -0.6074000000953674, -0.6920999884605408]]

错误:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-245-489aea87f307> in <module>
----> 1 torch.FloatTensor(t)

ValueError: expected sequence of length 5 at dim 1 (got 6)

显然,它说,如果我没记错的话,它期望列表的长度相同。

有人可以帮忙吗?

【问题讨论】:

    标签: python pytorch tensor


    【解决方案1】:

    我同意@helloswift123,你不能堆叠不同长度的张量。

    此外,@helloswift123 的答案仅在元素总数可被您想要的形状整除时才有效。在这种情况下,元素的总数是19,并且在任何情况下,它都不能被重新塑造成有用的东西,因为它是一个素数。

    torch.cat() 建议,

    data = [torch.tensor([-0.1873, -0.6180, -0.3918, -0.5849, -0.3607]),
                    torch.tensor([-0.6873, -0.3918, -0.5849, -0.9768, -0.7590, -0.6707]),
                    torch.tensor([-0.6686, -0.7022, -0.7436, -0.8231, -0.6348, -0.4040, -0.6074, -0.6921])]
    dataTensor = torch.cat(data)
    dataTensor.numel()
    

    输出:

    tensor([-0.1873, -0.6180, -0.3918, -0.5849, -0.3607, -0.6873, -0.3918, -0.5849,
            -0.9768, -0.7590, -0.6707, -0.6686, -0.7022, -0.7436, -0.8231, -0.6348,
            -0.4040, -0.6074, -0.6921])
    19 
    

    可能的解决方案:

    这也不是一个完美的解决方案,但可能会解决这个问题。

    # Have a list of tensors (which can be of different lengths) 
    data = [torch.tensor([-0.1873, -0.6180, -0.3918, -0.5849, -0.3607]),
            torch.tensor([-0.6873, -0.3918, -0.5849, -0.9768, -0.7590, -0.6707]),
            torch.tensor([-0.6686, -0.7022, -0.7436, -0.8231, -0.6348, -0.4040, -0.6074, -0.6921])]
    
    # Determine maximum length
    max_len = max([x.squeeze().numel() for x in data])
    
    # pad all tensors to have same length
    data = [torch.nn.functional.pad(x, pad=(0, max_len - x.numel()), mode='constant', value=0) for x in data]
    
    # stack them
    data = torch.stack(data)
    
    print(data)
    print(data.shape)
    

    输出:

    tensor([[-0.1873, -0.6180, -0.3918, -0.5849, -0.3607,  0.0000,  0.0000,  0.0000],
            [-0.6873, -0.3918, -0.5849, -0.9768, -0.7590, -0.6707,  0.0000,  0.0000],
            [-0.6686, -0.7022, -0.7436, -0.8231, -0.6348, -0.4040, -0.6074, -0.6921]])
    torch.Size([3, 8])
    

    这会将零添加到任何元素较少的张量的末尾,在这种情况下,您可以像往常一样使用torch.stack()

    我希望这会有所帮助!

    【讨论】:

      【解决方案2】:

      试试:

      >>>data = [tensor([-0.1873, -0.6180, -0.3918, -0.5849, -0.3607]),tensor([-0.6873, -0.3918, 
      -0.5849, -0.9768, -0.7590, -0.6707]),tensor([-0.6686, -0.7022, -0.7436, -0.8231, 
      -0.6348, -0.4040, -0.6074, -0.6921])]
      
      >>>dataTensor = torch.cat(data).reshape(x,y)  #x*y = data.numel()
      
      >>>print(type(dataTensor))
      <class 'torch.Tensor'>
      

      torch.stack 连接一系列具有相同大小的张量。

      torch.cat 连接张量序列。

      来自torch.cat的文档:

      在给定维度中连接给定的 seq 张量序列。所有张量必须具有相同的形状(连接维度除外)或为空。

      【讨论】:

      • 谢谢。这也很有帮助。
      【解决方案3】:

      另一种可能的解决方案,使用torch.nn.utils.rnn.pad_sequence

      # data = [tensor([1, 2, 3]), 
      #         tensor([4, 5])]
      data = pad_sequence(data, batch_first=True)
      # data = tensor([[1, 2, 3],
      #                [4, 5, 0]])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-10
        • 2020-08-05
        • 1970-01-01
        • 2019-07-29
        • 2016-10-15
        • 2019-10-07
        • 2021-01-14
        相关资源
        最近更新 更多