torchvision.transforms.Normalize 是如何操作的?

2024-04-11

我不明白如何标准化Pytorch works.

我想将平均值设置为0和标准差1跨越张量中的所有列x形状的(2, 2, 3).

一个简单的例子:

>>> x = torch.tensor([[[ 1.,  2.,  3.],
                       [ 4.,  5.,  6.]],

                       [[ 7.,  8.,  9.],
                        [10., 11., 12.]]])

>>> norm = transforms.Normalize((0, 0), (1, 1))
>>> norm(x)
tensor([[[ 1.,  2.,  3.],
         [ 4.,  5.,  6.]],

        [[ 7.,  8.,  9.],
         [10., 11., 12.]]])

因此,应用归一化变换时没有任何变化。这是为什么?


为了回答你的问题,你现在已经意识到torchvision.transforms.Normalize https://pytorch.org/vision/main/generated/torchvision.transforms.Normalize.html没有像你预期的那样工作。那是因为它并不意味着:

  • 正常化:(使你的数据范围在[0, 1]) nor

  • 标准化: 制作你的数据mean=0 and std=1(这就是你正在寻找的。

执行的操作是T.Normalize只是一个平移尺度变换:

output[channel] = (input[channel] - mean[channel]) / std[channel]

参数名称mean and std这似乎相当具有误导性,因为知道它并不意味着指代所需的output而是统计数据任意值。没错,如果你输入mean=0 and std=1,它会给你output = (input - 0) / 1 = input。因此您收到的结果是函数norm当您期望获得均值和方差张量时,对张量值没有影响0 and 1, 分别。

然而,提供正确的mean and std参数,i.e. when mean=mean(data) and std=std(data),然后你最终计算出z-score https://en.wikipedia.org/wiki/Standard_score您的数据通道逐个通道,这就是通常所说的'标准化'。所以为了真正得到mean=0 and std=1,您首先需要计算数据的平均值和标准差。

如果你这样做:

>>> mean, std = x.mean(), x.std()
(tensor(6.5000), tensor(3.6056))

它将分别为您提供全局平均值和全局标准差。

相反,您想要的是测量一阶和二阶统计量per-渠道。因此,我们需要申请torch.mean https://pytorch.org/docs/stable/generated/torch.mean.html and torch.std https://pytorch.org/docs/stable/generated/torch.mean.html在所有维度上期望dim=1。这两个函数都可以接收tuple尺寸:

>>> mean, std = x.mean((0,2)), x.std((0,2))
(tensor([5., 8.]), tensor([3.4059, 3.4059]))

以上是正确的均值和标准差x沿每个通道测量。从那里您可以继续使用T.Normalize(mean, std)正确转换您的数据x具有正确的平移尺度参数。

>>> norm(x)
tensor([[[-1.5254, -1.2481, -0.9707],
         [-0.6934, -0.4160, -0.1387]],

        [[ 0.1387,  0.4160,  0.6934],
         [ 0.9707,  1.2481,  1.5254]]])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

torchvision.transforms.Normalize 是如何操作的? 的相关文章

随机推荐