pytorch 中的层归一化

问题描述

我正在尝试测试 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]

这是合理的。假设只有两个元素是 ab。因此,均值将为 (a+b)/2,方差为 ((a-b)^2)/4。因此,归一化结果将是 [((a-b)/2) / (sqrt(variance)) ((b-a)/2) / (sqrt(variance))],它本质上是 [1,-1][-1,1],具体取决于 a > ba < b