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

上海cms建站今日最新足球推荐

上海cms建站,今日最新足球推荐,wordpress自定义的注册,天津建委网站 官网目录 一、BN层介绍 1、深层神经网络存在的问题 2、批量归一化公式的数学推导 3、BN层的作用位置 4、 预测过程中的批量归一化 5、BN层加速模型训练的原因 6、总结 二、批量归一化从零实现 1、实现批量归一化操作 2、创建BN层 3、对LeNet加入批量归一化 4、开始训练…

目录

一、BN层介绍

1、深层神经网络存在的问题

2、批量归一化公式的数学推导

3、BN层的作用位置

4、 预测过程中的批量归一化

5、BN层加速模型训练的原因

6、总结

二、批量归一化从零实现

1、实现批量归一化操作

2、创建BN层 

3、对LeNet加入批量归一化

4、开始训练 

三、简明实现

1、对LeNet加入批量归一化

2、开始训练 


一、BN层介绍

       批量归一化(Batch Normalization)是一种用于深度神经网络的常用技术,旨在加快模型的训练速度、提高模型的稳定性和泛化能力。

1、深层神经网络存在的问题

       在深度神经网络中,反向传播算法用于计算网络参数的梯度,以便通过梯度下降等优化算法来更新参数。损失函数在神经网络的上层计算损失,梯度在反向传播过程中会逐层传递,通过链式法则计算每一层的梯度,就导致上层梯度大而下层梯度小。当网络层数很深时,梯度在传递过程中可能会变得非常小,甚至趋近于零,这就是梯度消失问题。

       梯度消失问题会导致深层网络的参数难以更新,因为梯度信息无法有效地传播回浅层网络。这会导致浅层网络的参数在训练过程中几乎不会得到更新,导致收敛速度较慢,从而影响了整个网络的训练效果。

2、批量归一化公式的数学推导

       请注意,我们在方差估计值中添加一个小的常量 $\epsilon > 0$,以确保我们永远不会尝试除以零。应用标准化($ \frac{x_i-\mu _B}{\sigma _B} $)后,生成的小批量的平均值为0和单位方差为1。由于单位方差是一个主观的选择,因此需要重新学习一个新的拉伸参数(scale) $ \gamma $ 和偏移参数(shift) $ \beta $

       因此$ x_i $的均值为$ \mu _B $,方差为$ \sigma _{B}^{2} $

$ Average\left( \frac{x_i-\mu _B}{\sigma _B} \right) =\mu _{B}^{'}=\frac{1}{\left| B \right|}\sum_{i\in B}{\frac{x_i-\mu _B}{\sigma _B}=}\frac{1}{\left| B \right|}\sum_{i\in B}{\frac{\left( x_1+x_2+...+x_B \right) -\mu _B\times B}{\sigma _B}=0} $

$ Variance\left( \frac{x_i-\mu _B}{\sigma _B} \right) =\sigma _{B}^{'2}=\frac{1}{\left| B \right|}\sum_{i\in B}{\left( \frac{x_i-\mu _B}{\sigma _B}-\mu _{B}^{'} \right) ^2=}\frac{1}{\left| B \right|}\sum_{i\in B}{\left( \frac{x_i-\mu _B}{\sigma _B}-0 \right) ^2=\frac{1}{\left| B \right|}\sum_{i\in B}{\frac{\left( x_i-\mu _B \right) ^2}{\sigma _{B}^{2}}=}}\dfrac{\left( \frac{1}{\left| B \right|}\sum_{i\in B}{\left( x_i-\mu _B \right) ^2} \right)}{\sigma _{B}^{2}}=1 $

       因此$ \frac{x_i-\mu _B}{\sigma _B} $的均值为0,方差为1。

