部署模型的优化:Z-score标准化
flyfish
如果接触过计算机视觉,一定对这个操作不陌生:训练模型前给图像做预处理,先减去一组固定的均值,再除以一组固定的标准差。
为什么一定要做这一步?这两步简单的算术,背后到底藏着怎样的数学逻辑?
其实这两步加起来,就是统计学和机器学习里最常用的标准化方法——Z-score标准化,也有人叫它标准差标准化、零均值标准化。它看起来只是先减后除的简单操作,背后却是一套完整的统计设计。今天把这个天天见的操作彻底搞懂。
一、标准化到底在对数据做什么?
在推导公式之前,我们先抛开所有符号,想明白一件事:我们做标准化,到底想实现什么效果?
目标非常明确,就两条:
而Z-score做的,就是通过一次线性变换,把原始数据平移、缩放,刚好满足这两个条件。
什么是线性变换?说穿了就是初中数学里的先乘一个数,再加一个数:
z=a⋅x+b z = a \\cdot x + b z=a⋅x+b
其中aaa是缩放系数,bbb是平移量。乘一个数,能把数据整体拉大或缩小,改变它的波动幅度;加一个数,能把数据整体左右移动,改变它的中心位置。
我们接下来要做的,就是通过上面两个目标,算出这个缩放系数和平移量到底该取多少。
二、一步步推导:公式到底是怎么来的?
我们先做基础约定:原始数据包含nnn个样本,分别为x1,x2,…,xnx_1, x_2, \\dots, x_nx1,x2,…,xn;它们的平均值为μ\\muμ,标准差为σ\\sigmaσ;变换之后的数值为zzz。
第一步:用平均值为0,推导平移量
我们先计算变换之后的数据平均值。根据定义,平均值等于所有样本之和除以样本总数。
变换后每个样本的值为a⋅xi+ba \\cdot x_i + ba⋅xi+b,因此变换后的平均值为:
E[z]=1n∑i=1n(a⋅xi+b)
E[z] = \\frac{1}{n}\\sum_{i=1}^n (a \\cdot x_i + b)
E[z]=n1i=1∑n(a⋅xi+b)
根据求和的分配律,将求和式拆分为两部分:
E[z]=1n(∑i=1na⋅xi+∑i=1nb)
E[z] = \\frac{1}{n}\\left( \\sum_{i=1}^n a \\cdot x_i + \\sum_{i=1}^n b \\right)
E[z]=n1(i=1∑na⋅xi+i=1∑nb)
常数可以提到求和符号之外,nnn个常数bbb相加等于n⋅bn \\cdot bn⋅b,因此式子可以化简为:
E[z]=an∑i=1nxi+n⋅bn
E[z] = \\frac{a}{n}\\sum_{i=1}^n x_i + \\frac{n \\cdot b}{n}
E[z]=nai=1∑nxi+nn⋅b
其中1n∑i=1nxi\\frac{1}{n}\\sum_{i=1}^n x_in1∑i=1nxi就是原始数据的平均值μ\\muμ,第二项约分后等于bbb。由此可以得到线性变换下的均值变化规律:
E[z]=aμ+b
E[z] = a\\mu + b
E[z]=aμ+b
Z-score标准化要求变换后平均值为0,即E[z]=0E[z] = 0E[z]=0,代入上式可得:
aμ+b=0
a\\mu + b = 0
aμ+b=0
移项后得到平移量bbb的表达式:
b=−aμ
b = -a\\mu
b=−aμ
到这里,我们就把bbb用aaa表示了出来。接下来只要算出缩放系数aaa,就能得到完整的变换公式。
第二步:用标准差为1,推导缩放系数
要计算变换后的标准差,需要先从方差入手。方差描述数据的离散程度,定义为每个样本与平均值偏差的平方的平均值;标准差是方差的算术平方根。
根据定义,变换后的方差为:
Var(z)=1n∑i=1n(zi−E[z])2
\\text{Var}(z) = \\frac{1}{n}\\sum_{i=1}^n \\left( z_i – E[z] \\right)^2
Var(z)=n1i=1∑n(zi−E[z])2
我们已经知道单个变换后的样本zi=a⋅xi+bz_i = a \\cdot x_i + bzi=a⋅xi+b,以及变换后的平均值E[z]=aμ+bE[z] = a\\mu + bE[z]=aμ+b。将两者代入偏差项:
zi−E[z]=(a⋅xi+b)−(aμ+b)
z_i – E[z] = (a \\cdot x_i + b) – (a\\mu + b)
zi−E[z]=(a⋅xi+b)−(aμ+b)
展开后,bbb项相互抵消,仅剩与缩放系数相关的部分:
zi−E[z]=a⋅xi−aμ=a⋅(xi−μ)
z_i – E[z] = a \\cdot x_i – a\\mu = a \\cdot (x_i – \\mu)
zi−E[z]=a⋅xi−aμ=a⋅(xi−μ)
这也对应一个直观结论:给所有数据同时加上一个固定数值,不会改变数据的离散程度。因为平移量在计算偏差时会被完全抵消。
将偏差结果代回方差定义式:
Var(z)=1n∑i=1n[a⋅(xi−μ)]2
\\text{Var}(z) = \\frac{1}{n}\\sum_{i=1}^n \\left[ a \\cdot (x_i – \\mu) \\right]^2
Var(z)=n1i=1∑n[a⋅(xi−μ)]2
将平方展开,常数a2a^2a2提到求和符号之外:
Var(z)=a2⋅1n∑i=1n(xi−μ)2
\\text{Var}(z) = a^2 \\cdot \\frac{1}{n}\\sum_{i=1}^n (x_i – \\mu)^2
Var(z)=a2⋅n1i=1∑n(xi−μ)2
其中1n∑i=1n(xi−μ)2\\frac{1}{n}\\sum_{i=1}^n (x_i – \\mu)^2n1∑i=1n(xi−μ)2就是原始数据的方差σ2\\sigma^2σ2,因此得到线性变换下方差的变化规律:
Var(z)=a2⋅σ2
\\text{Var}(z) = a^2 \\cdot \\sigma^2
Var(z)=a2⋅σ2
标准差是方差的算术平方根,因此变换后的标准差为:
σ(z)=Var(z)=a⋅σ
\\sigma(z) = \\sqrt{\\text{Var}(z)} = a \\cdot \\sigma
σ(z)=Var(z)=a⋅σ
这里默认缩放不改变数据的正负顺序,因此aaa取正值。
Z-score标准化要求变换后的标准差为1,即σ(z)=1\\sigma(z) = 1σ(z)=1,代入上式可得:
a⋅σ=1
a \\cdot \\sigma = 1
a⋅σ=1
解得缩放系数:
a=1σ
a = \\frac{1}{\\sigma}
a=σ1
第三步:合并结果,得到最终公式
将a=1σa = \\frac{1}{\\sigma}a=σ1代入平移量的表达式b=−aμb = -a\\mub=−aμ,可得:
b=−μσ
b = -\\frac{\\mu}{\\sigma}
b=−σμ
再将aaa和bbb代回线性变换的通用式z=a⋅x+bz = a \\cdot x + bz=a⋅x+b:
z=1σ⋅x−μσ
z = \\frac{1}{\\sigma} \\cdot x – \\frac{\\mu}{\\sigma}
z=σ1⋅x−σμ
整理后就得到了Z-score标准化的最终公式:
z=x−μσ
z = \\frac{x – \\mu}{\\sigma}
z=σx−μ
到这里,整个推导就完成了。没有任何凭空出现的结论,每一步都来自最基础的统计定义,最终从两个简单的目标出发,推导出了这个通用公式。
三、数值验证:亲手算一遍,确认结果成立
光推导公式还不够,我们用一组真实的数据,完整演算一遍标准化的全过程,再反向验证变换后的均值和标准差是否真的等于0和1。
我们选取一组简单的样本数据:2, 4, 4, 4, 5, 5, 7, 9
总共有8个样本,即KaTeX parse error: Can't use function '\\(' in math mode at position 1: \\̲(̲n=8\\)。
步骤1:计算原始数据的均值μ\\muμ
根据均值定义,所有样本之和除以样本数:
μ=2+4+4+4+5+5+7+98
\\mu = \\frac{2 + 4 + 4 + 4 + 5 + 5 + 7 + 9}{8}
μ=82+4+4+4+5+5+7+9
逐步计算分子总和:2+4=6,6+4=10,10+4=14,14+5=19,19+5=24,24+7=31,31+9=40
代入计算:
μ=408=5
\\mu = \\frac{40}{8} = 5
μ=840=5
原始数据的均值为5。
步骤2:计算原始数据的方差σ2\\sigma^2σ2和标准差σ\\sigmaσ
根据方差定义,先计算每个样本与均值的偏差,再求平方,最后取平均。
逐个计算每个样本的偏差平方:
第一个样本:(2−5)2=(−3)2=9(2-5)^2 = (-3)^2 = 9(2−5)2=(−3)2=9
第二个样本:(4−5)2=(−1)2=1(4-5)^2 = (-1)^2 = 1(4−5)2=(−1)2=1
第三个样本:(4−5)2=1(4-5)^2 = 1(4−5)2=1
第四个样本:(4−5)2=1(4-5)^2 = 1(4−5)2=1
第五个样本:(5−5)2=02=0(5-5)^2 = 0^2 = 0(5−5)2=02=0
第六个样本:(5−5)2=0(5-5)^2 = 0(5−5)2=0
第七个样本:(7−5)2=22=4(7-5)^2 = 2^2 = 4(7−5)2=22=4
第八个样本:(9−5)2=42=16(9-5)^2 = 4^2 = 16(9−5)2=42=16
将所有偏差平方求和:
∑i=18(xi−μ)2=9+1+1+1+0+0+4+16=32
\\sum_{i=1}^8 (x_i – \\mu)^2 = 9 + 1 + 1 + 1 + 0 + 0 + 4 + 16 = 32
i=1∑8(xi−μ)2=9+1+1+1+0+0+4+16=32
方差为偏差平方的平均值:
σ2=328=4
\\sigma^2 = \\frac{32}{8} = 4
σ2=832=4
标准差为方差的算术平方根:
σ=4=2
\\sigma = \\sqrt{4} = 2
σ=4=2
原始数据的标准差为2。
步骤3:对每个样本执行Z-score标准化
套用公式zi=xi−μσz_i = \\frac{x_i – \\mu}{\\sigma}zi=σxi−μ,逐个计算标准化后的数值:
z1=2−52=−32=−1.5z_1 = \\frac{2 – 5}{2} = \\frac{-3}{2} = -1.5z1=22−5=2−3=−1.5
z2=4−52=−12=−0.5z_2 = \\frac{4 – 5}{2} = \\frac{-1}{2} = -0.5z2=24−5=2−1=−0.5
z3=4−52=−0.5z_3 = \\frac{4 – 5}{2} = -0.5z3=24−5=−0.5
z4=4−52=−0.5z_4 = \\frac{4 – 5}{2} = -0.5z4=24−5=−0.5
z5=5−52=02=0z_5 = \\frac{5 – 5}{2} = \\frac{0}{2} = 0z5=25−5=20=0
z6=5−52=0z_6 = \\frac{5 – 5}{2} = 0z6=25−5=0
z7=7−52=22=1z_7 = \\frac{7 – 5}{2} = \\frac{2}{2} = 1z7=27−5=22=1
z8=9−52=42=2z_8 = \\frac{9 – 5}{2} = \\frac{4}{2} = 2z8=29−5=24=2
标准化后的完整数据为:-1.5, -0.5, -0.5, -0.5, 0, 0, 1, 2
步骤4:验证变换后的均值是否为0
计算标准化后数据的平均值:
E[z]=−1.5+(−0.5)+(−0.5)+(−0.5)+0+0+1+28
E[z] = \\frac{-1.5 + (-0.5) + (-0.5) + (-0.5) + 0 + 0 + 1 + 2}{8}
E[z]=8−1.5+(−0.5)+(−0.5)+(−0.5)+0+0+1+2
逐步计算分子总和:
-1.5 – 0.5 = -2;-2 – 0.5 = -2.5;-2.5 – 0.5 = -3;-3 + 0 + 0 = -3;-3 + 1 = -2;-2 + 2 = 0
代入计算:
E[z]=08=0
E[z] = \\frac{0}{8} = 0
E[z]=80=0
变换后的均值恰好为0,符合设计目标。
步骤5:验证变换后的标准差是否为1
同样先计算方差,再求标准差。先计算每个zzz值与均值0的偏差平方:
(−1.5−0)2=(−1.5)2=2.25(-1.5 – 0)^2 = (-1.5)^2 = 2.25(−1.5−0)2=(−1.5)2=2.25
(−0.5−0)2=0.25(-0.5 – 0)^2 = 0.25(−0.5−0)2=0.25
(−0.5−0)2=0.25(-0.5 – 0)^2 = 0.25(−0.5−0)2=0.25
(−0.5−0)2=0.25(-0.5 – 0)^2 = 0.25(−0.5−0)2=0.25
(0−0)2=0(0 – 0)^2 = 0(0−0)2=0
(0−0)2=0(0 – 0)^2 = 0(0−0)2=0
(1−0)2=1(1 – 0)^2 = 1(1−0)2=1
(2−0)2=4(2 – 0)^2 = 4(2−0)2=4
偏差平方求和:
∑i=18(zi−E[z])2=2.25+0.25+0.25+0.25+0+0+1+4=8
\\sum_{i=1}^8 (z_i – E[z])^2 = 2.25 + 0.25 + 0.25 + 0.25 + 0 + 0 + 1 + 4 = 8
i=1∑8(zi−E[z])2=2.25+0.25+0.25+0.25+0+0+1+4=8
变换后的方差:
Var(z)=88=1
\\text{Var}(z) = \\frac{8}{8} = 1
Var(z)=88=1
变换后的标准差:
σ(z)=1=1
\\sigma(z) = \\sqrt{1} = 1
σ(z)=1=1
变换后的标准差恰好为1,完全符合设计目标。
至此,我们通过真实数据完整验证了Z-score标准化的效果,推导的结论完全成立。
四、均值和期望是一回事吗?
很多人看教材的时候会困惑:有时候写 μ\\muμ 是均值,有时候又写 (E[x])(E[x])(E[x])叫期望,这俩到底是不是一个东西?
严格来说,它们不是一回事,区别在总体和样本。
期望是针对整个总体的,是一个理论上的固定值。比如掷一枚均匀的骰子,所有可能结果的平均是3.5,这就是期望。它是分布本身的属性,和掷多少次没关系。
均值是针对手里的样本的,是实际算出来的数值。比如掷10次骰子,算出来的平均分就是样本均值。每次抽样的结果不一样,算出来的均值也会变。
放到机器学习的场景里,我们没有办法拿到所有可能的数据,手里只有训练集。所以我们默认训练集能代表整体数据的分布,直接用训练集算出来的样本均值,去代替总体的期望;用样本标准差,代替总体的标准差。
平时大家说的数据集均值,本质上就是样本均值,只是习惯上沿用了期望的符号和叫法。
五、为什么偏偏是均值0、标准差1?
看到这里可能会问:线性变换能把数据缩放到任意范围,为什么一定要凑成均值0、标准差1?均值设成5、标准差设成10不行吗?
这个设定不是随便选的,它是从实际工程需求里沉淀出来的最优选择。
1. 消除尺度差异,让所有特征站在同一起跑线
现实数据里,不同特征的数值范围天差地别。比如一个人的年龄在0到100之间,年收入可能在几万到几十万之间,数值差了上千倍。
如果不做标准化,在计算距离、训练模型的时候,数值大的特征会完全盖过数值小的特征的影响;梯度下降更新权重时,大尺度特征的更新步长也会远大于小尺度特征,导致训练来回震荡,收敛很慢。
标准化之后,所有特征的波动范围都被拉到了相近的水平,每个特征对模型的影响更均衡,不会被数值大小绑架。
2. 零均值让神经网络训练更稳定
对于神经网络来说,零均值的作用非常关键。
如果输入数据全是正数,比如原始图像像素都是0到255,经过卷积或者全连接层之后,输出也会倾向于全是正数。再经过sigmoid、tanh这类S型激活函数时,很容易进入两端平缓的区域,梯度变得非常小,模型就会学不动,也就是常说的梯度消失。
数据中心对齐到0之后,正负值各占一半,激活函数的输入会落在梯度最明显的中间区域,梯度传播更顺畅,训练速度和稳定性都会提升很多。
3. 单位标准差让数据有了统一的度量衡
当标准差统一为1之后,每个标准化后的z值都有了明确的物理意义:这个数值比平均值偏离了多少个标准差。
比如z=2,就代表这个值比平均水平高出2倍的波动幅度,属于偏高的数值;z=-0.5,就代表比平均水平略低一点,属于正常范围。
不管原始数据的单位是元、岁还是像素,都可以直接通过z值比较偏离程度,跨特征、跨数据集都能直接对比。
4. 保证训练和推理的分布一致
这也刚好能解释开头的ImageNet预处理。
预训练模型是在整个ImageNet数据集上,用标准化后的数据训练出来的。模型的权重已经适配了均值0、标准差1的输入分布。
我们自己用预训练模型时,如果不做同样的标准化,输入数据的分布和训练时不一样,模型权重就对不上,预测效果会大打折扣。这一步操作,本质是在保证输入分布和训练分布对齐。
六、ImageNet预处理到底在做什么?
现在再回头看图像预处理里的逐通道减均值、除标准差,逻辑就非常清晰了。
RGB三个颜色通道,就相当于三个独立的特征维度。人们提前在百万级的ImageNet数据集上,分别统计出了R、G、B三个通道各自的均值和标准差。
对每张输入图像,每个通道的像素都单独套用一次Z-score公式,把0到255的原始像素值,转换成模型熟悉的标准分布。
整个过程就是一次逐通道执行的Z-score标准化。


