data.norm() < 1000 在 PyTorch 中做什么?

What does data.norm() < 1000 do in PyTorch?

我正在学习 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.]).

就是张量的L2范数(a.k.a欧氏范数)。下面是一个可复制的插图:

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.

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

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

y.data.norm() 

相当于

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

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


下面的代码块创建了一个形状为 (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 returns 一个张量,其 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() Returns给定张量的矩阵范数或向量范数。默认情况下,它 returns Frobenius 范数 又名 L2-Norm 是使用公式
[=43= 计算的]

在我们的示例中,因为 y 中的每个元素都是 2,y.data.norm() returns 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>)