当前位置: 首页 > 知识库问答 >
问题:

PyTorch中的“视图”方法是如何工作的?

农飞星
2023-03-14

我对下面代码片段中的方法view()感到困惑。

class Net(nn.Module):
    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool  = nn.MaxPool2d(2,2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.fc1   = nn.Linear(16*5*5, 120)
        self.fc2   = nn.Linear(120, 84)
        self.fc3   = nn.Linear(84, 10)

    def forward(self, x):
        x = self.pool(F.relu(self.conv1(x)))
        x = self.pool(F.relu(self.conv2(x)))
        x = x.view(-1, 16*5*5)
        x = F.relu(self.fc1(x))
        x = F.relu(self.fc2(x))
        x = self.fc3(x)
        return x

net = Net()

我的困惑在于以下几行。

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

什么是张量。view()函数的作用是什么?我在很多地方见过它的用法,但我不明白它是如何解释它的参数的。

如果我将负值作为参数赋给view()函数,会发生什么情况?例如,如果我调用,tensor\u变量会发生什么。视图(1,1,-1)

有人能用一些例子解释一下view()函数的主要原理吗?

共有3个答案

邵诚
2023-03-14

view()通过将张量的元素“拉伸”或“挤压”到指定的形状来重塑张量:

首先让我们看看引擎盖下的张量是什么:

陶高峻
2023-03-14

让我们做一些例子,从简单到更难。

>

  • view方法返回一个张量,该张量的数据与自张量的数据相同(这意味着返回的张量具有相同数量的元素),但形状不同。例如:

    a = torch.arange(1, 17)  # a's shape is (16,)
    
    a.view(4, 4) # output below
      1   2   3   4
      5   6   7   8
      9  10  11  12
     13  14  15  16
    [torch.FloatTensor of size 4x4]
    
    a.view(2, 2, 4) # output below
    (0 ,.,.) = 
    1   2   3   4
    5   6   7   8
    
    (1 ,.,.) = 
     9  10  11  12
    13  14  15  16
    [torch.FloatTensor of size 2x2x4]
    

    假设-1不是参数之一,当将它们相乘时,结果必须等于张量中的元素数。如果您这样做:a.view(3,3),它将引发运行时错误,因为形状(3 x 3)对于包含16个元素的输入无效。换句话说:3x3不等于16,但等于9。

    可以使用-1作为传递给函数的参数之一,但只能使用一次。所发生的是,该方法将为您计算如何填充该维度。例如a.view(2,-1,4)等价于a.view(2,2,4)

    请注意,返回的张量共享相同的数据。如果在“视图”中进行更改,则更改的是原始张量数据:

    b = a.view(4, 4)
    b[0, 2] = 2
    a[2] == 3.0
    False
    

    现在,对于更复杂的用例。留档说每个新的视图维度必须是原始维度的子空间,或者只有满足以下类似连续条件的d, d1,..., dk,对于所有i=0,..., k-1,步幅[i]=步幅[i 1]x大小[i 1]。否则,需要在查看张量之前调用contiguous()。例如:

    a = torch.rand(5, 4, 3, 2) # size (5, 4, 3, 2)
    a_t = a.permute(0, 2, 3, 1) # size (5, 3, 2, 4)
    
    # The commented line below will raise a RuntimeError, because one dimension
    # spans across two contiguous subspaces
    # a_t.view(-1, 4)
    
    # instead do:
    a_t.contiguous().view(-1, 4)
    
    # To see why the first one does not work and the second does,
    # compare a.stride() and a_t.stride()
    a.stride() # (24, 6, 2, 1)
    a_t.stride() # (24, 2, 1, 6)
    

    请注意,对于a_t,stride[0]!=步幅[1]x大小[1]自24!=2 x 3

  • 金和雅
    2023-03-14

    视图函数旨在重塑张量。

    假设你有一个张量

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

    a是一个张量,它包含从1到16的16个元素。如果你想重塑这个张量,使它成为一个4 x 4张量,那么你可以使用

    a = a.view(4, 4)
    

    现在a将是4x4张量。请注意,重塑后,图元的总数需要保持不变。将张量a重塑为3 x 5张量将不合适。

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

    这可以在上面给出的神经网络代码中看到。在x=self行之后。pool(F.relu(self.conv2(x)))在forward函数中,您将有一个16深度的特征映射。您必须将其展平,以将其提供给完全连接的层。所以你告诉pytorch重塑你得到的张量,使其具有特定的列数,并让它自己决定行数。

    在numpy和pytorch之间绘制一个相似的视图,view类似于numpy的重塑功能

     类似资料:
    • 问题内容: 我对以下代码片段中的方法感到困惑。 我的困惑是关于以下几行。 函数有什么作用?我已经在很多地方看到了它的用法,但是我不明白它是如何解释其参数的。 如果我给函数赋负值作为参数会怎样?例如,如果我打电话给我怎么办? 谁能举例说明功能的主要原理? 问题答案: 视图功能旨在重塑张量。 说你有张量 是具有1到16(包括)的16个元素的张量。如果要重塑此张量以使其成为张量,则可以使用 现在将是张量

    • 我正在Scala 3中运行以下代码。x、 据我所知,它应该返回True,因为Int根据Scala文档扩展了AnyVal。 在Java中,下面的代码打印为true,这是可以理解的。

    • 问题内容: 创建视图时,我基本上是在创建一个新表,当其中一个表中的数据发生变化时,该表将自动进行处理。那是对的吗? 另外,为什么我不能在视图中使用子查询? 问题答案: 视图的工作方式 类似于表 ,但不是表。它永远不存在;它只是在引用视图名称时运行的准备好的SQL语句。IE浏览器: …相当于运行: MySQLDump将永远不会包含要插入视图中的行… 另外,为什么我不能在视图中使用子查询???? 遗憾

    • //我在main方法的最后一行获得了一个IllegalStateException。这是为什么?我能知道这对.的工作原理吗

    • 我试图在Pytorch中实现seq2seq模型,我对批处理有一些问题。例如,我有一批数据,其尺寸是 [batch_sizesequence_lengthsencoding_dimension] 其中,批次中每个示例的序列长度不同。 现在,我通过将批处理中的每个元素填充到最长序列的长度来完成编码部分。 通过这种方式,如果我向我的网络输入一个与上述形状相同的批次,我会得到以下输出: 输出,形状 隐藏状

    • 我试图在PyTorch中执行静态训练后量化。对于这个例子,我尝试用偏置量化Conv2d层: PyTorch文档明确指出,偏差不是量子化的,而是保持为浮动张量。输出的整数表示产生: 但是,浮点表示法产生: 我搜索了关于这个问题的信息,得出的结论是,用于卷积输出再量化的刻度和零点考虑了偏差,并且在GEMM操作期间,偏差被量化为int32_t,然后被添加到GEMMint32_t结果中...从上述示例中,