当前位置: 首页 > article >正文

AI-02a5a6.神经网络-与学习相关的技巧-批量归一化

批量归一化 Batch Normalization

设置合适的权重初始值,则各层的激活值分布会有适当的广度,从而可以顺利的进行学习。那么,更进一步,强制性的调整激活值的分布,是的各层拥有适当的广度呢?批量归一化(Batch Normalization)就是基于这个想法产生的。

算法介绍

有什么优点呢?

  • 可以使学习快速进行(可以增大学习率)。
  • 不那么依赖初始值(对于初始值不用那么神经质)。
  • 抑制过拟合(降低Dropout等的必要性)

向神经网络中插入对数据分布进行正规化的层,即Batch Normalization层。

在这里插入图片描述

式(6.7), μ B ← 1 m ∑ i = 1 m x i σ B 2 ← 1 m ∑ i = 1 m ( x i − μ B ) 2 x ^ i ← x i − μ B σ B 2 + ϵ \begin{aligned} \mu_B &\leftarrow \frac{1}{m}\sum^m_{i=1}x_i \\ \sigma_B^2 &\leftarrow \frac{1}{m}\sum^m_{i=1}(x_i-\mu_B)^2 \\ \hat{x}_i &\leftarrow \frac{x_i-\mu_B}{\sqrt{\sigma_B^2+\epsilon}} \end{aligned} μBσB2x^im1i=1mxim1i=1m(xiμB)2σB2+ϵ xiμB

这里对mini-batch的 m m m个输入数据的集合 B = { x 1 , x 2 , . . . , x m } B = \{x_1, x_2, ... , x_m\} B={x1,x2,...,xm}求均值 μ B \mu_B μB和方差 σ B 2 \sigma_B^2 σB2 。然后,对输入数据进行均值为0、方差为1(合适的分布)的正规化。式(6.7)中的 ϵ \epsilon ϵ是一个微小值(比如,10e-7等),它是为了防止出现除以0的情况。

式(6.7)所做的是将mini-batch的输入数据 { x ^ 1 , x ^ 2 , . . . , x ^ m } \{\hat{x}_1, \hat{x}_2, ... , \hat{x}_m\} {x^1,x^2,...,x^m}变换为均值为0、方差为1的数据。通过将这个处理插入到激活函数的前面(或者后面),可以减小数据分布的偏向。

接着,Batch Norm层会对正规化后的数据进行缩放和平移的变换,式(6.8), y i ← γ x i ^ + β y_i \leftarrow \gamma\hat{x_i} + \beta yiγxi^+β

这里, γ \gamma γ β \beta β是参数。一开始 γ = 1 , β = 0 \gamma = 1, \beta = 0 γ=1,β=0,然后再通过学习调整到合适的值。

在这里插入图片描述

几乎所有的情况下都是使用Batch Norm时学习进行得更快。同时也可以发现,实际上,在不使用Batch Norm的情况下,如果不赋予一个尺度好的初始值,学习将完全无法进行。

通过使用批量归一化,可以推动学习的进行。并且,对权重初始值变得健壮(“对初始值健壮”表示不那么依赖初始值)。

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  # 为了导入父目录的文件而进行的设定
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from common.multi_layer_net_extend import MultiLayerNetExtend
from common.optimizer import SGD, Adam(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True)# 减少学习数据
x_train = x_train[:1000]
t_train = t_train[:1000]max_epochs = 20
train_size = x_train.shape[0]
batch_size = 100
learning_rate = 0.01def __train(weight_init_std):bn_network = MultiLayerNetExtend(input_size=784, hidden_size_list=[100, 100, 100, 100, 100], output_size=10,weight_init_std=weight_init_std, use_batchnorm=True)network = MultiLayerNetExtend(input_size=784, hidden_size_list=[100, 100, 100, 100, 100], output_size=10,weight_init_std=weight_init_std)optimizer = SGD(lr=learning_rate)train_acc_list = []bn_train_acc_list = []iter_per_epoch = max(train_size / batch_size, 1)epoch_cnt = 0for i in range(1000000000):batch_mask = np.random.choice(train_size, batch_size)x_batch = x_train[batch_mask]t_batch = t_train[batch_mask]for _network in (bn_network, network):grads = _network.gradient(x_batch, t_batch)optimizer.update(_network.params, grads)if i % iter_per_epoch == 0:train_acc = network.accuracy(x_train, t_train)bn_train_acc = bn_network.accuracy(x_train, t_train)train_acc_list.append(train_acc)bn_train_acc_list.append(bn_train_acc)print("epoch:" + str(epoch_cnt) + " | " + str(train_acc) + " - " + str(bn_train_acc))epoch_cnt += 1if epoch_cnt >= max_epochs:breakreturn train_acc_list, bn_train_acc_list# 3.绘制图形==========
weight_scale_list = np.logspace(0, -4, num=16)
x = np.arange(max_epochs)for i, w in enumerate(weight_scale_list):print( "============== " + str(i+1) + "/16" + " ==============")train_acc_list, bn_train_acc_list = __train(w)plt.subplot(4,4,i+1)plt.title("W:" + str(w))if i == 15:plt.plot(x, bn_train_acc_list, label='Batch Normalization', markevery=2)plt.plot(x, train_acc_list, linestyle = "--", label='Normal(without BatchNorm)', markevery=2)else:plt.plot(x, bn_train_acc_list, markevery=2)plt.plot(x, train_acc_list, linestyle="--", markevery=2)plt.ylim(0, 1.0)if i % 4:plt.yticks([])else:plt.ylabel("accuracy")if i < 12:plt.xticks([])else:plt.xlabel("epochs")plt.legend(loc='lower right')
plt.show()

