为什么 Pytorch 官方使用 mean=[0.485, 0.456, 0.406] 和 std=[0.229, 0.224, 0.225] 来规范化图像?

lar*_*ang 29 python normalize pytorch

在这个页面(https://pytorch.org/vision/stable/models.html)中,它说“所有预训练的模型都期望以相同的方式标准化输入图像,即小批量的 3 通道 RGB 图像形状 (3 x H x W),其中 H 和 W 预计至少为 224。图像必须加载到 [0, 1] 的范围内,然后使用mean = [0.485, 0.456, 0.406]std = [0.229, 0.224, 0.225]“进行归一化。

如果不是平时meanstd正常化是[0.5, 0.5, 0.5][0.5, 0.5, 0.5]?为什么要设置这么奇怪的值?

zih*_*hao 35

使用 Imagenet 的均值和标准差是一种常见的做法。它们是根据数百万张图像计算得出的。如果你想在你自己的数据集上从头开始训练,你可以计算新的均值和标准差。否则,建议使用具有自己的均值和标准差的 Imagenet 预训练模型。

  • 对于对使用自定义平均值和标准差时的结果感兴趣的人,请参阅火炬论坛:https://discuss.pytorch.org/t/discussion-why-normalise-according-to-imagenet-mean-and-std-dev-用于迁移学习/115670。这真的很有帮助。 (2认同)

cry*_*ick 8

在那个例子中,他们使用了 ImageNet 的均值和标准差,但是如果你看看他们的 MNIST 例子,均值和标准差是一维的(因为输入是灰度的——没有 RGB 通道)。

是否使用ImageNet的mean和stddev取决于你的数据。假设您的数据是“自然场景” (人、建筑物、动物、不同的照明/角度/背景等)的普通照片,并假设您的数据集以与 ImageNet 相同的方式存在偏差(在类平衡方面),然后用ImageNet的场景统计进行归一化就可以了。如果照片以某种方式“特殊”(颜色过滤、对比度调整、不常见的照明等)或“非自然主题”(医学图像、卫星图像、手绘等),那么我建议正确标准化您的数据集在模型训练之前!*

以下是一些示例代码,可帮助您入门:

import os
import torch
from torchvision import datasets, transforms
from torch.utils.data.dataset import Dataset
from tqdm.notebook import tqdm
from time import time

N_CHANNELS = 1

dataset = datasets.MNIST("data", download=True,
                 train=True, transform=transforms.ToTensor())
full_loader = torch.utils.data.DataLoader(dataset, shuffle=False, num_workers=os.cpu_count())

before = time()
mean = torch.zeros(1)
std = torch.zeros(1)
print('==> Computing mean and std..')
for inputs, _labels in tqdm(full_loader):
    for i in range(N_CHANNELS):
        mean[i] += inputs[:,i,:,:].mean()
        std[i] += inputs[:,i,:,:].std()
mean.div_(len(dataset))
std.div_(len(dataset))
print(mean, std)

print("time elapsed: ", time()-before)
Run Code Online (Sandbox Code Playgroud)

在计算机视觉中,“自然场景”具有与自然与人造无关的特定含义,请参阅https://en.wikipedia.org/wiki/Natural_scene_perception

*否则,由于损失函数的延长,您会遇到优化问题——请在此处查看我的回答