$ Average\left( \gamma \frac{x_i-\mu _B}{\sigma _B}+\beta \right) =\mu _{B}^{''}=\frac{1}{\left| B \right|}\sum_{i\in B}{\left( \gamma \frac{x_i-\mu _B}{\sigma _B}+\beta \right) =\frac{\gamma}{\left| B \right|}\sum_{i\in B}{\frac{x_i-\mu _B}{\sigma _B}+\beta =\gamma \times \mu _{B}^{'}+\beta =\beta}} $

$ Variance\left( \gamma \frac{x_i-\mu _B}{\sigma _B}+\beta \right) =\sigma _{B}^{''2}=\frac{1}{\left| B \right|}\sum_{i\in B}{\left( \gamma \frac{x_i-\mu _B}{\sigma _B}+\beta -\mu _{B}^{''} \right) ^2=\frac{\gamma ^2}{\left| B \right|}\sum_{i\in B}{\frac{\left( x_i-\mu _B \right) ^2}{\sigma _{B}^{2}}=\gamma ^2}} $

       因此$ \gamma \frac{x_i-\mu _B}{\sigma _B}+\beta $的均值为$ \beta $,方差为$ \gamma ^2 $

样本减去其均值后除以方差的操作被称为标准化或归一化。这种操作常用于统计分析和机器学习中。

3、BN层的作用位置

4、 预测过程中的批量归一化

       批量规一化在训练模式和预测模式下的行为通常不同。在预测模式下,我们使用训练时得到的移动平均均值(moving_mean)和方差(moving_var)来进行归一化,而不是使用验证集的数据重新计算。批量归一化在训练模式和预测模式下的行为不同,这一点和暂退法(丢弃法)有点像。

5、BN层加速模型训练的原因

       批量归一化(Batch Normalization)在深度学习中能够加快模型训练速度的原因主要有以下几点:

       缓解梯度消失问题:在深层神经网络中,梯度消失是一个常见的问题,导致较深层的梯度信息无法有效地传播回浅层网络。批量归一化通过对每一层的输入进行标准化,使得输入数据的均值接近0,方差接近1,从而使得激活函数的输入范围更加适中,避免了输入数据过大或过小,激活函数在其有效范围内具有较大的导数值,从而使得梯度能够更好地通过网络传播。这样,即使在深层网络中,梯度仍然可以有效地反向传播,从而保持参数的更新,缓解梯度消失问题,加速模型的训练过程。

       加速收敛:批量归一化通过标准化每一层的输入,将数据分布调整为接近标准正态分布,使得网络的参数更容易学习。这有助于加快模型的收敛速度,减少训练的迭代次数,从而加速模型的训练过程。

       增加学习率:批量归一化使得网络中的各层输入具有相对较小的变化范围,从而增加了模型对学习率的鲁棒性。较大的学习率可以加速模型的收敛,同时避免了因为学习率过大导致的不稳定性。

       正则化效果:批量归一化本质上对每一层的输入进行了规范化处理,类似于一种正则化的效果。它在一定程度上减少了模型对输入数据的依赖,增强了模型的泛化能力,有助于防止过拟合。

       总的来说,批量归一化通过标准化每一层的输入数据,缓解梯度消失问题,加快模型的收敛速度,增加学习率和正则化效果,从而有效地加快模型的训练速度。

6、总结

  • 批量归一化固定小批量中的均值和方差,然后学习出适合的偏移和缩放
  • 可以加速收敛速度,但一般不改变模型精度 

二、批量归一化从零实现

1、实现批量归一化操作

       下面,我们从头开始实现一个具有张量的批量规范化层。

import torch
from torch import nn
from d2l import torch as d2ldef batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum): # X:输入  gamma,beta:可学习参数γ,β  moving_mean,moving_var:全局均值和方差,做推理时用  eps:避免除0的东西  momentum:用来更新γ,β的参数# 通过is_grad_enabled来判断当前模式是训练模式还是预测模式if not torch.is_grad_enabled():# 如果是在预测模式下,直接使用传入的移动平均所得的均值和方差X_hat = (X - moving_mean) / torch.sqrt(moving_var + eps)else:assert len(X.shape) in (2, 4)   # 等于2的话就是全连接层,等于4的话就是卷积层if len(X.shape) == 2:# 使用全连接层的情况,计算特征维上的均值和方差mean = X.mean(dim=0)    # 二维的话第一维是批量大小(行),第二维是特征(列),dim=0表示每一列算出一个均值var = ((X - mean) ** 2).mean(dim=0)else:# 使用二维卷积层的情况,计算通道维上(axis=1)的均值和方差。# 这里我们需要保持X的形状以便后面可以做广播运算mean = X.mean(dim=(0, 2, 3), keepdim=True)var = ((X - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True)# 训练模式下,用当前的均值和方差做标准化X_hat = (X - mean) / torch.sqrt(var + eps)# 更新移动平均的均值和方差moving_mean = momentum * moving_mean + (1.0 - momentum) * meanmoving_var = momentum * moving_var + (1.0 - momentum) * varY = gamma * X_hat + beta  # 缩放和移位return Y, moving_mean.data, moving_var.data

       momentum 是一个介于 0 和 1 之间的超参数,用于控制移动平均的更新速度。在批量归一化中,为了减少每个批次数据的波动对均值和方差的影响,通常会计算移动平均的均值和方差。这样可以提供更稳定的均值和方差估计,从而使得批量归一化在测试阶段也能够起到归一化的效果。在测试阶段,使用移动平均的均值和方差来对数据进行归一化,以保持与训练阶段的一致性。

       self.moving_mean 和 self.moving_var 需要在前向传播过程中与输入数据 X 在相同的设备上进行计算,所以需要使用 .to(X.device) 进行设备转移操作。而 self.gamma 和 self.beta 是可学习参数,已经被定义为 nn.Parameter,会自动根据模型所在的设备进行初始化,所以不需要额外的设备转移操作。 

       在全连接层中,输入数据的维度通常为两个,分别是:

  • 批量大小(Batch Size):表示一次输入的样本数量,即一批数据的大小。通常用于同时处理多个样本,以利用并行计算的优势。
  • 特征维度(Feature Dimension):表示每个样本在全连接层中的特征表示。这个维度的大小可以根据任务和网络设计进行调整,通常是通过将输入数据展平(flatten)为一维向量来实现。展平操作将多维的输入数据转换为一维的特征向量,作为全连接层的输入。

       例如,如果输入数据的维度为[batch_size, num_features],其中batch_size表示批量大小,num_features表示每个样本的特征维度,那么全连接层的两个维度就分别是batch_size和num_features。

2、创建BN层 

       我们现在可以创建一个正确的`BatchNorm`层。这个层将保持适当的参数:拉伸`gamma`和偏移`beta`,这两个参数将在训练过程中更新。此外,我们的层将保存均值和方差的移动平均值,以便在模型预测期间随后使用。

       撇开算法细节,注意我们实现层的基础设计模式。通常情况下,我们用一个单独的函数定义其数学原理,比如说`batch_norm`。然后,我们将此功能集成到一个自定义层中,其代码主要处理数据移动到训练设备(如GPU)、分配和初始化任何必需的变量、跟踪移动平均线(此处为均值和方差)等问题。为了方便起见,我们并不担心在这里自动推断输入形状,因此我们需要指定整个特征的数量。

class BatchNorm(nn.Module):# num_features:全连接层的输出数量或卷积层的输出通道数。# num_dims:2表示完全连接层,4表示卷积层def __init__(self, num_features, num_dims):super().__init__()if num_dims == 2:shape = (1, num_features)   # (batch_size, num_features)else:shape = (1, num_features, 1, 1) # (batch_size, channel, height, width)# 参与求梯度和迭代的拉伸和偏移参数,分别初始化成1和0self.gamma = nn.Parameter(torch.ones(shape))self.beta = nn.Parameter(torch.zeros(shape))# 非模型参数的变量初始化为0和1self.moving_mean = torch.zeros(shape)self.moving_var = torch.ones(shape)def forward(self, X):# 如果X不在内存上,将moving_mean和moving_var# 复制到X所在显存上if self.moving_mean.device != X.device:self.moving_mean = self.moving_mean.to(X.device)self.moving_var = self.moving_var.to(X.device)# 保存更新过的moving_mean和moving_var,等待下一个批量进来继续更新,直到整个训练过程完全结束Y, self.moving_mean, self.moving_var = batch_norm(X, self.gamma, self.beta, self.moving_mean,self.moving_var, eps=1e-5, momentum=0.9)    # 预测模式下不更新self.moving_mean和self.moving_var,只在训练模式下更新return Y

       在PyTorch中,nn.Parameter是一个特殊的张量,它被用作模型的可学习参数。当我们使用nn.Parameter包装一个张量时,PyTorch会自动将其标记为模型参数,使得在模型的训练过程中可以对其进行自动求导和更新。

       在这段代码中,self.gamma和self.beta是可学习参数,它们用于缩放(gamma)和偏移(beta)归一化后的数据。因此,我们需要使用nn.Parameter将这两个张量标记为模型参数,以便可以对它们进行自动求导和更新。

       而self.moving_mean和self.moving_var是批量归一化层中的非模型参数。它们用于保存移动平均的均值和方差,在训练过程中会被更新。但是它们不是模型的可学习参数,因此不需要使用nn.Parameter进行标记。

3、对LeNet加入批量归一化

       为了更好理解如何应用`BatchNorm`,下面我们将其应用于LeNet模型。批量规范化是在卷积层或全连接层之后、相应的激活函数之前应用的。

net = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5), BatchNorm(6, num_dims=4), nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6, 16, kernel_size=5), BatchNorm(16, num_dims=4), nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2), nn.Flatten(),nn.Linear(16*4*4, 120), BatchNorm(120, num_dims=2), nn.Sigmoid(),nn.Linear(120, 84), BatchNorm(84, num_dims=2), nn.Sigmoid(),nn.Linear(84, 10))

