首页 > 解决方案 > 为什么 numpy 和 pytorch 在均值和方差归一化后给出不同的结果?

问题描述

我正在研究一个矩阵必须逐行归一化的问题。还需要在将每一行分成小批量后应用归一化。该代码似乎适用于 Numpy,但在 Pytorch 上失败(这是培训所必需的)。Pytorch 和 Numpy 的结果似乎不同。任何帮助将不胜感激。

示例代码:

import numpy as np
import torch


def normalize(x, bsize, eps=1e-6):
    nc = x.shape[1]
    if nc % bsize != 0:
        raise Exception(f'Number of columns must be a multiple of bsize')
    x = x.reshape(-1, bsize)
    m = x.mean(1).reshape(-1, 1)
    s = x.std(1).reshape(-1, 1)
    n = (x - m) / (eps + s)
    n = n.reshape(-1, nc)
    return n

# numpy
a = np.float32(np.random.randn(8, 8))
n1 = normalize(a, 4)
# torch
b = torch.tensor(a)
n2 = normalize(b, 4)
n2 = n2.numpy()

print(abs(n1-n2).max())

标签: numpypytorchnormalization

解决方案


在第一个示例中,您normalize使用a, a进行调用numpy.ndarray,而在第二个示例中,您normalize使用b, a 进行调用torch.Tensor

根据文档页面torch.std,默认使用贝塞尔校正来衡量标准偏差。因此,和之间的默认行为numpy.ndarray.stdtorch.Tensor.std不同的。

如果unbiasedTrue,将使用贝塞尔校正。否则,将计算样本偏差,而不进行任何校正。

torch.std(input, dim, unbiased, keepdim=False, *, out=None) → Tensor
参数

  • input(Tensor) – 输入张量。
  • unbiased(bool) – 是否使用贝塞尔校正 ( δN = 1)。

你可以自己试试:

>>> a.std(), b.std(unbiased=True), b.std(unbiased=False)
(0.8364538, tensor(0.8942), tensor(0.8365))

推荐阅读