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 d2ldef 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) * meanmoving_var = momentum * moving_var + (1.0 - momentum) * varY = 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和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_varY, 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.mzph.cn/news/740246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

利用“定时执行专家”软件的25种任务与12种触发器,提升IT系统管理自动化水平

在IT系统管理中&#xff0c;自动化是提高工作效率、减少人为错误的关键。而《定时执行专家》这款软件&#xff0c;以其强大的功能、易用性和毫秒级的执行精度&#xff0c;成为了IT系统管理员的得力助手。今天&#xff0c;我们就来探讨一下如何利用这款软件的25种任务类型和12种…

Day37:安全开发-JavaEE应用JNDI注入RMI服务LDAP服务JDK绕过调用链类

目录 JNDI注入-RMI&LDAP服务 JNDI远程调用-JNDI-Injection JNDI远程调用-marshalsec JNDI-Injection & marshalsec 实现原理 JNDI注入-FastJson漏洞结合 JNDI注入-JDK高版本注入绕过 思维导图 Java知识点&#xff1a; 功能&#xff1a;数据库操作&#xff0c;文…

Fair Data Exchange:区块链实现的原子式公平数据交换

1. 引言 2024年斯坦福大学和a16z crypto research团队 论文 Atomic and Fair Data Exchange via Blockchain 中&#xff0c;概述了一种构建&#xff08;包含过期EIP-4844 blobs的&#xff09;fair data-markets的协议。该论文源自a16z crypto的暑期实习计划&#xff0c;与四名…

下载BenchmarkSQL并使用BenchmarkSQL查看OceanBase 的执行计划

下载BenchmarkSQL并使用BenchmarkSQL查看OceanBase 的执行计划 一、什么是BenchmarkSQL二、下载BenchmarkSQL三、使用BenchmarkSQL查看OceanBase 的执行计划 一、什么是BenchmarkSQL BenchmarkSQL是一个开源的数据库基准测试工具&#xff0c;可以用来评估数据库系统的性能&…

在没有推出硬盘的情况下,重启mac电脑,外接移动硬盘无法加载显示?

一、mac磁盘工具显示未装载 1.打开终端&#xff0c;输入 diskutil list查看当前硬盘列表&#xff0c;大多数时候&#xff0c;可以解决。 二、使用命令行装载硬盘 执行上面命令后&#xff0c;仍不起作用&#xff0c;则手动挂载&#xff0c;在命令行输入如下内容&#xff1a; …

pytorch激活函数

目录 1.激活函数由来2. 常见激活函数2.1 Sigmoid2.2 Tanh2.3 relu 1.激活函数由来 科学家对青蛙的神经元进行研究的时候发现&#xff0c;只有超过一定的阈值青蛙才会有反应&#xff0c;因此不能将多个输入做简单的加权平均&#xff0c;而需要一个阶梯函数也就是激活函数&#…

便携式能见度仪-关键能见度数据检测工具

TH-BN6随着科技的不断进步和应用领域的日益拓宽&#xff0c;便携式能见度仪已经成为众多行业&#xff0c;尤其是交通运输、环保监测和公共安全等领域的必备工具。这款设备以其便携性、准确性和高效性&#xff0c;在移动或狭窄的空间中实现了对能见度数据的精确测量。 一、便携式…

springboot2.x 分页查询实现(mybatis-plus+pagehelper)

基于mybatisplus使用pagehelper实现简单分页查询的功能。pagehelper仅需要把已有查询结果重新封装一下即可&#xff0c;不需要改变sql、mapper之类的。例如有xxxmaper.findall(xx)函数可以列出全部符合条件的数据。仅需要 PageHelper.startPage(pageNum, pageSize); List<E…

[vscode]将命令行参数传递给调试目标

一、简介 本文介绍了在vscode中使用cmake工具时&#xff0c;如何传递参数给编译目标的方法。 前提&#xff1a;使用vscodecmake编译C/C程序。 二、方法 在.vscode/目录下新建settings.json文件&#xff0c;并将待传底的参数写在 cmake.debugConfig里。 下面介绍了一个示例&a…

