28 批量归一化【李沐动手学深度学习v2课程笔记】(备注:这一节讲的很迷惑,很乱)

目录

1.批量归一化

1.1训练神经网络时出现的挑战

1.2核心思想

1.3原理

2.批量规范化层

2.1 全连接层

2.2 卷积层

2.3 总结

3. 代码实现

4. 使用批量规范化层的LeNet

5. 简明实现


1.批量归一化

现在主流的卷积神经网络几乎都使用了批量归一化
批量归一化是一种流行且有效的技术,它可以持续加速深层网络的收敛速度

1.1训练神经网络时出现的挑战

1、数据预处理的方式通常会对最终结果产生巨大影响

使用真实数据时,第一步是标准化输入特征(使其均值为0,方差为1),这种标准化可以很好地与优化器配合使用(可以将参数的量级进行统一)


2、对于典型的多层感知机或卷积神经网络,在训练时中间层中的变量可能具有更广的变化范围

不论是沿着从输入到输出的层、跨同一层中的单元、或是随着时间的推移,模型参数的随着训练更新变化莫测
归一化假设变量分布中的不规则的偏移可能会阻碍网络的收敛


3、更深层的网络很复杂,容易过拟合

这就意味着正则化变得更加重要 作者:如果我是泡橘子 

当神经网络比较深的时候会发现:数据在下面,损失函数在上面,这样会出现什么问题?

正向传递的时候,数据是从下往上一步一步往上传递;反向传递的时候,数据是从上面往下传递,这时候就会出现问题:梯度在上面的时候比较大,越到下面就越容易变小(因为是n个很小的数进行相乘,越到后面结果就越小,也就是说越靠近数据的,层的梯度就越小)


上面的梯度比较大,那么每次更新的时候上面的层就会不断地更新;但是下面层因为梯度比较小,所以对权重地更新就比较少,这样的话就会导致上面的收敛比较快,而下面的收敛比较慢,这样就会导致底层靠近数据的内容(网络所尝试抽取的网络底层的特征:简单的局部边缘、纹理等信息)变化比较慢,上层靠近损失的内容(高层语义信息)收敛比较快,所以每一次底层发生变化,所有的层都得跟着变(底层的信息发生变化就导致上层的权重全部白学了),这样就会导致模型的收敛比较慢。


所以提出了假设:能不能在改变底部信息的时候,避免顶部不断的重新训练?(这也是批量归一化所考虑的问题) 

1.2核心思想

为什么会变?因为方差和均值整个分布会在不同层之间变化

所以假设将分布固定,假设每一层的输出、梯度都符合某一分布,相对来说就是比较稳定的(具体分布可以做细微的调整,但是整体保持基本一致,这样的话,在学习细微的变动时也比较容易)

批量归一化:将不同层的不同位置的小批量(mini-batch)输出的均值和方差固定,均值和方差的计算方法如下图所示

在这个基础上做额外的调整,如下图所示 

1.3原理

2.批量规范化层

回想一下,批量规范化和其他层之间的一个关键区别是,由于批量规范化在完整的小批量上运行,因此我们不能像以前在引入其他层时那样忽略批量大小。 我们在下面讨论这两种情况:全连接层和卷积层,他们的批量规范化实现略有不同。

2.1 全连接层

2.2 卷积层

2.3 总结

3. 代码实现

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

import torch
from torch import nn
from d2l import torch as d2l


def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, 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)
        if len(X.shape) == 2:
            # 使用全连接层的情况,计算特征维上的均值和方差
            mean = X.mean(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) * mean
        moving_var = momentum * moving_var + (1.0 - momentum) * var
    Y = gamma * X_hat + beta  # 缩放和移位
    return Y, moving_mean.data, moving_var.data

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

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

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)
        else:
            shape = (1, num_features, 1, 1)
        # 参与求梯度和迭代的拉伸和偏移参数,分别初始化成1和0
        self.gamma = nn.Parameter(torch.ones(shape))
        self.beta = nn.Parameter(torch.zeros(shape))
        # 非模型参数的变量初始化为0和1
        self.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)
        return Y