4、开始训练 

       和以前一样,我们将在Fashion-MNIST数据集上训练网络。这个代码与我们第一次训练LeNet时几乎完全相同,主要区别在于学习率大得多。

lr, num_epochs, batch_size = 1.0, 10, 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
loss 0.273, train acc 0.899, test acc 0.807
32293.9 examples/sec on cuda:0

       让我们来看看从第一个批量规范化层中学到的拉伸参数`gamma`和偏移参数`beta`。

net[1].gamma.reshape((-1,)), net[1].beta.reshape((-1,))
(tensor([0.4863, 2.8573, 2.3190, 4.3188, 3.8588, 1.7942], device='cuda:0',grad_fn=<ReshapeAliasBackward0>),tensor([-0.0124,  1.4839, -1.7753,  2.3564, -3.8801, -2.1589], device='cuda:0',grad_fn=<ReshapeAliasBackward0>))

三、简明实现

1、对LeNet加入批量归一化

       除了使用我们刚刚定义的`BatchNorm`,我们也可以直接使用深度学习框架中定义的`BatchNorm`。该代码看起来几乎与我们上面的代码相同。

net = nn.Sequential(nn.Conv2d(1, 6, kernel_size=5), nn.BatchNorm2d(6), nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2),nn.Conv2d(6, 16, kernel_size=5), nn.BatchNorm2d(16), nn.Sigmoid(),nn.AvgPool2d(kernel_size=2, stride=2), nn.Flatten(),nn.Linear(256, 120), nn.BatchNorm1d(120), nn.Sigmoid(),nn.Linear(120, 84), nn.BatchNorm1d(84), nn.Sigmoid(),nn.Linear(84, 10))

