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)
到-现在正确地-Normalizex
或具有相同比例的任何其他张量
>>> 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)
到-现在正确地-Normalizex
或具有相同比例的任何其他张量
>>> 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]]])