.view()对x张量有什么作用?负值是什么意思?

x = x.view(-1, 16 * 5 * 5)

当前回答

View()在不复制内存的情况下重塑张量,类似于numpy的重塑()。

给定一个包含16个元素的张量a:

import torch
a = torch.range(1, 16)

为了重塑这个张量,使它成为一个4 x 4张量,使用:

a = a.view(4, 4)

现在a就是一个4 x 4张量。注意,在重塑之后,元素的总数需要保持不变。将张量a重塑为3 x 5张量是不合适的。

参数-1是什么意思?

如果有任何情况,你不知道你想要多少行,但确定列的数量,那么你可以指定这个-1。(注意,你可以将其扩展到更多维度的张量。只有一个轴值可以是-1)。这是一种告诉库的方式:“给我一个张量,它有这么多列,然后你计算出实现这一点所需的适当行数”。

这可以在模型定义代码中看到。在forward函数中的x = self.pool(F.relu(self.conv2(x)))行之后,您将得到一个16深度的特征映射。你必须把它压平,让它成为完全连接的层。所以你告诉PyTorch重塑你得到的张量,让它有特定的列数,并让它自己决定行数。

其他回答

我真的很喜欢@Jadiel de Armas的例子。

我想添加一个关于.view(…)元素如何排序的小见解。

对于形状为(a,b,c)的张量,其元素的顺序为 由编号系统确定:其中第一个数字有 数字,第二个数字是b,第三个数字是c。 由.view(…)返回的新张量中元素的映射 保持原始张量的阶数。

让我们通过下面的例子来理解view:

    a=torch.range(1,16)

print(a)

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

print(a.view(-1,2))

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

print(a.view(2,-1,4))   #3d tensor

    tensor([[[ 1.,  2.,  3.,  4.],
             [ 5.,  6.,  7.,  8.]],

            [[ 9., 10., 11., 12.],
             [13., 14., 15., 16.]]])
print(a.view(2,-1,2))

    tensor([[[ 1.,  2.],
             [ 3.,  4.],
             [ 5.,  6.],
             [ 7.,  8.]],

            [[ 9., 10.],
             [11., 12.],
             [13., 14.],
             [15., 16.]]])

print(a.view(4,-1,2))

    tensor([[[ 1.,  2.],
             [ 3.,  4.]],

            [[ 5.,  6.],
             [ 7.,  8.]],

            [[ 9., 10.],
             [11., 12.]],

            [[13., 14.],
             [15., 16.]]])

-1作为参数值是计算x值的一种简单方法,前提是我们知道y和z的值,反之亦然,对于3d和2d,同样是计算x值的一种简单方法,前提是我们知道y的值,反之亦然。

我发现x.view(- 1,16 * 5 * 5)等价于x.flatten(1),其中参数1表示扁平化过程从第一个维度开始(不是扁平化'样本'维度) 如您所见,后一种用法在语义上更清楚,也更容易使用,因此我更喜欢flatten()。

参数-1是什么意思?

您可以将-1读取为动态参数数或“任何东西”。因此,在view()中只能有一个参数-1。

如果你问x.view(-1,1),这将输出张量形状[任何东西,1]取决于x中的元素数量。例如:

import torch
x = torch.tensor([1, 2, 3, 4])
print(x,x.shape)
print("...")
print(x.view(-1,1), x.view(-1,1).shape)
print(x.view(1,-1), x.view(1,-1).shape)

将输出:

tensor([1, 2, 3, 4]) torch.Size([4])
...
tensor([[1],
        [2],
        [3],
        [4]]) torch.Size([4, 1])
tensor([[1, 2, 3, 4]]) torch.Size([1, 4])

View()通过“拉伸”或“挤压”张量的元素来重新塑造你指定的形状:


view()如何工作?

首先让我们看看什么是张量:

Tensor and its underlying storage e.g. the right-hand tensor (shape (3,2)) can be computed from the left-hand one with t2 = t1.view(3,2)

在这里你可以看到PyTorch通过添加shape和stride属性将底层的连续内存块转换为类似矩阵的对象来创建一个张量:

形状表示每个维度的长度 Stride表示在到达每个维度的下一个元素之前需要在内存中执行多少步

View (dim1,dim2,…)返回相同底层信息的视图,但被重新塑造为形状为dim1 x dim2 x…(通过修改形状和stride属性)。

注意,这隐含地假设新维和旧维有相同的乘积(即旧张量和新张量有相同的体积)。


PyTorch -1

-1是PyTorch的别名,表示“在其他维度都已指定的情况下推断该维度”(即原产品与新产品的商)。这是一个来自numpy.重塑()的约定。

因此,本例中的t1.view(3,2)将等效于t1.view(3,-1)或t1.view(-1,2)。