4. 使用批量规范化层的LeNet

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

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))

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

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())

让我们来看看从第一个批量规范化层中学到的拉伸参数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>))

5. 简明实现

除了使用我们刚刚定义的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))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/451848.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Scrapy 爬虫框架

网络爬虫框架scrapy &#xff08;配置型爬虫&#xff09; 什么是爬虫框架&#xff1f; 爬虫框架是实现爬虫功能的一个软件结构和功能组件集合爬虫框架是个半成品&#xff0c;帮助用户实现专业网络爬虫 scrapy框架结构("52"结构) spider: 解析downloader返回的响…

【读论文】【精读】3D Gaussian Splatting for Real-Time Radiance Field Rendering

文章目录 1. What&#xff1a;2. Why&#xff1a;3. How&#xff1a;3.1 Real-time rendering3.2 Adaptive Control of Gaussians3.3 Differentiable 3D Gaussian splatting 4. Self-thoughts 1. What&#xff1a; What kind of thing is this article going to do (from the a…

传输层协议介绍(tcp,udp),可靠性和不可靠性

目录 传输层协议 介绍 tcp协议 介绍 面向连接 可靠性 面向字节流 udp协议 介绍 无连接 不可靠 面向数据报 可靠和不可靠 可靠 不可靠 传输层协议 介绍 传输层是计算机网络体系结构中的第四层&#xff0c;它负责在网络中的不同主机之间提供端到端的数据传输 传输…

ARMv8架构特殊寄存器介绍-1

1&#xff0c;ELR寄存器&#xff08;Exception Link Register &#xff09; The Exception Link Register holds the exception return address。 异常链接寄存器保存异常返回地址。最常用也很重要。 2&#xff0c;SPSR&#xff08;Saved Process Status Register&#xff09;…

PDF 文件与其他文档格式相比有哪些优势?

PDF文件与其他文档格式相比&#xff0c;具有许多明显的优势。首先&#xff0c;PDF是一种跨平台的文档格式&#xff0c;这意味着无论在哪种操作系统或设备上&#xff0c;用户都可以打开和查看PDF文件&#xff0c;而无需担心格式不兼容的问题。这种跨平台性使得PDF文件在办公、学…

Centos7安装postgresql14步骤

1、进入网址 https://www.postgresql.org/download/ 2、按步骤执行 # Install the repository RPM: sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm# Install PostgreSQL: sudo yum install -y…

基于springboot+vue的线上教育系统(源码+论文)

目录 前言 一、功能设计 二、功能实现 三、库表设计 四、论文 前言 现在大家的生活方式正在被计算机的发展慢慢改变着&#xff0c;学习方式也逐渐由书本走向荧幕,我认为这并不是不能避免的,但说实话,现在的生活方式与以往相比有太大的改变&#xff0c;人们的娱乐方式不仅仅…

PHP立体安全攻击向量:保护应用程序的关键挑战

PHP立体安全攻击向量&#xff1a;保护应用程序的关键挑战 PHP作为一种广泛使用的服务器端脚本语言&#xff0c;拥有庞大的用户群体和丰富的生态系统。然而&#xff0c;随着互联网的发展&#xff0c;网络安全问题也变得愈发严重。本文将深入探讨PHP的立体安全攻击向量&#xff0…

FPGA高端项目:FPGA基于GS2971+GS2972架构的SDI视频收发+图像缩放,提供3套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收发送本方案的SDI接收纯verilog图像缩放纯verilog多路视频拼接应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD动态字符叠加输出应用本方案的SDI接收HLS多路视频融合叠加应…

jupyter 修改文件保存位置 步骤

一、找到配置文件位置 打开Anaconda Prompt&#xff0c;输入&#xff1a; jupyter notebook --generate-config 根据得到的路径&#xff0c;以记事本方式打开配置文件 二、修改路径 在文件中输入&#xff1a; c.NotebookApp.notebook_dir E:\\deepLearning\\Jupyter_files…

SQL-2

