Pytorch中的正常化是如何操作的?

Pytorch中的正常化是如何操作的?,pytorch,torchvision,Pytorch,Torchvision,这一定是一个非常基本的问题,但即使在尝试了一些东西之后,我也不明白怎么做 Pytorch中的规范化工作正常 我想将大小为(2,2,3)的张量x中所有列的平均值设置为0,标准偏差设置为1。 一个简单的例子: norm = transforms.Normalize((0,0),(1,1)) x = torch.tensor([[[1.0,2,3],[4,5,6]],[[7,8,9],[10,11,12]]]) out = norm(x) print(x) print(out) 给予 因此,标准化没

这一定是一个非常基本的问题,但即使在尝试了一些东西之后,我也不明白怎么做
Pytorch
中的规范化工作正常

我想将大小为
(2,2,3)
的张量
x
中所有列的平均值设置为0,标准偏差设置为1。 一个简单的例子:

norm = transforms.Normalize((0,0),(1,1))
x = torch.tensor([[[1.0,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
out = norm(x)
print(x)
print(out)
给予

因此,标准化没有任何改变。为什么?

请按照以下说明操作:

使用平均值和标准偏差对张量图像进行规格化。给定平均值: (平均值[1],…,平均值[n])和标准:(标准值[1],…,标准值[n])对于n个通道,此 变换将规范化输入火炬的每个通道。*张量,即。, 输出[通道]=(输入[通道]-平均[通道])/std[通道]

因此,如果您有
mead=0
std=1
,则
output=(output-0)/1
不会改变

显示上述解释的示例:

from torchvision import transforms
import torch

norm = transforms.Normalize((0,0),(1,2))
x = torch.tensor([[[1.0,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
out = norm(x)
print(x)
print(out)
产出:

tensor([[[ 1.,  2.,  3.],  
         [ 4.,  5.,  6.]], 

        [[ 7.,  8.,  9.],  
         [10., 11., 12.]]])
tensor([[[1.0000, 2.0000, 3.0000], 
         [4.0000, 5.0000, 6.0000]],

        [[3.5000, 4.0000, 4.5000],
         [5.0000, 5.5000, 6.0000]]])
正如您所看到的,第一个通道是不变的,第二个通道是除以 2.

按照以下说明操作:

使用平均值和标准偏差对张量图像进行规格化。给定平均值: (平均值[1],…,平均值[n])和标准:(标准值[1],…,标准值[n])对于n个通道,此 变换将规范化输入火炬的每个通道。*张量,即。, 输出[通道]=(输入[通道]-平均[通道])/std[通道]

因此,如果您有
mead=0
std=1
,则
output=(output-0)/1
不会改变

显示上述解释的示例:

from torchvision import transforms
import torch

norm = transforms.Normalize((0,0),(1,2))
x = torch.tensor([[[1.0,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
out = norm(x)
print(x)
print(out)
产出:

tensor([[[ 1.,  2.,  3.],  
         [ 4.,  5.,  6.]], 

        [[ 7.,  8.,  9.],  
         [10., 11., 12.]]])
tensor([[[1.0000, 2.0000, 3.0000], 
         [4.0000, 5.0000, 6.0000]],

        [[3.5000, 4.0000, 4.5000],
         [5.0000, 5.5000, 6.0000]]])
正如您所看到的,第一个通道是不变的,第二个通道是除以
2.

实际回答你的问题。你现在已经意识到它并不像你期望的那样工作。这是因为它并不意味着规范化(使您的数据范围在
[0,1]
中)或标准化(使您的数据的
平均值=0
std=1
,这正是您所寻找的)您的数据。执行的只是一个移位刻度操作:

给定
平均值
标准值
,称之为
标准化
,感觉有点违反直觉。。。所以自然地,
(输入-0)/1
给出了
output=input
,这一点都没有帮助

但是,如果您提供
mean=mean(data)
std=std(data)
作为参数,那么您最终将按通道计算数据通道的长度,这通常称为“标准化”。因此,为了实际获得
mean=0
std=1
,首先需要计算数据的平均值和标准偏差

如果您这样做:

>>> mean, std = x.mean(), x.std()
(tensor(6.5000), tensor(3.6056))
它将分别给出全球平均值和全球std

相反,您想要的是测量每个通道的两个参数。因此,除了在
dim=1
上,我们希望在所有维度上使用
.mean()
.std()
。为此,我们可以排列
dim=0
dim=1
,展平除
dim=0
(现在是排列后的通道轴)之外的所有轴,并调用
.mean(dim=1)
.std(dim=1)
,即沿展平尺寸

>>> flattened = x.permute(1, 0, 2).flatten(start_dim=1)
>>> mean, std = flattened.mean(dim=1), flattened.std(dim=1)
(tensor([5., 8.]), tensor([3.4059, 3.4059]))
这是沿每个通道测量的
x
的正确平均值和标准偏差。从那里,您可以继续使用
torchvision.transforms.Normalize(mean,std)
到-现在正确地-Normalize
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]]])

真正回答你的问题。你现在已经意识到它并不像你期望的那样工作。这是因为它并不意味着规范化(使您的数据范围在
[0,1]
中)或标准化(使您的数据的
平均值=0
std=1
,这正是您所寻找的)您的数据。执行的只是一个移位刻度操作:

给定
平均值
标准值
,称之为
标准化
,感觉有点违反直觉。。。所以自然地,
(输入-0)/1
给出了
output=input
,这一点都没有帮助

但是,如果您提供
mean=mean(data)
std=std(data)
作为参数,那么您最终将按通道计算数据通道的长度,这通常称为“标准化”。因此,为了实际获得
mean=0
std=1
,首先需要计算数据的平均值和标准偏差

如果您这样做:

>>> mean, std = x.mean(), x.std()
(tensor(6.5000), tensor(3.6056))
它将分别给出全球平均值和全球std

相反,您想要的是测量每个通道的两个参数。因此,除了在
dim=1
上,我们希望在所有维度上使用
.mean()
.std()
。为此,我们可以排列
dim=0
dim=1
,展平除
dim=0
(现在是排列后的通道轴)之外的所有轴,并调用
.mean(dim=1)
.std(dim=1)
,即沿展平尺寸

>>> flattened = x.permute(1, 0, 2).flatten(start_dim=1)
>>> mean, std = flattened.mean(dim=1), flattened.std(dim=1)
(tensor([5., 8.]), tensor([3.4059, 3.4059]))
这是沿每个通道测量的
x
的正确平均值和标准偏差。从那里,您可以继续使用
torchvision.transforms.Normalize(mean,std)
到-现在正确地-Normalize
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]]])