Debug系列 GroupNorm和BatchNorm出现Nan或inf的情况

Debug系列 GroupNorm和BatchNorm出现Nan或inf的情况

  • 前言
  • 这两个函数做了什么
  • 可能出现的问题
  • 解决方法
    • train和eval
    • batchsize或channel设置过小
    • 可训练参数的问题
    • 数值溢出
    • 其它的方法

前言

在复现别人论文的实验结果时,按照README乖乖做完之后,却发现损失函数的走向十分诡异,具体表现为在cifar10数据集上运行2万步以前,一切风平浪静,祥和美好,但是突然loss就全部变为nan了。令人费解。在Debug两天后,终于发现并修改了问题。令人发指。

在此记录,也希望各位以后遇到此类问题,能够快速解决提供参考。

如果你也想试试,就看这个论文 论文连接。

这两个函数做了什么

x ′ = x − u i σ i 2 + ϵ ∗ W + γ x'=\frac{x - u_i}{\sqrt{\sigma_i^2+\epsilon}}*W + \gamma x=σi2+ϵ xuiW+γ
Normalize实际上是将当前数据 x x x的分布转换为一个标准正态分布,即均值 u i = 0 u_i=0 ui=0,方差 σ i = 1 \sigma_i=1 σi=1。后面的 W , γ W,\gamma W,γ是可以训练的参数, ϵ \epsilon ϵ是为了实现数学稳定,在分母上增添的小量。

在神经网络中添加这个层,可以改变数据的分布,从而使得不同阶段数据分布相同,从而实现加速神经网络收敛,提高表达能力的效果。

需要说明的是,这两个函数会受到model.eval()和model.train()的影响。

这两个函数本身的区别在于,一个是按batch进行normalization,另一个则是按照channel进行normalization。

可能出现的问题

根据公式,我们会很容易发现,每一轮次,当前层都会计算当前数据batch中的均值和方差。那么显而易见,当数据分布不合理,或出现问题时,均值和方差有可能计算得到inf或nan。

此外为什么有时候,在训练的时候没问题,测试的时候却出现问题了呢?

还有为什么我的模型loss很好,输出却总是黑色图像呢?

为什么loss一开始很好,突然就不好了呢?

解决方法

train和eval

最容易解决的方式便是,如果发现模型只在测试中出现问题,那么不妨一直采用model.train的模式来进行预测。

batchsize或channel设置过小

这两个网络层每次计算实际上是会根据当前数据的batchsize或channel数进行的,那么过小的batchsize当然会导致算法不稳定。一般来说单GPU,batchsize定在32是一个合理的范围,而channel的话我是采用了128以上。

可训练参数的问题

这一说法的话,直接冻结参数即可,以免受到模型收敛的影响。

数值溢出

对了,这就是我最想说的!!!!

你可能会觉得奇怪,这为什么会数值溢出呢?如果没有觉得奇怪,可能大多数人都会想到,是不是 σ = 0 \sigma=0 σ=0?但是转念一想,我不是加了一个 ϵ \epsilon ϵ吗?是的,一开始我也是这么认为的。但是在经过不断Debug的过程中,发现这都不是问题的关键。

可能聪明的你猜到了,这可能与输入数据x有关,但是x怎么会导致数值溢出呢?这是因为,在Normalization的过程中,计算得到的均值和方差可能是很大的值,而这个值的大小如果一旦超过这两个变量本身能表达的最大大小,那么就会导致数值溢出,从而产生inf和nan。

这里可能与python的直觉不符,但是由于pytorch中存在 torch.float16之类的类型,其最大能表示的数值甚至不超过1e6,太抽象了。因此,需要手动将变量的type变为torch.float32以上,才能更好的计算。

