问题的出现 Question

这个问题是我基于TensorFlow使用CNN训练MNIST数据集的时候遇到的。关键的相关代码是以下这部分:

cross_entropy = -tf.reduce_sum(y_*tf.log(y_conv))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)

学习速率是\((1e-4)\)的时候是没有问题,但是当我把学习速率调到\(0.01/0.5\)的时候,很快就会报错。

tensorflow.python.framework.errors.InvalidArgumentError: ReluGrad input is not finite. : Tensor had NaN values

分析 Analysis

学习速率 Learning Rate

于是我尝试加上几行代码,希望能把y_conv和cross_entropy的状态反映出来。

y_conv=tf.Print(y_conv,[y_conv],"y_conv: ")
cross_entropy =tf.Print(cross_entropy,[cross_entropy],"cross_entropy: ")

当learning rate \(=0.01\)时,程序会报错:

I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [3.0374929e-06 0.0059775524 0.980205...]
step 0, training accuracy 0.04
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [9.2028862e-10 1.4812358e-05 0.044873074...]
I tensorflow/core/kernels/logging_ops.cc:64] cross_entropy: [648.49146]
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [0.024463326 1.4828938e-31 0...]
step 1, training accuracy 0.2
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [2.4634053e-11 3.3087209e-34 0...]
I tensorflow/core/kernels/logging_ops.cc:64] cross_entropy: [nan]
step 2, training accuracy 0.14
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [nan nan nan...]
W tensorflow/core/common_runtime/executor.cc:1027] 0x7ff51d92a940 Compute status: Invalid argument: ReluGrad input is not finite. : Tensor had NaN values

当learning rate \(=1e-4\)时,程序不会报错。

I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [0.00056920078 8.4922984e-09 0.00033719366...]
step 0, training accuracy 0.14
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [7.0613837e-10 9.28294e-09 0.00016230672...]
I tensorflow/core/kernels/logging_ops.cc:64] cross_entropy: [439.95135]
step 1, training accuracy 0.16
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [0.031509314 3.6221365e-05 0.015359053...]
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [3.7112056e-07 1.8543299e-09 8.9234991e-06...]
I tensorflow/core/kernels/logging_ops.cc:64] cross_entropy: [436.37653]
step 2, training accuracy 0.12
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [0.015578311 0.0026688741 0.44736364...]
I tensorflow/core/kernels/logging_ops.cc:64] y_conv: [6.0428465e-07 0.0001744287 0.026451336...]
I tensorflow/core/kernels/logging_ops.cc:64] cross_entropy: [385.33765]

至此,我们可以看到,学习速率太大是产生error其中一个原因。

参考斯坦福CS 224D的Lecture Note,在训练深度神经网络的时候,出现NaN比较大的可能是因为学习速率过大,梯度值过大,产生梯度爆炸。

Refer to the lecture note of Stanford CS 224D, a precise definition of Gradient Explosion is:

During experimentation, once the gradient value grows extremely large, it causes an overflow (i.e. NaN) which is easily detectable at runtime; this issue is called the Gradient Explosion Problem.

解决方法 Solutions

  1. 适当减小学习速率 Try to decrease the learning rate.
  2. 加入Gradient clipping的方法。 Gradient clipping的方法最早是由Thomas Mikolov提出的。每当梯度达到一定的阈值,就把他们设置回一个小一些的数字。

    Refer to the lecture note of Stanford CS 224D, use gradient clipping.

To solve the problem of exploding gradients, Thomas Mikolov first introduced a simple heuristic solution that clips gradients to a small number whenever they explode. That is, whenever they reach a certain threshold, they are set back to a small number as shown in Algorithm 1.

Algorithm 1:

\(\frac{\partial E}{\partial W}\to g\)

if $ \Vert g\Vert\ge threshold$ then

\(\frac {threshold}{\Vert g\Vert} g\to g\)

end if