浏览器与服务器通信过程(HTTP协议)

目录 1 概念 2 常见的 web 服务器有 3 浏览器与服务器通信过程 3.1 DNS 3.2 URL 4 HTTP请求方法和应答状态码 4.1 HTTP请求报文段实例 4.2 HTTP请求方法 5 HTTP应答报头和应答状态 5.1 HTTP的应答报头结构 5.2 HTTP的应答状态 1 概念 浏览器与 web 服务器在应用层通…

LeetCode 每日一题 Day 95-101

2917. 找出数组中的 K-or 值 给你一个整数数组 nums 和一个整数 k 。让我们通过扩展标准的按位或来介绍 K-or 操作。在 K-or 操作中&#xff0c;如果在 nums 中&#xff0c;至少存在 k 个元素的第 i 位值为 1 &#xff0c;那么 K-or 中的第 i 位的值是 1 。 返回 nums 的 K-o…

不看后悔!国内外程序员接单平台大合集!带你一次性了解各个热门接单平台!

相信每个程序员都对于接单这件事&#xff0c;都或多或少的有所了解&#xff0c;程序员在网上兼职接单&#xff0c;的确是一个增加收入的有效方式&#xff0c;收入的多少&#xff0c;与程序员的个人能力也是息息相关&#xff0c;但是除此之外&#xff0c;还有一个影响收入的关键…

Vue 3中的provide和inject:跨组件通信的新方式

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

解决:chrome无痕模式下找不到插件问题

如需在 Chrome 浏览器或 ChromeOS 设备上以无痕模式使用扩展程序&#xff0c;请执行以下操作&#xff1a; 在新的无痕式窗口中&#xff0c;打开 chrome://extensions。找到要在无痕模式下使用的扩展程序。点击详情。开启在无痕模式下启用。 此时打开无痕模式&#xff0c;就能看…

(顶会)组合结构的贝叶斯优化

Bayesian Optimization of Combinatorial Structures 1.摘要 本文提出了一个算法(BOCS)&#xff0c;它基于一个自适应的、可扩展的模型&#xff0c;即使数据稀缺&#xff0c;也能识别有用的组合结构。我们的采集函数率先使用半定编程来实现效率和可伸缩性。实验结果表明&#…

Oracle Primavera P6 数据库升级

前言 为了模拟各种P6测试&#xff0c;我常常会安装各种不同版本的p6系统&#xff0c;无论是P6服务&#xff0c;亦或是P6客户端工具Professional&#xff0c;在今天操作p6使用时&#xff0c;无意识到安装在本地的P6 数据库&#xff08;21.12&#xff09;出现了与Professional软…

教你用两种方式遍历循环python中的字典

开发中经常会用到对于字典、列表等数据的循环遍历&#xff0c;但是python中对于字典的遍历对于很多初学者来讲非常陌生&#xff0c;今天就来讲一下python中字典的循环遍历的两种方式。 注意&#xff1a; python2和python3中&#xff0c;下面两种方法都是通用的。 1. 只对键的…

docker容器镜像管理+compose容器编排(持续更新中)

目录 一、 Docker的基本组成 二、 容器和镜像的关系 2.1 面向对象角度 2.2 从镜像容器角度 三、 容器命令 3.1 使用Ubuntu 3.1.1 下载镜像 3.1.2 新建和启动容器 run 3.1.3交互式 compose编排与部署 1. docker-compose部署 2. docker-compose.yml模板 …

力扣刷题Days16(js)-67二进制求和

目录 1,题目 2&#xff0c;代码 2.1转换进制数 2.2模拟加法 3&#xff0c;学习与总结 Math.floor() 模拟加法思路回顾 重点复习巩固 模拟加法的思路和学习位运算&#xff1b; 今天没精力了&#xff0c;先休息 1,题目 给你两个二进制字符串 a 和 b &#xff0c;以二进制…

软考高级:统计过程阶段和工作流概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…