如果还是不行,附以下代码,是我手写的GroupNorm,里面可以用clip强行划定 σ \sigma σ的值,从而避免出现inf,当然如果方差本来就是很大,这样clip实际上并不能使数据的分布转变为标准正态分布,但是在超不是特别多的情况下,这种clip实际上是一种妥协的方法,最差情况,即方差接近无限大,那么这样clip实际上相当于将整个GroupNorm的功能给作废。这并不影响整体模型效果,无非是GroupNorm的优良性质没了。

class GroupNorm(nn.GroupNorm):def forward(self, x):if len(x.shape) == 4:N,C,H,W = x.size()G = self.num_groupsassert C % G == 0x = x.view(N,G,-1)mean = x.mean(-1, keepdim=True)var = th.clip(x.var(-1, keepdim=True), max=1e7)x = (x-mean) / (var+self.eps).sqrt()x = x.view(N,C,H,W)else:N,C,H = x.size()G = self.num_groupsassert C % G == 0x = x.view(N,G,-1)mean = x.mean(-1, keepdim=True)var = th.clip(x.var(-1, keepdim=True), max=1e7)x = (x-mean) / (var+self.eps).sqrt()x = x.view(N,C,H)return x

其它的方法

之前看到有一个说法是可以冻结均值和方差????不知道怎么做,可以查一下。

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

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

相关文章

Windows / Linux dir 命令

Windows / Linux dir 命令 1. dir2. dir *.* > data.txt3. dir - list directory contentsReferences 1. dir 显示目录的文件和子目录的列表。 Microsoft Windows [版本 10.0.18363.900] (c) 2019 Microsoft Corporation。保留所有权利。C:\Users\cheng>dir驱动器 C 中…

线性代数:向量组的秩

目录 回顾“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2 矩阵的“秩” 及 向量组线性表示 相关特性 向量组的秩 例1 例2

@Async引发的spring循环依赖的问题,

今天发现一个很有意思的问题,正常解决项目中产生的循环依赖,是找出今天添加的注入代码,然后一个个加lazy试过去,会涉及到类中新增的注入 但是今天修改了某个serviceimpl的方法,加入了Async方法后 就发生循环依赖了 ai…

【职场经验】关于自动化用例设计的思考

为什么要设计用例? 作为质量保证(QA)人员,设计测试用例的重要性不亚于开发人员编写技术实现方案。如果实现方案设计不周,编码阶段将可能遇到许多问题;同理,如果我们未能设计测试用例,产品质量就难以得到充…

如何实现一个K8S DevicePlugin?

什么是device plugin k8s允许限制容器对资源的使用,比如CPU和内存,并以此作为调度的依据。 当其他非官方支持的设备类型需要参与到k8s的工作流程中时,就需要实现一个device plugin。 Kubernetes提供了一个设备插件框架,你可以用…

机器视觉系统选型-为什么还要选用工业光源控制器

工业光源控制器最主要的用途是给光源供电,实现光源的正常工作。 1.开关电源启动时,电压是具有波浪的不稳定电压,其瞬间峰值电压超过了LED灯的耐压值,灯珠在多次高压冲击下严重降低了使用寿命; 2.使用专用的光源控制器&…

【算法学习】搜索算法之深度优先搜索

深度优先搜索 DFS 1.算法介绍 深度优先搜索(DFS)算法是一种用于遍历或搜索树或图的算法。它的基本思想是尽可能深地搜索图的分支,直到到达叶节点或无法再深入为止,然后回溯到前一个节点,继续探索其他分支。这种搜索策略可以确保图中的每个节点都被访问到,除非它是一个环。…

inBuilder低代码平台新特性推荐-第十六期

各位友友们,大家好~今天来给大家介绍一下inBuilder低代码平台社区版中的系列特性之一 —— 构件热加载! 01 概述 构件热加载指的是:构件代码修改后,无需重启应用,通过WebIDE的部署或发布工程后,即可正常调…

08-静态pod(了解即可,不重要)

我们都知道,pod是kubelet创建的,那么创建的流程是什么呐? 此时我们需要了解我们k8s中config.yaml配置文件了; 他的存放路径:【/var/lib/kubelet/config.yaml】 一、查看静态pod的路径 [rootk8s231 ~]# vim /var/lib…