TensorFlow | ReluGrad input is not finite. Tensor had NaN values的更多相关文章

  1. Tensorflow 模型文件结构、模型中Tensor查看

    tensorflow训练后保存的模型主要包含两部分,一是网络结构的定义(网络图),二是网络结构里的参数值. 1.  .meta文件 .meta 文件以 "protocol buffer&qu ...

  2. tensorflow报错 tensorflow Resource exhausted: OOM when allocating tensor with shape

    在使用tensorflow的object detection时,出现以下报错 tensorflow Resource exhausted: OOM when allocating tensor wit ...

  3. 怎么在tensorflow中打印graph中的tensor信息

    from tensorflow.python import pywrap_tensorflow import os checkpoint_path=os.path.join('./model.ckpt ...

  4. Spark连续特征转化成离散特征

    当数据量很大的时候,分类任务通常使用[离散特征+LR]集成[连续特征+xgboost],如果把连续特征加入到LR.决策树中,容易造成overfit. 如果想用上连续型特征,使用集成学习集成多种算法是一 ...

  5. 用NVIDIA Tensor Cores和TensorFlow 2加速医学图像分割

    用NVIDIA Tensor Cores和TensorFlow 2加速医学图像分割 Accelerating Medical Image Segmentation with NVIDIA Tensor ...

  6. Tensorflow学习笔记2:About Session, Graph, Operation and Tensor

    简介 上一篇笔记:Tensorflow学习笔记1:Get Started 我们谈到Tensorflow是基于图(Graph)的计算系统.而图的节点则是由操作(Operation)来构成的,而图的各个节 ...

  7. [开发技巧]·TensorFlow中numpy与tensor数据相互转化

    [开发技巧]·TensorFlow中numpy与tensor数据相互转化 个人主页–> https://xiaosongshine.github.io/ - 问题描述 在我们使用TensorFl ...

  8. TensorFlow使用记录 (九): 模型保存与恢复

    模型文件 tensorflow 训练保存的模型注意包含两个部分:网络结构和参数值. .meta .meta 文件以 “protocol buffer”格式保存了整个模型的结构图,模型上定义的操作等信息 ...

  9. TensorFlowSharp入门使用C#编写TensorFlow人工智能应用

    TensorFlowSharp入门使用C#编写TensorFlow人工智能应用学习. TensorFlow简单介绍 TensorFlow 是谷歌的第二代机器学习系统,按照谷歌所说,在某些基准测试中,T ...

随机推荐

  1. ubuntu上建立本地git 和 网络 github的上传与下载

    github工具是一个很好用的工具,可以在本地建立一个git仓库,存储当前写的程序或者数据,然后通过ssh与github建立联系.具体怎么实现,下面进行介绍. 1.首先要安装git 软件 在Linux ...

  2. 【Django笔记四】Django2.0中的表单

    一.环境版本信息: 操作系统:windows10 Django版本:2.0.5 Python版本:3.6.4 Mysql版本: 5.5.53   安装mysql 二.基础信息 1.App中的模型mod ...

  3. My collage goals

    PART ONE: THE GOALS OF GRADE ONE 1, Try my best to improve my GPA ,  keep it around 4.0 2, Learn mor ...

  4. hdu_5187_zhx's contest

    Problem Description As one of the most powerful brushes, zhx is required to give his juniors n probl ...

  5. mariadb或者mysql忘记root密码

    windows======================net stop mysql #先停止mysql或者在服务管理里面停止 直接打开Windows的命令行(CMD)窗口(以管理员身份运行),输入 ...

  6. js如何生成id随机数

    有时候在我们在新增数据时,需要自动生成主键id等,就经常会遇到需要生成随机数的方法. 下面先介绍一种比较简单的生成随机数方法: //产生随机数函数 function RndNum(n){ var rn ...

  7. 百度地图定位JSP代码

    附:百度地图API:http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html#a1b0?qq-pf-to=pcqq.c2c &l ...

  8. 第2天 Java基础语法

    第2天 Java基础语法 今日内容介绍 变量 运算符 变量 变量概述 前面我们已经学习了常量,接下来我们要学习变量.在Java中变量的应用比常量的应用要多很多.所以变量也是尤为重要的知识点! 什么是变 ...

  9. C语言判断字符串是否旋转过

    //方法一 //每次左旋一次,判断旋转之后字符串是否与目标字符串是否一致 //旋转一圈 没有找到返回0 #define _CRT_SECURE_NO_WARNINGS #include<stdi ...

  10. Java线程和多线程(十二)——线程池基础

    Java 线程池管理多个工作线程,其中包含了一个队列,包含着所有等待被执行的任务.开发者可以通过使用ThreadPoolExecutor来在Java中创建线程池. 线程池是Java中多线程的一个重要概 ...