发新帖

TensorFlow 学习 -- TensorFlow 调试程序(1)

[复制链接]
410 0

快来加入 TensorFlowers 大家庭!

您需要 登录 才可以下载或查看,没有帐号?加入社区

x
转载自:https://tensorflow.google.cn/programmers_guide/debugger?hl=zh-CN


tfdbg 是 TensorFlow 的专用调试程序。借助该调试程序,您可以在训练和推理期间查看运行中 TensorFlow 图的内部结构和状态,由于 TensorFlow 的计算图模式,使用通用调试程序(如 Python 的 pdb)很难完成调试。
本指南重点介绍 tfdbg 的命令行界面 (CLI)。有关如何使用 tfdbg 的图形用户界面 (GUI)(即 TensorBoard 调试程序插件)的指导,请访问相关 README 文件
注意:TensorFlow 调试程序使用基于 curses 的文本界面。在 Mac OS X 上,ncurses 库是必需的,而且可以使用 brew install homebrew/dupes/ncurses 进行安装。在 Windows 上,curses 并没有得到同样的支持,因此基于 readline 的界面可以与 tfdbg 配合使用(具体方法是使用 pip 安装 pyreadline)。如果您使用的是 Anaconda3,则可以使用 "C:\Program Files\Anaconda3\Scripts\pip.exe" install pyreadline 等命令进行安装。您可以在此处下载非官方 Windows curses 软件包,然后使用 pip install <your_version>.whl 进行安装;不过,Windows 上的 curses 可能无法像 Linux 或 Mac 上的 curses 一样稳定地运行。
本教程展示了如何使用 tfdbg CLI 调试出现 naninf 的问题,这是 TensorFlow 模型开发期间经常出现的一种错误类型。下面的示例适用于使用低阶 TensorFlow Session API 的用户。本文档的后面部分介绍了如何将 tfdbg 与更高阶的 API(即 tf-learn Estimator 和 Experiment)相结合。要观察此类问题,请在不使用调试程序的情况下运行以下命令(可在此处找到源代码):

python -m tensorflow.python.debug.examples.debug_mnist
此代码训练了一个简单的神经网络来识别 MNIST 数字图像。请注意,在完成第一个训练步之后,准确率略有提高,但之后停滞在较低(近机会)水平:

Accuracy at step 0: 0.1113
Accuracy at step 1: 0.3183
Accuracy at step 2: 0.098
Accuracy at step 3: 0.098
Accuracy at step 4: 0.098
您想知道哪里出了问题,怀疑训练图中的某些节点生成了错误数值(例如 inf 和 nan),因为这是导致此类训练失败的常见原因。我们可以使用 tfdbg 来调试此问题,并确定第一次出现此数字问题的确切图节点。

使用 tfdbg 封装 TensorFlow 会话
要向示例中的 tfdbg 添加支持,我们只需添加下列代码行,并使用调试程序封装容器封装会话对象。此代码已添加到 debug_mnist.py 中,因此您可以在命令行中使用 --debug 标记激活 tfdbg CLI。

# Let your BUILD target depend on "//tensorflow/python/debug:debug_py"
# (You don't need to worry about the BUILD dependency if you are using a pip
#  install of open-source TensorFlow.)
from tensorflow.python import debug as tf_debug

sess = tf_debug.LocalCLIDebugWrapperSession(sess)
此封装容器与会话具有相同的界面,因此启用调试时不需要对代码进行其他更改。该封装容器还提供其他功能,包括:
  • 在每次 Session.run() 调用前后调出 CLI,以便您控制执行情况和检查图的内部状态。
  • 允许您为张量值注册特殊 filters,以便诊断问题。
在本示例中,我们已经注册了一个名为 tfdbg.has_inf_or_nan 的张量过滤器,它仅仅确定任何中间张量(不是 Session.run() 调用的输入或输出,而是位于从输入到输出的路径中的张量)中是否存在任何 nan 或 inf 值。此过滤器可以确定是否存在 nan 和 inf,这是一种常见的用例,我们在 debug_data 模块中包含了此过滤器。
注意:您还可以自行编写自定义过滤器。要了解详情,请参阅 DebugDumpDir.find() 的 API 文档使用 tfdbg 调试模型训练
我们尝试再次训练模型,但这次添加 --debug 标记:

python -m tensorflow.python.debug.examples.debug_mnist --debug
调试封装容器会话会在将要执行第一次 Session.run() 调用时提示您,而屏幕上会显示关于获取的张量和 feed 字典的信息。
这就是我们所说的 run-start CLI。它先列出对当前 Session.run 调用的 feed 和 fetch,然后再执行任何操作。
如果因屏幕尺寸太小而无法显示完整的消息内容,您可以调整屏幕大小。
使用 PageUp/PageDown/Home/End 键可以浏览屏幕上的输出。在大部分没有这些键的键盘上,使用 Fn + Up/Fn + Down/Fn + Right/Fn + Left 也可以。
在命令提示符处输入 run 命令(或只输入 r):

tfdbg> run
run 命令会让 tfdbg 一直执行,直到下一次 Session.run() 调用结束,而此调用会使用测试数据集计算模型的准确率。tfdbg 会扩展运行时图来转储所有中间张量。运行结束后,tfdbg 会在 run-end CLI 中显示所有转储的张量值。例如:
在执行 run 之后运行命令 lt 也可以获得此张量列表。


tfdbg CLI 常用命令
在 tfdbg> 提示符处尝试下列命令(参考 tensorflow/python/debug/examples/debug_mnist.py 中的代码):
[td]
命令
语法或选项
说明
示例
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
help输出常规帮助信息help
help <command>输出指定命令的帮助信息。help lt

请注意,每次输入命令时,都会显示新的屏幕输出。这有点类似于浏览器中的网页。您可以通过点击 CLI 左上角附近的 <-- 和 --> 文本箭头在这些屏幕之间导航。

本楼点评(0) 收起
您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

快速回复 返回顶部 返回列表