-1在pytorch视图中意味着什么?

What does -1 mean in pytorch view?

正如问题所说,-1在pytorch中做了什么view

>>> a = torch.arange(1, 17)
>>> a
tensor([  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
         11.,  12.,  13.,  14.,  15.,  16.])

>>> a.view(1,-1)
tensor([[  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
          11.,  12.,  13.,  14.,  15.,  16.]])

>>> a.view(-1,1)
tensor([[  1.],
        [  2.],
        [  3.],
        [  4.],
        [  5.],
        [  6.],
        [  7.],
        [  8.],
        [  9.],
        [ 10.],
        [ 11.],
        [ 12.],
        [ 13.],
        [ 14.],
        [ 15.],
        [ 16.]])

它(-1)会产生额外的维度吗? 它的行为是否与 numpy reshape -1 相同?

我想这类似于 np.reshape:

The new shape should be compatible with the original shape. If an integer, then the result will be a 1-D array of that length. One shape dimension can be -1. In this case, the value is inferred from the length of the array and remaining dimensions.

如果您有 a = torch.arange(1, 18),您可以通过多种方式查看它,例如 a.view(-1,6)a.view(-1,9)a.view(3,-1)

是的,它的行为确实像 numpy.reshape() 中的 -1,也就是说,将推断此维度的实际值,以便视图中的元素数与原始元素数相匹配。

例如:

import torch

x = torch.arange(6)

print(x.view(3, -1))      # inferred size will be 2 as 6 / 3 = 2
# tensor([[ 0.,  1.],
#         [ 2.,  3.],
#         [ 4.,  5.]])

print(x.view(-1, 6))      # inferred size will be 1 as 6 / 6 = 1
# tensor([[ 0.,  1.,  2.,  3.,  4.,  5.]])

print(x.view(1, -1, 2))   # inferred size will be 3 as 6 / (1 * 2) = 3
# tensor([[[ 0.,  1.],
#          [ 2.,  3.],
#          [ 4.,  5.]]])

# print(x.view(-1, 5))    # throw error as there's no int N so that 5 * N = 6
# RuntimeError: invalid argument 2: size '[-1 x 5]' is invalid for input with 6 elements

print(x.view(-1, -1, 3))  # throw error as only one dimension can be inferred
# RuntimeError: invalid argument 1: only one dimension can be inferred

From the PyTorch documentation:

>>> x = torch.randn(4, 4)
>>> x.size()
torch.Size([4, 4])
>>> y = x.view(16)
>>> y.size()
torch.Size([16])
>>> z = x.view(-1, 8)  # the size -1 is inferred from other dimensions
>>> z.size()
torch.Size([2, 8])

-1 推断为 2,例如,如果您有

>>> a = torch.rand(4,4)
>>> a.size()
torch.size([4,4])
>>> y = x.view(16)
>>> y.size()
torch.size([16])
>>> z = x.view(-1,8) # -1 is generally inferred as 2  i.e (2,8)
>>> z.size()
torch.size([2,8])

我喜欢本杰明给出的答案

Yes, it does behave like -1 in numpy.reshape(), i.e. the actual value for this dimension will be inferred so that the number of elements in the view matches the original number of elements.

但我认为奇怪的边缘情况可能对你来说不直观(或者至少对我来说不是)是用单个 -1 调用它时,即 tensor.view(-1)我的猜测是,它的工作方式与以往完全相同,只是因为您给出了一个数字来查看它,所以它假设您需要一个维度。 如果您有 tensor.view(-1, Dnew) 它会产生两个 dimensions/indices 的张量,但会根据张量的原始维度确保第一个维度的大小正确。假设你有 (D1, D2) 你有 Dnew=D1*D2 那么新维度将是 1.

对于带有代码的真实示例,您可以 运行:

import torch

x = torch.randn(1, 5)
x = x.view(-1)
print(x.size())

x = torch.randn(2, 4)
x = x.view(-1, 8)
print(x.size())

x = torch.randn(2, 4)
x = x.view(-1)
print(x.size())

x = torch.randn(2, 4, 3)
x = x.view(-1)
print(x.size())

输出:

torch.Size([5])
torch.Size([1, 8])
torch.Size([8])
torch.Size([24])

History/Context

我觉得一个很好的例子(common case early on in pytorch before the flatten layer was official added是这个常用代码):

class Flatten(nn.Module):
    def forward(self, input):
        # input.size(0) usually denotes the batch size so we want to keep that
        return input.view(input.size(0), -1)

顺序。在这个视图中,x.view(-1) 是一个奇怪的扁平层,但缺少挤压(即添加维度 1)。添加或删除此压缩对于代码实际 运行.

通常很重要

示例 2

如果您想知道 x.view(-1) 是做什么的,它会将向量展平。为什么?因为它必须构建一个只有一维的新视图并推断该维度——所以它会展平它。此外,此操作似乎避免了 .resize() 带来的非常讨厌的错误,因为似乎尊重了元素的顺序。仅供参考,pytorch 现在有这个操作来展平:https://pytorch.org/docs/stable/generated/torch.flatten.html

#%%
"""
Summary: view(-1, ...) keeps the remaining dimensions as give and infers the -1 location such that it respects the
original view of the tensor. If it's only .view(-1) then it only has 1 dimension given all the previous ones so it ends
up flattening the tensor.

ref: my answer 
"""
import torch

x = torch.arange(6)
print(x)

x = x.reshape(3, 2)
print(x)

print(x.view(-1))

输出

tensor([0, 1, 2, 3, 4, 5])
tensor([[0, 1],
        [2, 3],
        [4, 5]])
tensor([0, 1, 2, 3, 4, 5])

看到原来的张量返回了!

-1 是 PyTorch 的别名,表示“在其他所有维度都已指定的情况下推断此维度”(即原始乘积与新乘积的商)。这是取自 numpy.reshape().

的约定

因此示例中的 t.view(1,17) 等同于 t.view(1,-1)t.view(-1,17).