代码的复用——Mixin使用例子

Mixin(混入)是一种在Sass和Vue.js等框架中常用的技术,用于分发和重用代码。以下是Sass和Vue.js中Mixin的使用举例。 在Sass中,Mixin允许你定义可以在整个样式表中重复使用的样式。以下是一个Sass中Mixin的使用例子: …

华为配置直连三层组网直接转发示例

华为配置直连三层组网直接转发示例 组网图形 图1 配置直连三层组网直接转发示例组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件扩展阅读 业务需求 企业用户接入WLAN网络,以满足移动办公的最基本需求。且在覆盖区域内移动发生漫游时&#xff…

标题:从预编译到链接:探索C/C++程序的翻译环境全貌

引言 在软件开发的世界里,我们通常会遇到两种不同的环境——翻译环境与运行环境。今天,我们将聚焦于前者,深入剖析C/C程序生命周期中至关重要的“翻译环境”,即从源代码到可执行文件这一过程中涉及的四个关键阶段:预编…

三七互娱,顺丰24春招内推

三七互娱,顺丰24春招内推 ①三七互娱 【介绍】知名上市游戏企业,24届本科及以上可投递,使用内推码,面试快人一步! 【岗位】美术设计类,运营类,游戏研发类,策划类,市场推广…

设备改造经历干扰处理

设备改造完了,终于松了口气。没过几天,客户打电话过来,刚松了的那口气立马又吊了起来。通过客户描述,感觉麻烦来了。 客户每台机器都用了4台伺服,国产某品牌的,之前就经常发生液压站压力变送器损坏、某个环节偶尔不工作等情况,通过增加滤波电路、分开走线等措施解决了。…

开发的软件如何在安卓市场上架

要在安卓市场上架开发的软件,你需要遵循一系列步骤来确保你的应用符合市场的要求和标准。以下是一个基本的上架流程: 1. 注册开发者账号 在Android安卓市场(如Google Play Store)上注册一个开发者账号。提供必要的信息&#xff…

LeetCode 算法题 (数组)存在连续3个奇数的数组

问题: 输入一个数组,并输入长度,判断数组中是否存在连续3个元素都是奇数的情况,如果存在返回存在连续3个元素都是奇数的情况,不存在返回不存在连续3个元素都是奇数的情况 例一: 输入:a[1,2,3…

数论 - 博弈论(Nim游戏)

文章目录 前言一、Nim游戏1.题目描述输入格式输出格式数据范围输入样例:输出样例: 2.算法 二、台阶-Nim游戏1.题目描述输入格式输出格式数据范围输入样例:输出样例: 2.算法 三、集合-Nim游戏1.题目描述输入格式输出格式数据范围输…

Python编程-使用OpenCV和Numpy库实现图片去水印(附代码)

目录 安装OpenCV和NumPy库 开始 读取图像 选取水印位置 删除指定位置的水印 去除并修复水印(完整代码) 优化修复方法 效果(标红区域是原水印位置) 注意 安装OpenCV和NumPy库 cv2是基于OpenCV的图像处理库,可以对图像进行腐蚀,膨胀等操作;Numpy这是一个强大的处理矩…

【C++】创建多级目录下的指定文件

文章目录 一、判断文件存在二、获取文件所在目录三、创建指定目录四、使用方法 一、判断文件存在 static bool exists(const std::string &pathname) {// 方法1 获取文件状态,若存在则可能获取成功,若不存在则一定失败struct stat st;if (stat(path…

React18原理: React核心对象之ReactElement对象和Fiber对象

React中的核心对象 在React应用中,有很多特定的对象或数据结构.了解这些内部的设计,可以更容易理解react运行原理列举从react启动到渲染过程出现频率较高,影响范围较大的对象,它们贯穿整个react运行时 如 ReactElement 对象如 Fi…