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

Cla*_*neo 10 pytorch torchvision

我不明白标准化是如何Pytorch运作的。

我想将shape张量中所有列的均值0和标准差设置为。1x(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.]]])
Run Code Online (Sandbox Code Playgroud)

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

Iva*_*van 23

为了回答您的问题,您现在已经意识到这torchvision.transforms.Normalize并不像您预期​​的那样有效。那是因为它并不意味着:

  • 标准化:(使您的数据范围在[0, 1])也不

  • 标准化:使您的数据mean=0std=1(这就是您正在寻找的。

执行的操作T.Normalize仅仅是移位尺度变换:

output[channel] = (input[channel] - mean[channel]) / std[channel]
Run Code Online (Sandbox Code Playgroud)

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

然而,提供正确的meanstd参数,whenmean=mean(data)std=std(data),那么您最终会逐个通道计算数据通道的z 分数,这就是通常所说的“标准化”。因此,为了实际获得mean=0std=1,您首先需要计算数据的平均值和标准差。

如果你这样做:

>>> mean, std = x.mean(), x.std()
(tensor(6.5000), tensor(3.6056))
Run Code Online (Sandbox Code Playgroud)

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

相反,您想要的是测量每个通道的一阶和二阶统计数据。因此,我们需要在期望的所有维度上应用torch.mean和。这两个函数都可以接收维度元组:torch.stddim=1

>>> mean, std = x.mean((0,2)), x.std((0,2))
(tensor([5., 8.]), tensor([3.4059, 3.4059]))
Run Code Online (Sandbox Code Playgroud)

以上是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]]])
Run Code Online (Sandbox Code Playgroud)