• What have we achieved so far using SELECT ? — Retrieve data from all the rows and columns (whole table) — Retrieve data from all the rows and select columns — Retrieve data from select rows and columns • Sometimes we want to re-format the output fr…

​扩散模型(Diffusion Model)详解:直观理解、数学原理、PyTorch 实现​

在过去的大半年里&#xff0c;以Stable Diffusion为代表的AI绘画是世界上最为火热的AI方向之一。或许大家会有疑问&#xff0c;Stable Diffusion里的这个"Diffusion"是什么意思&#xff1f;其实&#xff0c;扩散模型(Diffusion Model)正是Stable Diffusion中负责生成…

【Preprocessing数据预处理】之Scaler

在机器学习中&#xff0c;特征缩放是训练模型前数据预处理阶段的一个关键步骤。不同的缩放器被用来规范化或标准化特征。这里简要概述了您提到的几种缩放器&#xff1a; StandardScaler StandardScaler 通过去除均值并缩放至单位方差来标准化特征。这种缩放器假设特征分布是正…

让生活更加精致的APP?

晚上好&#xff0c;今天博主来介绍几款帮助你条理生活的APP&#xff0c;让你的生活更加精致&#xff0c;充满仪式感。 一&#xff0e;格志日记 一款以“格子”的方式记录日记的APP&#xff0c;非常简单明了&#xff0c;用户可以依据自己的喜好&#xff0c;来自由定义或者删除格…

Qt/C++音视频开发69-保存监控pcm音频数据到mp4文件/监控录像/录像存储和回放/264/265/aac/pcm等

一、前言 用ffmpeg做音视频保存到mp4文件&#xff0c;都会遇到一个问题&#xff0c;尤其是在视频监控行业&#xff0c;就是监控摄像头设置的音频是PCM/G711A/G711U&#xff0c;解码后对应的格式是pcm_s16be/pcm_alaw/pcm_mulaw&#xff0c;将这个原始的音频流保存到mp4文件是会…

关于电脑无法开启5G频段热点的解决方案

tips:本文是本着解决校园网开热点后限速的问题的目的&#xff0c;具体情况具体对待。 1.找到设备管理器 右键该选项 2.在新弹出窗口选择首选频带 3.选择首选5GHz频带 确定之后重新连接wifi&#xff0c;重新开启热点&#xff0c;大功告成。 后记&#xff1a;在使用2.4ghz开热点…

细粒度IP定位参文2(Corr-SLG):A street-level IP geolocation method (2021年)

[2]S. Ding, F. Zhao, and X. Luo, “A street-level IP geolocation method based on delay-distance correlation and multilayered common routers,” Secur. Commun. Netw., vol. 2021, no. 1, pp. 1–10, 2021. 智能设备的地理位置可以帮助提供多媒体内容提供商和5G网络中…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的行人跌倒检测系统(深度学习+UI界面+完整训练数据集)

摘要&#xff1a;开发行人跌倒检测系统在确保老年人安全方面扮演着至关重要的角色。本篇文章详尽地阐述了如何利用深度学习技术构建一个行人跌倒检测系统&#xff0c;并附上了完整的代码实现。该系统采用了先进的YOLOv8算法&#xff0c;并对YOLOv7、YOLOv6、YOLOv5等先前版本进…

​如何使用 ArcGIS Pro 分析爆炸波及建筑

假设在某栋建筑内发生了爆炸&#xff0c;需要根据爆炸的范围分析出来波及的建筑&#xff0c;对于这一需求&#xff0c;我们可以通过ArcGIS Pro来实现&#xff0c;这里为大家介绍一下分析的方法&#xff0c;希望能对你有所帮助。 数据来源 教程所使用的数据是从水经微图中下载…

MATLAB中的矩阵的重构和重新排列

师从清风 矩阵的重构和重新排列 reshape函数 reshape函数可以改变矩阵的形状&#xff0c;其常用语法为reshape(A,m,n)或者reshape(A,[m,n]),这可以将矩阵A的形状更改为m行n列&#xff0c;前提是转化前后的两个矩阵的元素总数要相同。例如有一个矩阵A&#xff0c;它原来的大小是…
最新文章