因为tensorflow的图计算方式,传统的调试方式是无法进行变量值动态查看的。google提供了tensorflow的官方调试其tfdbg来进行调试工作。
现将基本使用方式概述如下:
1、在源码中用tfdbf的专属Session来封装普通Session,这个很简单,如下:
from tensorflow.python import debug as tf_debug
sess2 = tf_debug.LocalCLIDebugWrapperSession(sess1)
session1是tf普通的session, 使用LocalCLIDebugWrapperSession封装过的session2,可以替代session1来执行后续操作。
2、在控制台命令行下执行python程序,并附带--debug参数,例如:
pyton -m demo.py --debug
此时,tf将执行该demo程序,一直到代码中遇到session.run()的语句会停止。此时,tfdbg将进入debug字符界面。这是一种特殊交互方式,需配合命令与鼠标一起操作。
3、tensor张量的debug
在debug某个张量之前,需事先知道这个张量的名称。根据个人经验,这个可以在IDE下,用普通的debug模式查看该张量的名称。
知道名称后,可以用如下指令列出该张量。
lt -n 张量名
如果tfdbg找到该张量,则会以列表形式罗列出来。
找到需要查看的张量,用鼠标可以点击打开。
如下示例:
4、有时候,需要查看的张量会不存在,那么很有可能是因为程序还没执行到产生该张量的代码位置。
根据个人的使用经验,需要debug的程序往往很长,而且该debug方式不同于常见的debuger。因此,需要观察log的输出,可以用来判断程序执行到哪个位置,进而判断想要查看的张量是否已经存在。
5、常用的tfdbg指令
命令 | 语法或选项 | 说明 | 示例 |
---|---|---|---|
lt | 列出转储张量。 | lt | |
-n <name_pattern> | 列出名称符合指定正则表达式格式的转储张量。 | lt -n Softmax.* | |
-t <op_pattern> | 列出指令类型符合指定正则表达式格式的转储张量。 | lt -t MatMul | |
-f <filter_name> | 列出仅通过已注册张量过滤器的张量。 | lt -f has_inf_or_nan | |
-f <filter_name> -fenn <regex> | 列出仅通过已注册张量过滤器的张量,不包括名称符合正则表达式的节点。 | lt -f has_inf_or_nan -fenn .*Sqrt.* | |
-s <sort_key> | 按指定的 sort_key 对输出进行排序,该键可能的值为 timestamp (默认)、dump_size 、op_type 和 tensor_name 。 | lt -s dump_size | |
-r | 按相反的顺序排序。 | lt -r -s dump_size | |
pt | 输出转储张量的值。 | ||
pt <tensor> | 输出张量值。 | pt hidden/Relu:0 | |
pt <tensor>[slicing] | 使用 Numpy 样式的数组切片输出张量的子数组。 | pt hidden/Relu:0[0:50,:] | |
-a | 输出整个大张量,而不使用省略号(对于大张量来说可能需要很长时间)。 | pt -a hidden/Relu:0[0:50,:] | |
-r <range> | 突出显示属于指定数值范围的元素。可以结合使用多个范围。 | pt hidden/Relu:0 -a -r [[-inf,-1],[1,inf]] | |
-n <number> | 输出编号对应于指定转储编号(从 0 开始)的转储。具有多个转储的张量必须如此。 | pt -n 0 hidden/Relu:0 | |
-s | 包括张量的数值摘要(仅适用于布尔型和数字型(例如 int* 和 float* )的非空张量)。 | pt -s hidden/Relu:0[0:50,:] | |
-w | 使用 numpy.save() 将张量(可能已切片)的值写入 NumPy 文件 | pt -s hidden/Relu:0 -w /tmp/relu.npy | |
@[coordinates] | 转到 pt 输出中的指定元素。 | @[10,0] 或 @10,0 | |
/regex | 指定正则表达式的 less 样式搜索。 | /inf | |
/ | 滚动到下一行,其中显示所搜索的正则表达式的匹配结果(如果有的话)。 | / | |
pf | 输出 Session.run 的 feed_dict 中的一个值。 | ||
pf <feed_tensor_name> | 输出 feed 的值。另请注意,pf 命令具有 -a 、-r 和 -s 标记(未在下面列出),它们与 pt 的同名标记具有相同的语法和语义。 | pf input_xs:0 | |
eval | 评估任意 Python 和 Numpy 表达式。 | ||
eval <expression> | 评估 Python/Numpy 表达式,其中 np 表示 Numpy,调试张量名称用反引号引起来。 | eval "np.matmul((`output/Identity:0` / `Softmax:0`).T, `Softmax:0`)" | |
-a | 输出很长的完整评估结果,即不使用省略号。 | eval -a 'np.sum(`Softmax:0`, axis=1)' | |
-w | 使用 numpy.save() 将评估结果写入 NumPy 文件 | eval -a 'np.sum(`Softmax:0`, axis=1)' -w /tmp/softmax_sum.npy | |
ni | 显示节点信息。 | ||
-a | 在输出中包含节点属性。 | ni -a hidden/Relu | |
-d | 列出节点中的调试转储。 | ni -d hidden/Relu | |
-t | 显示节点创建的 Python 堆栈追踪。 | ni -t hidden/Relu | |
li | 列出节点的输入 | ||
-r | 递归地列出节点的输入(输入树)。 | li -r hidden/Relu:0 | |
-d <max_depth> | 在 -r 模式下限制递归深度。 | li -r -d 3 hidden/Relu:0 | |
-c | 包含控制输入。 | li -c -r hidden/Relu:0 | |
-t | 显示输入节点的指令类型。 | li -t -r hidden/Relu:0 | |
lo | 列出节点的输出接收方 | ||
-r | 递归地列出节点的输出接收方(输出树)。 | lo -r hidden/Relu:0 | |
-d <max_depth> | 在 -r 模式下限制递归深度。 | lo -r -d 3 hidden/Relu:0 | |
-c | 包含经由控制边缘的接收方。 | lo -c -r hidden/Relu:0 | |
-t | 显示接收方节点的指令类型。 | lo -t -r hidden/Relu:0 | |
ls | 列出节点创建中所涉及的 Python 源文件。 | ||
-p <path_pattern> | 限制源文件的输出符合指定正则表达式路径格式。 | ls -p .*debug_mnist.* | |
-n | 限制节点名称的输出符合指定正则表达式格式。 | ls -n Softmax.* | |
ps | 输出 Python 源文件。 | ||
ps <file_path> | 输出指定 Python 源文件 source.py,每行用在此行创建的节点进行注解(如果有)。 | ps /path/to/source.py | |
-t | 执行关于张量(而不是默认的节点)的注解。 | ps -t /path/to/source.py | |
-b <line_number> | 从 source.py 的指定行开始注解。 | ps -b 30 /path/to/source.py | |
-m <max_elements> | 限制每行注解中的元素数量。 | ps -m 100 /path/to/source.py | |
run | 继续下一个 Session.run() | run | |
-n | 执行到下一次 Session.run (无需调试),然后在开始下一次运行之前进入 CLI。 | run -n | |
-t <T> | 执行 T - 1 次 Session.run (无需调试),接着执行一次运行(需要调试)。然后,在执行需要调试的运行之后进入 CLI。 | run -t 10 | |
-f <filter_name> | 继续执行 Session.run ,直到任何中间张量触发指定的张量过滤器(导致过滤器返回 True )为止。 | run -f has_inf_or_nan | |
-f <filter_name> -fenn <regex> | 继续执行 Session.run ,直到其节点名称不符合正则表达式的任何中间张量触发指定的张量过滤器(导致过滤器返回 True )为止。 | run -f has_inf_or_nan -fenn .*Sqrt.* | |
--node_name_filter <pattern> | 执行下一次 Session.run ,仅查看名称符合指定正则表达式格式的节点。 | run --node_name_filter Softmax.* | |
--op_type_filter <pattern> | 执行下一次 Session.run ,仅查看指令类型符合指定正则表达式格式的节点。 | run --op_type_filter Variable.* | |
--tensor_dtype_filter <pattern> | 执行下一次 Session.run ,仅转储数据类型 (dtype ) 符合指定正则表达式格式的张量。 | run --tensor_dtype_filter int.* | |
-p | 在分析模式下执行下一次 Session.run 调用。 | run -p | |
ri | 显示有关运行当前运行的信息,包括 fetch 和 feed。 | ri | |
config | 设置或显示永久性 TFDBG 界面配置。 | ||
set | 设置配置项的值:{graph_recursion_depth , mouse_mode }。 | config set graph_recursion_depth 3 | |
show | 显示当前的永久性界面配置。 | config show | |
version | 输出 TensorFlow 的版本及其关键依赖项。 | version | |
help | 输出常规帮助信息 | help | |
help <command> | 输出指定命令的帮助信息。 | help lt |