起因是看到有的T.Normalize参数是固定的一堆0.5,而有的则是符合函数定义的计算出来的均值标准差而产生的疑惑


文章目录

  • 一. 函数功能(快速上手)
  • 二. transform.Normalize参数详解及样例
  • 三. 常见用法(解释了为何有时参数是固定的0.5)


一. 函数功能(快速上手)

T.Normalize(mean, std)

输入(channel,height,width)形式的tensor,并输入每个channel对应的均值和标准差作为参数,函数会利用这两个参数分别将每层标准化(使数据均值为0,方差为1)后输出。即:

pytorch normalize pytorch normalize参数_深度学习
例:(具体解释见参数详解)

import torch
from torchvision import transforms as T
x = np.array([[[1, 1],
               [3, 3]],
              [[2, 2],
               [4, 4]]])
tr = T.Normalize([2,3], [1,1])
tr(x.float())
'''
输出:
tensor([[[-1., -1.],
         [ 1.,  1.]],
        [[-1., -1.],
         [ 1.,  1.]]])
'''

二. transform.Normalize参数详解及样例

T.Normalize(mean, std)

参数详解:

  • mean:(list)长度与输入的通道数相同,代表每个通道上所有数值的平均值。
  • std:(list)长度与输入的通道数相同,代表每个通道上所有数值的标准差。
import torch

x=torch.tensor([[[1,1],[3,3]],[[2,2],[4,4]]])
x
'''
tensor([[[1, 1],
         [3, 3]],  # 第一个通道均值为2,标准差为1
         
        [[2, 2],
         [4, 4]]]) # 第二个通道均值为3,标准差为1
'''

#  所以这个tensor的mean应为[2,3],std应为[1,1]

将每个通道的均值和标准差作为参数输入,即可使每个通道标准化,即均值为0,方差为1

from torchvision import transforms as T
tr = T.Normalize([2,3], [1,1])
tr(x.float())
'''
tensor([[[-1., -1.],
         [ 1.,  1.]],
        [[-1., -1.],
         [ 1.,  1.]]])
'''

三. 常见用法(解释了为何有时参数是固定的0.5)

1.如上例所示,分别计算出每层通道的均值和标准差,作为参数输入即可对每层通道进行标准化

思考:

问题:按说输入确定时,每个通道的均值和标准差也就确定了,但为什么这个函数任需要人为输入这两个参数?

回答:当输入的图片较大时,通道的均值和标准差计算相对耗时。人为的话可以取样计算或估算这两个值,更加灵活。

2.将两个参数都设置为0.5并与transforms.ToTensor()一起使用可以使将数据强制缩放到[-1,1]区间上。(标准化只能保证大部分数据在0附近——3σ原则)

这个用法实际上并不是这个函数的本意,只是借用了(x-mean)/std这个公式。

首先,ToTensor可以将图像的值从[0,255]通过out = in/255缩放到[0,1],之后再通过区间化公式:
pytorch normalize pytorch normalize参数_pytorch normalize_02

  • 该式可以使X缩放到范围[a,b]

将[0,1]缩放到[-1,1]:将a=-1,b=1带入上式即可得到x_new = (x-0.5)/0.5,即mean和std都设置为0.5

from torchvision import transforms as T
import numpy as np
x = np.array([[[253, 179],
               [102, 17]],
              [[45, 99],
               [4, 223]]])
x_pil = T.ToPILImage()(x.astype('uint8'))  
# 只有当输入的array是uint8类型时ToTensor才能除255,
# 后面可能出一篇ToPILImage详细说一下
x_t = T.ToTensor()(x_pil)
T.Normalize([0.5,0.5], [0.5,0.5])(x_t)
'''
tensor([[[ 0.9843, -0.2000],
         [-0.6471, -0.9686]],
        [[ 0.4039, -0.8667],
         [-0.2235,  0.7490]]])
'''