之前在TensorFlow中实现不同的神经网络,作为新手,发现经常会出现计算的loss中,出现Nan值的情况,总的来说,TensorFlow中出现Nan值的情况有两种,一种是在loss中计算后得到了Nan值,另一种是在更新网络权重等等数据的时候出现了Nan值,本文接下来,首先解决计算loss中得到Nan值的问题,随后介绍更新网络时,出现Nan值的情况。

Loss计算中出现Nan

在搜索以后,找到StackOverflow上找到大致的一个解决办法(原文地址:https://stackoverflow.com/questions/33712178/tensorflow-nan-bug),大致的解决办法就是,在出现Nan值的loss中一般是使用的TensorFlow的log函数,然后计算得到的Nan,一般是输入的值中出现了负数值或者0值,在TensorFlow的官网上的教程中,使用其调试器调试Nan值的出现,也是查到了计算log的传参为0;而解决的办法也很简单,假设传参给log的参数为y,那么在调用log前,进行一次数值剪切,修改调用如下:

loss = tf.log(tf.clip_by_value(y,1e-8,1.0))

这样,y的最小值为0的情况就被替换成了一个极小值,1e-8,这样就不会出现Nan值了,StackOverflow上也给出了相同的解决方案。于是,我就采用了上述的解决方案对于log的参数进行数值限制,但是我更加复杂化了这个限制。

tf.clip_by_value这个函数,是将第一个参数,限制在第二、三个参数指定的范围之内,使用这个函数的原意是要避免0值,并没有限制最大值,因而我将限制的调用修改如下:

loss = tf.log(tf.clip_by_value(y,1e-8,tf.reduce_max(y)))

这样就确保了对于y值的剪切,不会影响到其数值的上限。但是在实际的神经网络中使用的时候,我发现这样修改后,虽然loss的数值一直在变化,可是优化后的结果几乎是保持不变的,这就存在问题了。

经过检查,其实并不能这么简单的为了持续训练,而修改计算损失函数时的输入值。这样修改后,loss的数值很可能(存在0的话确定就是)假的数值,会对优化器优化的过程造成一定的影响,导致优化器并不能正常的工作。

要解决这个假的loss的方法很简单,就是人为的改造神经网络,来控制输出的结果,不会存在0。这就需要设计好最后一层输出层的激活函数,每个激活函数都是存在值域的,详情请见博客http://www.jianshu.com/p/ffd3e63f39ef,比如要给一个在(0,1)之间的输出(不包含0),那么显然sigmoid是最好的选择。不过需要注意的是,在TensorFlow中,tf.nn.sigmoid函数,在输出的参数非常大,或者非常小的情况下,会给出边界值1或者0的输出,这就意味着,改造神经网络的过程,并不只是最后一层输出层的激活函数,你必须确保自己大致知道每一层的输出的一个范围,这样才能彻底的解决Nan值的出现。

举例说明就是TensorFlow的官网给的教程,其输出层使用的是softmax激活函数,其数值在[0,1],这在设计的时候,基本就确定了会出现Nan值的情况,只是发生的时间罢了。

更新网络时出现Nan

更新网络中出现Nan值很难发现,但是一般调试程序的时候,会用summary去观测权重等网络中的值的更新,因而,此时出现Nan值的话,会报错类似如下:

InvalidArgumentError (see above for traceback): Nan in summary histogram for: weight_1

这样的情况,一般是由于优化器的学习率设置不当导致的,而且一般是学习率设置过高导致的,因而此时可以尝试使用更小的学习率进行训练来解决这样的问题。

提供一个小小的debug经验,其实是我之前遇到的很傻的坑,可能不能解决题主的问题。

log(0)
log(0) * 0

当网络训练到达一定程度的时候,模型对分类的判断可能会产生0这样的数值,log(0)本身是没有问题的,-inf可以安全的参与绝大部分运算,除了(-inf * 0),会产生NaN。NaN的话,一旦参与reduce运算会让结果完蛋的… 因此呢,如果有

y_truth * log(y_predict)
# when y_truth[i] is 0, it is likely that y_predict[i] would be 0

这样的表达式,要考虑对log中的变量进行clip. 比如

safe_log = tf.clip_by_value(some_tensor, 1e-10, 1e100)
bin_tensor * tf.log(safe_log)

这种错误实在有点傻,不过坑了我好几个小时。并且呢,这样的错误十分肯定会造成断崖式下跌。 希望对题主有所帮助。(不然就当做我的一次笔记吧~)

当然除了log函数之外,exp也是产生NaN的大户,也要多加防范。

神经网络出现nan原因?以及解决的更多相关文章

  1. [Python Debug]Kernel Crash While Running Neural Network with Keras|Jupyter Notebook运行Keras服务器宕机原因及解决方法

    最近做Machine Learning作业,要在Jupyter Notebook上用Keras搭建Neural Network.结果连最简单的一层神经网络都运行不了,更奇怪的是我先用iris数据集跑了 ...

  2. SVN 错误 Access to SVN Repository Forbidden的原因及解决方法

    原创文章,转载请注明出处:http://www.cnblogs.com/baipengzhan/p/SVN_Access_to_SVN_Repository_Forbidden.html   当我们新 ...

  3. coreseek常见错误原因及解决方法

    coreseek常见错误原因及解决方法 Coreseek 中文全文检索引擎 Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和 ...

  4. RDS MySQL 空间问题的原因和解决

    来源:https://help.aliyun.com/knowledge_detail/41739.html RDS MySQL 空间问题的原因和解决 更新时间:2016-07-22 17:20:14 ...

  5. .NET 3.5 安装错误的四个原因及解决方法

    .net framework 3.5 安装错误的四个常见原因及解决方法,飓风软件站整理,转载请注明. 1.清除所有版本 .NET Framework  安装错误后在系统中遗留的文件: 如果您以往安装过 ...

  6. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

  7. Java ConcurrentModificationException异常原因和解决方法

    Java ConcurrentModificationException异常原因和解决方法 在前面一篇文章中提到,对Vector.ArrayList在迭代的时候如果同时对其进行修改就会抛出java.u ...

  8. 关于Node.js的httpClieint请求报错ECONNRESET的原因和解决措施

    背景说明 最近在工作项目中有下面一个场景: 使用Node.js的express框架实现了一个文件系统服务器端,其中有个API用于客户端上传文件.客户端使用Node.js的HttpClient来调用服务 ...

  9. 各种编码问题产生原因以及解决办法---------响应编码,请求编码,URL编码

     响应编码 产生原因以及解决办法: 示例: package cn.yzu; import java.io.IOException; import javax.servlet.ServletExcept ...

随机推荐

  1. Kong管理UI -kong-dashboard (附kong封装webservice方法)

    本文仍然是在centos 6.7的环境下进行                 本文转载请注明出处 —— xiaoEight btw如果要正常使用管理UI,前提为kong已经正常run(可参考)起来,此 ...

  2. IE6 CSS高度height:100% 无效解决方法总结

    原文地址:http://www.cnblogs.com/huangyong8585/archive/2013/02/05/2893058.html   上面红色部分为 height:100%; 自动拉 ...

  3. ubuntu14.04 login loop issue

    无法进入图形界面的所有问题几乎都碰到了,可惜尝试所有办法,还是各种broken packages 等,无法重装 ubuntu-desktop 成功. 耽误了2天,果断决定重装系统算了..尽管很多软件, ...

  4. [UE4]C++ STL总结

    STL概述 STL (Standard Template Library, 标准模板库) 是惠普实验室开发的一系列软件的统称.主要核心分为三大部分:容器(container).算法(algorithm ...

  5. Mysql 於lampp xampp LinuxUbuntu下的配置

    默认执行Lampp/Xampp 於Ubuntu下完成后,需要对mysql进行一系列的配置,方可进行更好的操作 lampp下的mysql配置文件路径: /opt/lampp/etc/my.cnf 1 配 ...

  6. Nexus3 仓库搭建(基于Docker)

    Nexus Repository OSS 支持的仓库类型 安装方法(使用docker) 命令: sudo docker run -d \ --name nexus3 \ --restart=alway ...

  7. 【BZOJ】1013 [JSOI2008]球形空间产生器sphere(高斯消元)

    题目 传送门:QWQ 分析 高斯消元就是个大暴力.... 代码 #include <bits/stdc++.h> using namespace std; ; ; int n; doubl ...

  8. 探究CSS中border-top属性的使用

    上一节我们介绍了CSS top属性的用法,那么这节关于CSS border-top属性用法学习起来就会轻松一些,border-top 简写属性把上边框的所有属性设置到一个声明中. 本文向大家描述一下C ...

  9. Jenkins邮件扩展(Email Extension插件 Windows环境)

    1.Jenkins ver. 2.107.3版本自带Email Extension插件启动后即可看到系统设置里的 Extended E-mail Notification ,如果没有请安装 2.安装过 ...

  10. uva216-枚举-简单题

    题意:n个计算机通过电缆连接,怎么连接使用的电缆最少 mmp,死wa不过,memset(vis,0,sizeof(per)),太不小心了 #include <iostream> #incl ...