当前位置:  开发笔记 > 编程语言 > 正文

"视图"方法在PyTorch中如何工作?

如何解决《"视图"方法在PyTorch中如何工作?》经验,为你挑选了2个好方法。

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)

tensor.view()功能有什么作用?我已经在许多地方看到了它的用法,但我无法理解它如何解释它的参数.

如果我将负值作为参数给view()函数会发生什么?例如,如果我打电话会发生什么tensor_variable.view(1, 1, -1)

任何人都可以view()通过一些例子解释功能的主要原理吗?



1> Kashyap..:

视图函数旨在重塑张量.

说你有一个张量

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

a是一个张量,有16个元素从1到16(包括).如果你想重塑这个张量使其成为一个4 x 4张量,那么你可以使用

a = a.view(4, 4)

现在a将是一个4 x 4张量.请注意,在重新整形后,元素的总数需要保持不变.重塑张a3 x 5张量是不恰当的.

参数-1是什么意思?

如果有任何情况你不知道你想要多少行,但确定列数,那么你可以用-1指定它.(请注意,您可以将其扩展到具有更多尺寸的张量.只有一个轴值可以为-1).这是告诉库的一种方式:"给我一个具有这么多列的张量,并计算实现这一点所需的适当行数".

这可以在您上面给出的神经网络代码中看到.x = self.pool(F.relu(self.conv2(x)))在前向功能中的行之后,您将拥有一个16深度的特征映射.您必须将其展平以将其提供给完全连接的图层.因此,您告诉pytorch重新构造您获得的具有特定列数的张量,并告诉它自己决定行数.

在numpy和pytorch之间绘制相似性,view类似于numpy的重塑功能.


**"视图类似于numpy的重塑"** - 为什么他们不在PyTorch中称它为"reshape"?!
@MaxB与重塑不同,"视图"返回的新张量与原始张量共享基础数据,因此它实际上是对旧张量的视图,而不是创建一个全新的张量.
@blckbird"reshape总是复制内存.查看永远不会复制内存." https://github.com/torch/cutorch/issues/98
@qihqi**"与重塑不同"**不正确.
@MaxB你有这个来源吗?我也读过齐齐说的话。
@CharlieParker将拉平张量。
@devinbost**Torch**重塑总是复制内存.**NumPy**重塑没有.

2> Jadiel de Ar..:

让我们举一些例子,从简单到更难.

    view方法返回张量与张量具有相同数据的self张量(这意味着返回的张量具有相同数量的元素),但具有不同的形状.例如:

    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),它将引发一个RuntimeError因为形状(3 x 3)对于16个元素的输入无效.换句话说:3 x 3不等于16但是9.

    您可以将其-1作为传递给函数的参数之一,但只能使用一次.所有发生的事情是该方法将为您填写关于如何填充该维​​度的数学.例如a.view(2, -1, 4)相当于a.view(2, 2, 4).[16 /(2 x 4)= 2]

    请注意,返回的张量共享相同的数据.如果您在"视图"中进行更改,则会更改原始张量的数据:

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

    现在,对于更复杂的用例.文档说每个新的视图维度必须是原始维度的子空间,或者只是跨越d,d + 1,...,d + k,它们满足以下所有i = 0的类似条件的条件. ..,k - 1,stride [i] = stride [i + 1] x size [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]!= stride [1] x size [1],因为24!= 2 x 3

推荐阅读
臭小子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有