起因是看到有的T.Normalize参数是固定的一堆0.5,而有的则是符合函数定义的计算出来的均值标准差而产生的疑惑
文章目录
- 一. 函数功能(快速上手)
- 二. transform.Normalize参数详解及样例
- 三. 常见用法(解释了为何有时参数是固定的0.5)
一. 函数功能(快速上手)
T.Normalize(mean, std)
输入(channel,height,width)形式的tensor,并输入每个channel对应的均值和标准差作为参数,函数会利用这两个参数分别将每层标准化(使数据均值为0,方差为1)后输出。即:
例:(具体解释见参数详解)
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],之后再通过区间化公式:
- 该式可以使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]]])
'''