transforms.Normalize()函数的计算过程及参数由来

1.transforms.Normalize()函数的计算过程。

  • 在对数据预处理时常常会遇到transforms.Normalize(mean=[0.485, 0.456,
    0.406],std=[0.229, 0.224, 0.2])语句。
  • 值得注意的是,在使用该语句之前,需使用transforms.ToTensor()函数将输入数据的形状由H、W、C变为C、H、W,然后将所有像素值除以255,即将数据归一化到[0,1]。
  • 接着,对每个通道依次使用公式"(x-mean)/std"求得标准化值。
  • 具体代码及运行结果如下,建议细细体会。
import torch
import numpy as np
from torchvision import transforms

data = np.array([
                [[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
                [[2,2,2],[2,2,2],[2,2,2],[2,2,2],[2,2,2]],
                [[3,3,3],[3,3,3],[3,3,3],[3,3,3],[3,3,3]],
                [[4,4,4],[4,4,4],[4,4,4],[4,4,4],[4,4,4]],
                [[5,5,5],[5,5,5],[5,5,5],[5,5,5],[5,5,5]]
        ],dtype='uint8')
print(data.shape)
data = transforms.ToTensor()(data)
print(data.shape)

print(data)
data = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                             std=[0.229, 0.224, 0.225])(data)
print(data)
(5, 5, 3)
torch.Size([3, 5, 5])
tensor([[[0.0039, 0.0039, 0.0039, 0.0039, 0.0039],
         [0.0078, 0.0078, 0.0078, 0.0078, 0.0078],
         [0.0118, 0.0118, 0.0118, 0.0118, 0.0118],
         [0.0157, 0.0157, 0.0157, 0.0157, 0.0157],
         [0.0196, 0.0196, 0.0196, 0.0196, 0.0196]],

        [[0.0039, 0.0039, 0.0039, 0.0039, 0.0039],
         [0.0078, 0.0078, 0.0078, 0.0078, 0.0078],
         [0.0118, 0.0118, 0.0118, 0.0118, 0.0118],
         [0.0157, 0.0157, 0.0157, 0.0157, 0.0157],
         [0.0196, 0.0196, 0.0196, 0.0196, 0.0196]],

        [[0.0039, 0.0039, 0.0039, 0.0039, 0.0039],
         [0.0078, 0.0078, 0.0078, 0.0078, 0.0078],
         [0.0118, 0.0118, 0.0118, 0.0118, 0.0118],
         [0.0157, 0.0157, 0.0157, 0.0157, 0.0157],
         [0.0196, 0.0196, 0.0196, 0.0196, 0.0196]]])
tensor([[[-2.1008, -2.1008, -2.1008, -2.1008, -2.1008],
         [-2.0837, -2.0837, -2.0837, -2.0837, -2.0837],
         [-2.0665, -2.0665, -2.0665, -2.0665, -2.0665],
         [-2.0494, -2.0494, -2.0494, -2.0494, -2.0494],
         [-2.0323, -2.0323, -2.0323, -2.0323, -2.0323]],

        [[-2.0182, -2.0182, -2.0182, -2.0182, -2.0182],
         [-2.0007, -2.0007, -2.0007, -2.0007, -2.0007],
         [-1.9832, -1.9832, -1.9832, -1.9832, -1.9832],
         [-1.9657, -1.9657, -1.9657, -1.9657, -1.9657],
         [-1.9482, -1.9482, -1.9482, -1.9482, -1.9482]],

        [[-1.7870, -1.7870, -1.7870, -1.7870, -1.7870],
         [-1.7696, -1.7696, -1.7696, -1.7696, -1.7696],
         [-1.7522, -1.7522, -1.7522, -1.7522, -1.7522],
         [-1.7347, -1.7347, -1.7347, -1.7347, -1.7347],
         [-1.7173, -1.7173, -1.7173, -1.7173, -1.7173]]])
[Finished in 1.6s]

2.transforms.Normalize(mean=[0.485, 0.456,
0.406],std=[0.229, 0.224, 0.2])参数由来。

  • 我们经常看到的参数mean=[0.485, 0.456, 0.406], std=[0.229, 0.224,
    0.225]是从ImageNet数据集上的百万张图片中随机抽样计算得到的。
  • 以一批图像(一批仅包含一张图像)为例进行计算,求得不同通道对应的均值和方差。
  • 代码及结果如下。
import torch
import numpy as np
from torchvision import transforms

# 链接:https://zhuanlan.zhihu.com/p/414242338
data = np.array([
                [[1,1,1],[1,1,1],[1,1,1],[1,1,1],[1,1,1]],
                [[2,2,2],[2,2,2],[2,2,2],[2,2,2],[2,2,2]],
                [[3,3,3],[3,3,3],[3,3,3],[3,3,3],[3,3,3]],
                [[4,4,4],[4,4,4],[4,4,4],[4,4,4],[4,4,4]],
                [[5,5,5],[5,5,5],[5,5,5],[5,5,5],[5,5,5]]
        ],dtype='uint8')
print(data.shape)

data = transforms.ToTensor()(data) #将数据转为C,W,H,并归一化到[0,1]
print(data.shape)


data = torch.unsqueeze(data,0) # 需要对数据进行扩维,增加batch维度
print(data.shape)


channel_mean = torch.zeros(3)
channel_std = torch.zeros(3)
print(channel_mean)

N, C, H, W = data.shape[:4]
data = data.view(N, C, -1)     #将w,h维度的数据展平,为batch,channel,data,然后对三个维度上的数分别求和和标准差
print(data.shape)

print(data)
#展平后,w,h属于第二维度,对他们求平均,sum(0)为将同一纬度的数据累加
channel_mean += data.mean(2).sum(0)
# print(channel_mean)
#展平后,w,h属于第二维度,对他们求标准差,sum(0)为将同一纬度的数据累加
channel_std += data.std(2).sum(0)
#获取所有batch的数据,这里为1


nb_samples = 0.
#创建3维的空列表
nb_samples += N
#获取同一batch的均值和标准差
channel_mean /= nb_samples
channel_std /= nb_samples
print(channel_mean, channel_std)
(5, 5, 3)
torch.Size([3, 5, 5])
torch.Size([1, 3, 5, 5])
tensor([0., 0., 0.])
torch.Size([1, 3, 25])
tensor([[[0.0039, 0.0039, 0.0039, 0.0039, 0.0039, 0.0078, 0.0078, 0.0078,
          0.0078, 0.0078, 0.0118, 0.0118, 0.0118, 0.0118, 0.0118, 0.0157,
          0.0157, 0.0157, 0.0157, 0.0157, 0.0196, 0.0196, 0.0196, 0.0196,
          0.0196],
         [0.0039, 0.0039, 0.0039, 0.0039, 0.0039, 0.0078, 0.0078, 0.0078,
          0.0078, 0.0078, 0.0118, 0.0118, 0.0118, 0.0118, 0.0118, 0.0157,
          0.0157, 0.0157, 0.0157, 0.0157, 0.0196, 0.0196, 0.0196, 0.0196,
          0.0196],
         [0.0039, 0.0039, 0.0039, 0.0039, 0.0039, 0.0078, 0.0078, 0.0078,
          0.0078, 0.0078, 0.0118, 0.0118, 0.0118, 0.0118, 0.0118, 0.0157,
          0.0157, 0.0157, 0.0157, 0.0157, 0.0196, 0.0196, 0.0196, 0.0196,
          0.0196]]])
tensor([0.0118, 0.0118, 0.0118]) tensor([0.0057, 0.0057, 0.0057])
[Finished in 1.7s]
  • 4
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信小海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值