2、开始训练 

       下面,我们使用相同超参数来训练模型。通常高级API变体运行速度快得多,因为它的代码已编译为C++或CUDA,而我们的自定义代码由Python实现。

d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())
loss 0.267, train acc 0.902, test acc 0.708
50597.3 examples/sec on cuda:0

http://www.dinnco.com/news/48358.html

相关文章:

  • 四川省乐山市建设银行网站国际机票搜索量大涨
  • 影响网站alexa排名的主要因素有怎么做个人网页
  • 高端网站建设公司报价国内疫情最新情况
  • 安徽建设厅网站证件查询seo刷排名公司
  • 有没有专业做电视测评的网站免费正能量erp软件下载
  • 成功的网站应该具备哪些要素网站推广怎么弄
  • 重庆网站建设哪家公司那家好百度网站收录提交入口
  • 网站页面一般以多大标准做合适百度搜索引擎优化方案
  • 网站后台如何更换在线qq咨询代码百度seo排名优化助手
  • 常德网站seo58同城网站推广
  • wordpress html5 音乐网络推广seo怎么弄
  • 提升网站权重的策略seo关键词优化案例
  • 株洲seo优化西安网站seo技术
  • 用ps做招生网站扬州网络推广哪家好
  • wordpress口塞百度关键词优化策略
  • 秦皇岛公司做网站拉新app推广平台
  • 网站开发群电商培训班一般多少钱一个月
  • wordpress搭建服务器如何seo网站推广
  • 广州网站制作公司联系方式seo交互论坛
  • wordpress 建立网站做网店自己怎么去推广
  • 石家庄建站程序seo是广告投放吗
  • 网站数据库查询怎么做的自建网站平台有哪些
  • 设计公司网站需要考虑什么谷歌在线浏览器入口
  • 自己电脑上做网站北京网站营销与推广
  • 有网站如何做app友情链接方面pr的选择应该优先选择的链接为
  • 帮别人做网站开票开什么税目网站关键词优化价格
  • 网站建设质量保证免费发布广告的网站
  • 网站的企业风采怎么做网络推广方式有哪几种
  • 做怎么样的自己的网站搜索引擎优化教材答案
  • 成都网站建设推广对网站提出的优化建议