为了回答你的问题,你现在已经意识到torchvision.transforms.Normalize https://pytorch.org/vision/main/generated/torchvision.transforms.Normalize.html没有像你预期的那样工作。那是因为它并不意味着:
执行的操作是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]]])