TensorFlow的Debugger调试实例

之前有翻译整理过关于TensofFlow的Debugger的简单教程,具体内容见这里。这次用自己实际的例子,来简要的做个使用介绍。

首先是代码遇到了问题,训练过程中的loss不是为nan,就是为负数,让我觉得很奇怪,但是自己去检查代码又找不到问题出在哪里,这时候就想到了TensorFlow自带的Debugger。之前也有使用过,如果在没出问题的情况下,Debugger还是比较给力的。

01 用Debugger封装需要调试的Session

首先在代码的开头需要import对应的debugger模块(官方教程喜欢import debug as tf_debug,我这里就简写了,为了省事,看个人习惯吧)

from tensorflow.python import debug as tfdbg

然后在创建完Session的对象后,用调试器的Session进行封装

# 没有调试器之前的写法with tf.Session(config=config) as sess:

# 加入调试器需要加入以下这行 sess = tfdbg.LocalCLIDebugWrapperSession(sess)

# 需要调试nan值,因此加上nan的过滤器 sess.add_tensor_filter("has_inf_or_nan", tfdbg.has_nan_or_inf)

02 调试过程

在用调试器封装好Session对象之后,就可以启动代码,运行后会看到如下界面:

图1 启动调试器

这是可以输入运行的指令(如果不清楚TensorFlow Debugger的指令,可以查看之前的教程)

r -f has_inf_or_nan

这样运行就会在有过滤器的情况下运行,并会捕获出现了过滤器指定数值的Tensor,我们这里指定的是出现了inf或者nan值的Tensor。运行后,结果如下图所示:

图2 捕获inf或nan值的Tensor

按照图中顺序,出现nan值的第一个Tensor是d_loss/Log:0,那么这个时候可以用下列指令直接查看这个Tensor的值

pt d_loss/Log:0 -a

很显然,你会在打印的数值中找到nan或者inf值,但是调试的本意并不是查看这些nan值,而是需要知道来源,因此,我们需要知道这个Tensor数据的来源,可以使用下列指令:

ni d_loss/Log:0

上述指令运行后如下图:

图3 找到nan值的来源Tensor

从结果中可以看到,这个张量有一个输入的张量Discrim/add_2,这个时候用指令pt查看下Discrim/add_2的数值,发现在调用tf.log计算前(就是输入到d_loss/Log:0节点前)的数值为-1.11897061e-05,然后调用tf.log就出现了nan,因为log计算定义域为正数。

查看数值只会知道原因,要查找来源,需要使用指令定位这个来源的数据在源码中的位置:

ni -t Discrim/add_2

命令输出的结果是一个堆栈的内容,最终可以定位到代码"D_output3 = tf.matmul(D_output2, dWeights3) + dbiases3"这行,于是发现由于输出D_output3的时候,是直接输出的,没有加sigmoid激活函数,导致输出值为负,然后在输出之前添加sigmoid激活函数,将数值映射到(0,1)区间,代码即可正确运行了。

03 总结

使用TensorFlow的Debugger并不困难,大致总结起来有这么几个流程:

1.import要使用的TensorFlow的调试模块

from tensorflow.python import debug as tfdbg

2.使用调试模块的会话对象包装原有的Session对象

with tf.Session(config=config) as sess: sess = tfdbg.LocalCLIDebugWrapperSession(sess)

3.加入异常值对应的过滤器

sess.add_tensor_filter("has_inf_or_nan", tfdbg.has_nan_or_inf)

4.运行代码,并在带过滤器的情况下运行

r -f has_inf_or_nan

5.跟踪异常值产生的节点,并找到异常值来源在源码中的位置(这个比较灵活,有些可能需要回溯几个节点,有些直接可查)

ni -t Discrim/add_2

原文发布于微信公众号 - 人工智能LeadAI(atleadai)

原文发表时间:2018-01-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏青玉伏案

PHP关于web页面交互内容

1. 学php学了有一段时间了总结总结给大家分享一下 2. PHP中的引用 第一段程序: <?php $first_name="fir...

1768
来自专栏angularejs学习篇

angularjs学习第一天笔记

    您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,...

981
来自专栏闻道于事

Java实现简单文件过滤器

输入路径查找该路径下的指定文件类型的文件 代码思路: 想要循环遍历文件夹下所有子文件夹,就要用到递归。 首先判断路径是否存在:   是:获取文件     判断是...

28610
来自专栏Java编程技术

使用包定长FixedLengthFrameDecoder解决半包粘包

由于客户端发给服务器端的是hello server,im a client字符串,该字符串占用24字节,所以在服务器端channelpipeline里面添加一个...

613
来自专栏http://www.cnblogs.com

day5-json和pickle序列化

一.json模块 序列化:把一个对象的形态改变一下,使他能够存放在文件中,或者在网络上传输,序列化也叫持久化,是把对象存储到永久介质中,这样就不会因为掉电而丢失...

34714
来自专栏alexqdjay

angularjs源码笔记(5.1)--parse

2495
来自专栏Java成神之路

【转】零基础写Java知乎爬虫之进阶篇

说到爬虫,使用Java本身自带的URLConnection可以实现一些基本的抓取页面的功能,但是对于一些比较高级的功能,比如重定向的处理,HTML标记的去除,仅...

853
来自专栏源哥的专栏

多媒体处理类

import java.io.*; import java.util.*; import javax.servlet.http.*;

561
来自专栏杂烩

spring AOP注解 原

由于程序现在要求支持多数据源,但是程序已经上线想要修改非常麻烦。于是想到用aop做个切面,执行前切换数据源。spring很多功能都支持xml和注解,这里直接使用...

401
来自专栏丑胖侠

《Drools7.0.0.Final规则引擎教程》第4章 4.1 规则文件

一个标准的规则文件的格式为已“.drl”结尾的文本文件,因此可以通过记事本工具进行编辑。规则放置于规则文件当中,一个规则文件可以放置多条规则。在规则文件当中也可...

1995

扫描关注云+社区