规范化和缩放MNIST数据集的正确方法

时间:2020-09-04 18:13:18

标签: python machine-learning pytorch mnist

我到处都看过,但找不到我想要的东西。基本上,MNIST数据集的图像像素值在[0, 255]范围内。人们通常说,最好执行以下操作:

  • 将数据缩放到[0,1]范围。
  • 将数据归一化为具有零均值和单位标准偏差(data - mean) / std

不幸的是,没有人展示过如何做这两种事情。它们都减去0.1307的平均值,然后除以0.3081的标准偏差。这些值基本上是数据集的平均值和标准偏差除以255:

from torchvision.datasets import MNIST        
import torchvision.transforms as transforms 

trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True)
print('Min Pixel Value: {} \nMax Pixel Value: {}'.format(trainset.data.min(), trainset.data.max()))
print('Mean Pixel Value {} \nPixel Values Std: {}'.format(trainset.data.float().mean(), trainset.data.float().std()))
print('Scaled Mean Pixel Value {} \nScaled Pixel Values Std: {}'.format(trainset.data.float().mean() / 255, trainset.data.float().std() / 255))

这将输出以下内容

Min Pixel Value: 0 
Max Pixel Value: 255
Mean Pixel Value 33.31002426147461 
Pixel Values Std: 78.56748962402344
Scaled Mean: 0.13062754273414612 
Scaled Std: 0.30810779333114624

但是,显然以上都不是!结果数据1)将不在[0, 1]之间,并且将没有均值0或std 1。实际上,这就是我们正在做的:

[data - (mean / 255)] / (std / 255)

与此非常不同

[(scaled_data) - (mean/255)] / (std/255)

其中scaled_data就是data / 255

3 个答案:

答案 0 :(得分:4)

我认为您误解了一个关键概念:这是两个不同且不一致的扩展操作。您只能使用以下两种之一:

  • 平均值= 0,stdev = 1
  • 数据范围[0,1]

考虑一下,考虑[0,1]范围:如果数据都是小的正值,且min = 0和max = 1,则数据必须的总和为正,给出正的非零平均值。同样,当数据可能与平均值相差1.0时,stdev 不能为1

相反,如果您的均值= 0,则某些数据必须为负。


您仅使用两个转换中的一个。您使用哪一个取决于数据集的特征,并且最终取决于哪个对您的模型更有效

对于[0,1]缩放比例,您只需除以255。

对于均值= 0,stdev = 1缩放,执行已知的简单线性变换:

new_val = (old_val - old_mean) / old_stdev

这是否为您澄清了,还是我完全想念您的困惑点?

答案 1 :(得分:3)

Euler_Salter

我可能发现这个有点晚了,但希望我能帮上一点忙。

假设您使用的是 torchvision.Transform,以下代码可用于规范化 MNIST 数据集。

        train_loader = torch.utils.data.DataLoader(
        datasets.MNIST('./data', train=True
        transform=transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize((0.1307,), (0.3081,))
        ])),

通常,'transforms.ToTensor()' 用于将 [0,255] 范围内的输入数据转换为 3 维 Tensor。 此函数自动将输入数据缩放到 [0,1] 的范围。(这相当于将数据缩放到 0,1)

因此,'transforms.Normalize(...)' 中使用的均值和标准差分别为 0.1307 和 0.3081 是有道理的。 (这相当于归一化零均值和单位标准差。)

请参考以下链接以获得更好的解释。

https://pytorch.org/vision/stable/transforms.html

答案 2 :(得分:1)

目的

缩放功能的两个最重要的原因是:

  1. 您可以缩放要素以使它们的大小相同(即重要性或重量)。

示例

具有两个功能的数据集:年龄和体重。年龄以年为单位,重量以克为单位!现在,在他20岁那年,体重只有60Kg的小伙子就可以转换为矢量= [20岁,60000g],依此类推,对于整个数据集,依此类推。权重属性将在训练过程中占主导地位。具体取决于您使用的算法类型-有些算法比其他算法更敏感:神经网络,其中梯度下降的学习率受神经网络Theta值(即权重)的影响,而后者在训练过程中与输入(即特征)的相关性有所不同; Feature Scaling还可以提高收敛性。另一个示例是K均值聚类算法,因为它在空间的所有方向上都是各向同性的,因此要求具有相同大小的特征。 INTERESTING LIST

  1. 您可以扩展功能以加快执行时间。

这很简单:与非常大的数量(或将特征乘以其他一些参数所产生的非常大的数量..etc)相比,所有这些矩阵乘法和参数求和在用小数量时将更快。


类型

功能缩放器的最受欢迎类型可以总结如下:

  1. StandardScaler:通常是您的首选,它非常常用。它通过标准化数据(即居中)来工作,即将它们带到STD=1Mean=0 它会受到异常值的影响 ,并且仅当数据包含Gaussian-Like Distribution时才应使用。

enter image description here

  1. MinMaxScaler:通常在您要将所有数据点都置于特定范围内时使用(例如[0-1] )。 它受到异常值的严重影响 ,仅仅是因为它使用了Range

enter image description here

  1. RobustScaler:针对异常值是“ robust ”,因为它可以根据quantile range缩放数据。但是,您应该知道在缩放后的数据中仍然存在异常值。

enter image description here

  1. MaxAbsScaler:主要用于sparse data

enter image description here

  1. Unit Normalization:基本上,每个样本的矢量都按比例缩放以具有单位范数,而与样本的分布无关。

enter image description here


哪个和几个

您需要先了解您的数据集。如上所述,您需要先查看以下内容,例如: 数据分布 异常值的存在 正在使用的算法

无论如何,除非有特殊要求,否则每个数据集都需要一个定标器,这样,如果存在一种算法,则仅当数据在特定范围内时才有效并且的均值为零且标准差为1-全部在一起。不过,我从未遇到过这种情况。


要点

相关问题