【问题标题】:What does data.norm() < 1000 do in PyTorch?data.norm() < 1000 在 PyTorch 中有什么作用?
【发布时间】:2018-11-18 02:12:21
【问题描述】:

我正在关注 PyTorch 教程 here。 它说

x = torch.randn(3, requires_grad=True)

y = x * 2
while y.data.norm() < 1000:
    y = y * 2

print(y)

Out:    
tensor([-590.4467,   97.6760,  921.0221])

有人能解释一下 data.norm() 在这里做什么吗? 当我将.randn 更改为.ones 时,其输出为tensor([ 1024., 1024., 1024.])

【问题讨论】:

  • 我不知道 PyTorch,但经过一番搜索,我认为 norm() 方法可能与 the mathematical norm 有关。我不知道这是否是相同的方法,但我还找到了一个带有 norm() 方法的 PyTorch 文档here

标签: python deep-learning linear-algebra pytorch tensor


【解决方案1】:

这只是张量的 L2 范数(又名欧几里得范数)。下面是一个可重现的插图:

In [15]: x = torch.randn(3, requires_grad=True)

In [16]: y = x * 2

In [17]: y.data
Out[17]: tensor([-1.2510, -0.6302,  1.2898])

In [18]: y.data.norm()
Out[18]: tensor(1.9041)

# computing the norm using elementary operations
In [19]: torch.sqrt(torch.sum(torch.pow(y, 2)))
Out[19]: tensor(1.9041)

解释:首先,它取输入张量x 中的每个元素的平方,然后将它们相加,最后取结果和的平方根。总而言之,这些操作计算所谓的 L2 or Euclidean norm

【讨论】:

  • 本质上,它试图获得一个幅度
【解决方案2】:

基于@kmario23 所说的,代码将向量的元素乘以 2,直到向量的欧几里德幅度(与原点的距离)/L2 范数至少为 1000。

以带有 (1,1,1) 的向量为例:它增加到 (512, 512, 512),其中 l2 范数约为 886。这小于 1000,因此再次乘以 2并变为 (1024, 1024, 1024)。它的震级大于 1000,所以它停止了。

【讨论】:

    【解决方案3】:
    y.data.norm() 
    

    等价于

    torch.sqrt(torch.sum(torch.pow(y, 2)))
    

    【讨论】:

    • 详细说明你的答案。
    【解决方案4】:

    让我们逐步打破它以更好地理解代码。


    下面的代码块创建了一个形状为 (1,3) 的张量 x

    x = torch.ones(3, requires_grad=True)
    print(x)
    
    >>> tensor([1., 1., 1.], requires_grad=True)
    

    下面的代码块通过将 x 的每个元素乘以 2 来创建张量 y

    y = x * 2
    print(y)
    print(y.requires_grad)
    
    >>> tensor([2., 2., 2.], grad_fn=<MulBackward0>)
    >>> True
    

    TORCH.data 返回一个 requires_grad 设置为 false 的张量

    print(y.data)
    print('Type of y: ', type(y.data))
    print('requires_grad: ', y.data.requires_grad)
    
    >>> tensor([2., 2., 2.])
    >>> Type of y:  <class 'torch.Tensor'>
    >>> requires_grad:  False
    

    TORCH.norm() 返回给定张量的矩阵范数或向量范数。默认情况下,它返回一个 Frobenius norm 又名 L2-Norm,它使用公式

    计算得出。

    在我们的示例中,由于 y 中的每个元素都是 2,因此 y.data.norm() 自 @987654322 以来返回 3.4641 @ 等于 3.4641

    print(y.data.norm())
    
    >>> tensor(3.4641)
    

    运行下面的循环,直到范数小于 1000

    while y.data.norm() < 1000:
        print('Norm value: ', y.data.norm(), 'y value: ', y.data )
        y = y * 2
    
    >>> Norm value:  tensor(6.9282) y value:  tensor([4., 4., 4.])
    >>> Norm value:  tensor(3.4641) y value:  tensor([2., 2., 2.])
    >>> Norm value:  tensor(13.8564) y value:  tensor([8., 8., 8.])
    >>> Norm value:  tensor(27.7128) y value:  tensor([16., 16., 16.])
    >>> Norm value:  tensor(55.4256) y value:  tensor([32., 32., 32.])
    >>> Norm value:  tensor(110.8512) y value:  tensor([64., 64., 64.])
    >>> Norm value:  tensor(221.7025) y value:  tensor([128., 128., 128.])
    >>> Norm value:  tensor(443.4050) y value:  tensor([256., 256., 256.])
    >>> Norm value:  tensor(886.8100) y value:  tensor([512., 512., 512.])
    >>> 
    >>> Final y value:  tensor([1024., 1024., 1024.], grad_fn=<MulBackward0>)
    

    【讨论】:

      猜你喜欢
      • 2020-11-19
      • 2017-03-30
      • 2017-08-09
      • 2020-05-20
      • 1970-01-01
      • 1970-01-01
      • 2018-12-28
      • 1970-01-01
      • 2019-06-06
      相关资源
      最近更新 更多