九 批量标准化
Batch Normalization (批量归一化)是经常使用一个网络层,其主要的作用是控制数据的分布,加快网络的收敛
原因:神经网络的学习其实在学习数据的分布,随着网络的深度增加、网络复杂度增加,一般流经网络的数据都是一个 mini batch,每个 mini batch 之间的数据分布变化非常剧烈,这就使得网络参数频繁的进行大的调整以适应流经网络的不同分布的数据,给模型训练带来非常大的不稳定性,使得模型难以收敛。
对每一个 mini batch 的数据进行标准化之后,数据分布就变得稳定,参数的梯度变化也变得稳定,有助于加快模型的收敛。
1 实现过程
每一层的输入上执行标准化操作,并学习两个可训练的参数:
$$
缩放因子 \lambda 偏移量 \beta。
$$
1.计算均值和方差
$$
对于给定的神经网络层,假设输入数据为 \mathbf{x} = \{x_1, x_2, \ldots, x_m\},其中 m是批次大小
$$
$$
均值(Mean):\mu_B = \frac{1}{m} \sum_{i=1}^m x_i
$$
$$
方差:\sigma_B^2 = \frac{1}{m} \sum_{i=1}^m (x_i - \mu_B)^2
$$
2.标准化
使用均值和方差对数据进行标准化,使得每个特征的均值为0,方差为1。
$$
标准化后的值:\hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 }+\epsilon}。\epsilon 是一个很小的常数,防止分母为0.
$$
3.缩放和平移
标准化后的数据通常会通过可训练的参数进行缩放和平移,以恢复模型的表达能力。
$$
缩放(Gamma):y_i = \lambda \hat{x}_i
$$
$$
平移(Beta):y_i = \lambda \hat{x}_i + \beta
$$
4.标准化公式
$$
y=\lambda \cdot \dfrac{x-\mu _{B}}{\sqrt{\delta_B ^{2}}+\varepsilon }+\beta,\gamma 和\beta是在训练过程中学习到的参数。
$$
1.λ 和 β 是可学习的参数,它相当于对标准化后的值做了一个线性变换,λ 为系数,β 为偏置;
$$
2.\epsilon通常指为 1e-5,避免分母为 0;\mu_B 表示变量的均值;\sigma_B^2表示变量的方差
$$
2 训练和推理阶段
训练阶段:
均值和方差是基于当前批次的数据计算得到的。
推理阶段: 批量标准化使用的是训练过程中计算得到的全局均值和方差,而不是当前批次的数据。这些全局均值和方差通常会被保存在模型中,用于推理时的标准化过程。
3 作用
批量标准化(Batch Normalization, BN)通过以下几个方面来提高神经网络的训练稳定性、加速训练过程并减少过拟合:
1.缓解梯度问题
标准化处理可以防止激活值过大或过小,避免了激活函数(如 Sigmoid 或 Tanh)饱和的问题,从而缓解梯度消失或爆炸的问题。
2.加速训练
由于 BN 使得每层的输入数据分布更为稳定,因此模型可以使用更高的学习率进行训练。这可以加快收敛速度,并减少训练所需的时间。
3.减少过拟合
类似于正则化:虽然 BN 不是一种传统的正则化方法,但它通过对每个批次的数据进行标准化,可以起到一定的正则化作用。它通过在训练过程中引入了噪声(由于批量均值和方差的估计不完全准确),这有助于提高模型的泛化能力。
避免对单一数据点的过度拟合:BN 强制模型在每个批次上进行标准化处理,减少了模型对单个训练样本的依赖。这有助于模型更好地学习到数据的整体特征,而不是对特定样本的噪声进行过度拟合。
4 BatchNorm
数据在经过 BN 层之后,会被归一化成均值为 β,标准差为 γ 的分布
BN 层不会改变输入数据的维度,只改变输入数据的的分布. 在实际使用过程中,BN 常常和卷积神经网络结合使用,卷积层的输出结果后接 BN 层。
API:
torch.nn.BatchNorm2d(num_features, eps=1e-05, momentum=0.1, affine=True)
由于每次使用的 mini batch 的数据集,所以 BN 使用移动加权平均来近似计算均值和方差,而 momentum 参数则调节移动加权平均值的计算;
$$
affine = False 表示 \lambda=1,β=0,反之,则表示 γ 和 β 要进行学习;(仿射变换)
$$
BatchNorm2d 适用于输入的数据为 4D,输入数据的形状 [N,C,H,W],N 表示批次,C 代表通道数,H 代表高度,W 代表宽度
由于每次输入到网络中的时小批量的样本,我们使用指数加权平均来近似表示整体的样本的均值和方差:
running_mean = momentum * running_mean + (1.0 – momentum) * batch_mean running_var = momentum * running_var + (1.0 – momentum) * batch_var
batch_mean 和 batch_var 表示当前批次的均值和方差。而 running_mean 和 running_var 是近似的整体的均值和方差的表示。当我们进行评估时,可以使用该均值和方差对输入数据进行归一化。
5 代码实现
import torch import torch.nn as nn def test01(): img=torch.randint(0,255,(16,3,512,512)).type(torch.float32)#NCHW n_samples 一批次数据 print(img) norm2d=nn.BatchNorm2d(num_features=3) img=norm2d(img) print(img) if __name__ == "__main__": test01()
十 项目实战
数据集平台:Mobile Price Classification (kaggle.com)
鲍勃开了自己的手机公司。他想与苹果、三星等大公司展开硬仗。 他不知道如何估算自己公司生产的手机的价格。在这个竞争激烈的手机市场,你不能简单地假设事情。为了解决这个问题,他收集了各个公司的手机销售数据。 鲍勃想找出手机的特性(例如:RAM、内存等)和售价之间的关系。但他不太擅长机器学习。所以他需要你帮他解决这个问题。 在这个问题中,你不需要预测实际价格,而是要预测一个价格区间,表明价格多高。