问题描述
我正在尝试测试 PyTorch 的层归一化功能。
但我不知道为什么 b[0]
和 result 在这里有不同的值
我做错了吗?
import numpy as np
import torch
import torch.nn as nn
a = torch.randn(1,5)
m = nn.Layernorm(a.size()[1:],elementwise_affine= False)
b = m(a)
结果:
input: a[0] = tensor([-1.3549,0.3857,0.1110,-0.8456,0.1486])
output: b[0] = tensor([-1.5561,1.0386,0.6291,-0.7967,0.6851])
mean = torch.mean(a[0])
var = torch.var(a[0])
result = (a[0]-mean)/(torch.sqrt(var+1e-5))
结果:
result = tensor([-1.3918,0.9289,0.5627,-0.7126,0.6128])
而且,对于 n*2
归一化,pytorch 层范数的结果总是 [1.0,-1.0]
(或 [-1.0,1.0]
)。我不明白为什么。如果您有任何提示,请告诉我
a = torch.randn(1,2)
m = nn.Layernorm(a.size()[1:],elementwise_affine= False)
b = m(a)
结果:
b = tensor([-1.0000,1.0000])
解决方法
计算方差使用 torch.var(a[0],unbiased=False)
。然后你会得到同样的结果。默认情况下,pytorch 计算方差的无偏估计。
对于您的第一个问题,正如@Theodor 所说,您需要在计算方差时使用 unbiased=False
unbiased。
仅当您想探索更多时:由于您的输入大小为 5,方差的无偏估计将是有偏估计的 5/4 = 1.25
倍。因为无偏估计在分母中使用 N-1
而不是 N
。因此,您生成的每个 result
值都是 sqrt(4/5) = 0.8944
值的 b[0]
倍。
关于您的第二个问题:
而且,对于 n*2 归一化,pytorch 层范数的结果总是 [1.0,-1.0]
这是合理的。假设只有两个元素是 a
和 b
。因此,均值将为 (a+b)/2
,方差为 ((a-b)^2)/4
。因此,归一化结果将是 [((a-b)/2) / (sqrt(variance)) ((b-a)/2) / (sqrt(variance))]
,它本质上是 [1,-1]
或 [-1,1]
,具体取决于 a > b
或 a < b
。