在pytorch视图中-1是什么意思?

Aer*_*rin 4 reshape pytorch

如问题所述,-1在pytorch 中做什么view

In [2]: a = torch.arange(1, 17)

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

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

In [8]: a.view(1,-1)
Out[8]:
tensor([[  1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,  10.,
          11.,  12.,  13.,  14.,  15.,  16.]])
Run Code Online (Sandbox Code Playgroud)

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

ben*_*che 10

是的,它的行为确实类似于-1in numpy.reshape(),即将推断该尺寸的实际值,以使视图中的元素数与元素的原始数匹配。

例如:

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
Run Code Online (Sandbox Code Playgroud)

  • @CharlieParker:这将使张量变平(类似于 [`torch.flatten( Correct)`](https://pytorch.org/docs/stable/ generated/torch.flatten.html)),即返回一个张量包含所有元素的单个维度。例如,在我的答案中的命令之后运行“x.view(-1)”将返回“tensor([0., 1., 2., 3., 4., 5.])”,即一个张量单一维度,大小为 6。 (4认同)

Cha*_*ker 7

我喜欢本杰明给出的答案/sf/answers/3555572961/

是的,它的行为确实类似于 numpy.reshape() 中的 -1,即将推断该维度的实际值,以便视图中的元素数量与原始元素数量相匹配。

但我认为奇怪的情况边缘情况对你来说可能不直观(或者至少对我来说不是)是用单个 -1 ie 调用它时tensor.view(-1)我的猜测是,它的工作方式与往常完全相同,只是因为您给出一个数字来查看,所以它假设您需要一个维度。如果有的话,tensor.view(-1, Dnew)它会产生一个二维/索引的张量,但会根据张量的原始维度确保第一个维度的大小正确。假设你有(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())
Run Code Online (Sandbox Code Playgroud)

输出:

torch.Size([5])
torch.Size([1, 8])
torch.Size([8])
torch.Size([24])
Run Code Online (Sandbox Code Playgroud)

历史/背景

我觉得有一个很好的例子(在正式添加扁平化层之前,pytorch 中早期的常见情况就是这个通用代码):

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)
Run Code Online (Sandbox Code Playgroud)

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


例2

如果你想知道x.view(-1)它是什么使向量变平的。为什么?因为它必须构造一个只有 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 /sf/answers/4655057641/
"""
import torch

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

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

print(x.view(-1))

Run Code Online (Sandbox Code Playgroud)

输出

tensor([0, 1, 2, 3, 4, 5])
tensor([[0, 1],
        [2, 3],
        [4, 5]])
tensor([0, 1, 2, 3, 4, 5])
Run Code Online (Sandbox Code Playgroud)

看到原来的张量被返回了!