背景

批量归一化(Batch Normalization)与层归一化(Layer Normalization)深度解析

什么是归一化 Normalization

在深度神经网络的训练过程中,随着网络深度的增加,模型的表征能力虽然有所提升,但也带来了许多训练上的难题。其中,梯度消失梯度爆炸是最具代表性的两个问题。早期的深层网络中常使用Sigmoid或tanh等饱和激活函数,一旦输入落入函数的饱和区(梯度接近0),梯度在层间传播时会迅速衰减;另一方面,如果网络层数较多或参数初始化不当,也有可能发生梯度的指数级增长,从而使参数更新呈现“发散”现象。

与此同时,随着网络在反向传播中不断更新,前几层的参数变化会连带影响后续层的输入分布,导致高层特征分布发生非平稳性,这种现象被称为内部协变量偏移(Internal Covariate Shift)。在网络很深或数据分布复杂的情况下,这种效应会被放大,导致网络难以收敛或需要极度细心地调整超参数。

归一化(Normalization)技术正是在这样的背景下逐渐兴起的。它的核心思想是,无论网络有多深,都希望每一层的输入分布尽量稳定、可控。为此,通过对每一层的激活值进行某种形式的“标准化”处理,可以使每层输入在训练中保持较为稳定的分布,即均值和方差在较短的训练迭代内不发生剧烈波动。这种操作一方面有助于缓解梯度消失和梯度爆炸;另一方面,网络也不需要时时刻刻去适应快速变化的激活分布,从而提高了学习效率并缩短训练收敛时间。

批量归一化对批量大小的依赖

BN对批量大小较为敏感,如果批量太小(例如小于16甚至更小),当前批次的均值方差容易出现大幅波动,进而导致训练不稳定或性能下降。在一些仅能使用小批量(如显存受限或序列生成任务)的场景下,BN的效果往往不及设计专门的归一化策略(例如LN、GN等)。

优缺点

优点

  • 大幅加速收敛,允许使用更高的初始学习率。
  • 有一定正则化作用,降低对初始权重的敏感性,减少过拟合。
  • 在主流图像任务和大型批量训练的场景下表现卓越。

缺点

  • 依赖足够大的批量尺寸,否则会导致估计方差不稳定。
  • 在序列模型(如RNN、Transformer等)或者小批量场景中表现不佳。
  • 在分布式训练时,计算全局均值与方差可能比较麻烦,需要额外同步开销。
http://www.lryc.cn/news/2378978.html

相关文章:

  • SVGPlay:一次 CodeBuddy 主动构建的动画工具之旅
  • 自己手写tomcat项目
  • 2025年渗透测试面试题总结-安恒[实习]安全工程师(题目+回答)
  • 生成对抗网络(Generative Adversarial Networks ,GAN)
  • 六、磁盘划分与磁盘配额
  • 在WSL中的Ubuntu发行版上安装Anaconda、CUDA、CUDNN和TensorRT
  • 小刚说C语言刷题—1230蝴蝶结
  • 代码随想录算法训练营第60期第三十九天打卡
  • 计算机网络体系结构深度解析:从理论到实践的全面梳理
  • Qwen2.5-VL模型sft微调和使用vllm部署
  • python打卡DAY22
  • 【教程】Docker更换存储位置
  • 鸿蒙Next API17学习新特性之组件可见区域变化事件新增支持设置事件的回调参数,限制它的执行间隔
  • AI大模型从0到1记录学习 mysql day23
  • spring -MVC-02
  • 深入解析 React 的 useEffect:从入门到实战
  • 通过Ollama读取模型
  • C#控制流
  • 永久免费,特殊版本!
  • Canva 推出自有应用生成器以与 Bolt 和 Lovable 竞争
  • Matrix-Game:键鼠实时控制、实时生成的游戏生成模型(论文代码详细解读)
  • MySQL 5.7在CentOS 7.9系统下的安装(下)——给MySQL设置密码
  • 机器学习笔记2
  • AgentCPM-GUI,清华联合面壁智能开源的端侧GUI智能体模型
  • Go语言实现链式调用
  • 重排序模型解读 mxbai-rerank-base-v2 强大的重排序模型
  • 期望是什么:(无数次的均值,结合概率)21/6=3.5
  • uniapp-vue3项目中引入高德地图的天气展示
  • 容器化-k8s-介绍及下载安装教程
  • lc42接雨水