有效防止softmax计算时上溢出(overflow)和下溢出(underflow)的方法
《Deep Learning》(Ian Goodfellow & Yoshua Bengio & Aaron Courville)第四章「数值计算」中,谈到了上溢出(overflow)和下溢出(underflow)对数值计算的影响,并以softmax函数和log softmax函数为例进行了讲解。这里我再详细地把它总结一下。
『1』什么是下溢出(underflow)和上溢出(overflow)
实数在计算机内用二进制表示,所以不是一个精确值,当数值过小的时候,被四舍五入为0,这就是下溢出。此时如果对这个数再做某些运算(例如除以它)就会出问题。反之,当数值过大的时候,情况就变成了上溢出。
『2』softmax函数是什么
softmax函数如下:
从公式上看含义不是特别清晰,所以借用知乎上的一幅图来说明(感谢原作者):
这幅图极其清晰地表明了softmax函数是什么,一图胜千言。
『3』计算softmax函数值的问题
通常情况下,计算softmax函数值不会出现什么问题,例如,当softmax函数表达式里的所有 xi 都是一个“一般大小”的数值 c 时——也就是上图中, z1=z2=z3=c 时,那么,计算出来的函数值y1=y2=y3=1/3 。
但是,当某些情况发生时,计算函数值就出问题了:
- c 极其大,导致分子计算 ec 时上溢出
- c 为负数,且 |c| 很大,此时分母是一个极小的正数,有可能四舍五入为0,导致下溢出
『4』如何解决
所以怎样规避这些问题呢?我们可以用同一个方法一口气解决俩:
令 M=max(xi),i=1,2,⋯,n ,即 M 为所有 xi 中最大的值,那么我们只需要把计算 f(xi)的值,改为计算 f(xi−M) 的值,就可以解决上溢出、下溢出的问题了,并且,计算结果理论上仍然和 f(xi)保持一致。
举个实例:还是以前面的图为例,本来我们计算 f(z2) ,是用“常规”方法来算的:
现在我们改成:
其中, M=3 是 z1,z2,z3 中的最大值。可见计算结果并未改变。这是怎么做到的呢?通过简单的代数运算就可以参透其中的“秘密”:
通过这样的变换,对任何一个 xi,减去M之后,e 的指数的最大值为0,所以不会发生上溢出;同时,分母中也至少会包含一个值为1的项,所以分母也不会下溢出(四舍五入为0)。所以这个技巧没什么高级的技术含量。
『5』延伸问题
看似已经结案了,但仍然有一个问题:如果softmax函数中的分子发生下溢出,也就是前面所说的 c 为负数,且 |c| 很大,此时分母是一个极小的正数,有可能四舍五入为0的情况,此时,如果我们把softmax函数的计算结果再拿去计算 log,即 log softmax,其实就相当于计算 log(0) ,所以会得到 −∞ ,但这实际上是错误的,因为它是由舍入误差造成的计算错误。所以,有没有一个方法,可以把这个问题也解决掉呢?
答案还是采用和前面类似的策略来计算 log softmax 函数值:
大家看到,在最后的表达式中,会产生下溢出的因素已经被消除掉了——求和项中,至少有一项的值为1,这使得log后面的值不会下溢出,也就不会发生计算 log(0) 的悲剧。在很多数值计算的library中,都采用了此类方法来保持数值稳定。
有效防止softmax计算时上溢出(overflow)和下溢出(underflow)的方法的更多相关文章
- phpcms v9 wap手机门户站点内容页添加上一篇、下一篇的方法
PHP源码修改:打开 phpcms\modules\wap\index.php 文件找到if(!$r || $r['status'] != 99) showmessage(L('info_does_n ...
- 为什么 softmax 计算时要先减去最大值
根据 softmax 最基本的定义,计算公式如下所示: $$S_i=\frac{e^{x_i}}{\sum_j e^{x_j}}$$ 原理也很简单,将原向量变为分布的形式(和为1). 看似很美好,但是 ...
- js计算当前日期上一个月和下一个月
/** * 获取上一个月 * * @date 格式为yyyy-mm-dd的日期,如:2014-01-25 */ funct ...
- css 溢出overflow
css 溢出overflow 当一个元素被设置为固定大小,在这个元素中的内容如果超出元素的界限,就会出现溢出的现象. 通常情况下我们可以通过overflow来控制这个属性. overflow语法定义 ...
- Stack overflow 编译能通过,运行时出现Stack overflow
Stack overflow 编译能通过,运行时出现Stack overflow 大家都知道,Windows程序的内存机制大概是这样的,全局变量(局部的静态变量本质也属于此范围)存储于堆内存,该段内存 ...
- 基于Flink秒级计算时CPU监控图表数据中断问题
基于Flink进行秒级计算时,发现监控图表中CPU有数据中断现象,通过一段时间的跟踪定位,该问题目前已得到有效解决,以下是解决思路: 一.问题现象 以SQL02为例,发现本来10秒一 ...
- OpenStack-Ocata版+CentOS7.6 云平台环境搭建 — 6.在计算节点上安装并配置计算服务Nova
安装和配置计算节点这个章节描述如何在计算节点上安装和配置计算服务. 计算服务支持几种不同的 hypervisors.为了简单起见,这个配置在计算节点上使用 :KVM <kernel-based ...
- JAVA中使用浮点数类型计算时,计算精度的问题
标题 在Java中实现浮点数的精确计算 AYellow(原作) 修改 关键字 Java 浮点数 精确计算 问题的提出:如果我们编译运行下面这个程序会看到什么?publi ...
- 深度学习原理与框架-Tensorflow基本操作-mnist数据集的逻辑回归 1.tf.matmul(点乘操作) 2.tf.equal(对应位置是否相等) 3.tf.cast(将布尔类型转换为数值类型) 4.tf.argmax(返回最大值的索引) 5.tf.nn.softmax(计算softmax概率值) 6.tf.train.GradientDescentOptimizer(损失值梯度下降器)
1. tf.matmul(X, w) # 进行点乘操作 参数说明:X,w都表示输入的数据, 2.tf.equal(x, y) # 比较两个数据对应位置的数是否相等,返回值为True,或者False 参 ...
随机推荐
- struct2_拦截器知识点.
Struts2拦截器原理: Struts2拦截器的实现原理相对简单,当请求struts2的action时,Struts 2会查找配置文件,并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个 ...
- Java基础学习笔记八 Java基础语法之接口和多态
接口 接口概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的”类”.接口只描述所应该具备的方法,并没有具体实现,具体的实现由接口的实现类(相当于接口的子类)来完成.这样将功能的定义 ...
- java编程思想笔记(1)
java编程思想笔记(1) 一,对象的创建和生命周期 对象的数据位于何处?怎样控制对象的生命周期? 在堆(heap)的内存池中动态地创建对象. java完全采用了动态内存分配方式. 二,垃圾回收器 自 ...
- 网易云音乐APP分析
网易云音乐-感受音乐的力量 你选择的产品是? 网易云音乐 为什么选择该产品作为分析? 之前用的一直是QQ音乐,但是有一天一个朋友分享了一首网易云上的音乐(顺便分享一下歌名:Drop By Drop) ...
- 2017-2018-1 1623 bug终结者 冲刺007
bug终结者 冲刺007 by 20162302 杨京典 今日任务:排行榜界面 排行榜界面,选项界面 简要说明 排行榜界面用于展示用户通关是所使用的步数和时间,选项界面可以调整背景音乐的开关.选择砖块 ...
- Spring+Hibernate+Struts(SSH)框架整合
SSH框架整合 前言:有人说,现在还是流行主流框架,SSM都出来很久了,更不要说SSH.我不以为然.现在许多公司所用的老项目还是ssh,如果改成流行框架,需要成本.比如金融IT这一块,数据库dao层还 ...
- Ubuntu的软件管理与安装
感谢燕十八,的Linux的基础进阶视频 来哥:应该是装的wineQQ,它用的12年的国际版,ubuntu的这个版本应该比较好用! [3]apt-get 用Linux apt-get命令的第一步就是引入 ...
- 获取选中的radio的value值
html:<div id="bb"> <input name="cc" type="radio" value=" ...
- api-gateway实践(15)API网关的待改进点 20171207
一.API网关能力 API网关负责服务请求路由.组合及协议转换.客户端的所有请求都首先经过API网关,然后由它将请求路由到合适的微服务.API网关的客户端通过统一的网关接入微服务,在网关层处理所有的非 ...
- istio入门(01)istio的优势在哪里?
Istio能做什么?Istio 试图解决微服务实施后面临的问题.Istio 提供了一个完整的解决方案,对整个服务网格行为洞察和操作控制,以满足微服务应用程序的多样化需求. Istio在服务网络中提供了 ...