发新帖

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

[复制链接]
496 0

快来加入 TensorFlowers 大家庭!

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

x
本帖最后由 大白白 于 2018-7-13 10:17 编辑

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


tfdbg CLI 的其他功能
除了上面列出的命令外,tfdbg CLI 还提供了下列其他功能:
  • 要浏览之前的 tfdbg 命令,请输入几个字符,然后按向上或向下箭头键。tfdbg 会向您显示以这些字符开头的命令的历史记录。
  • 要浏览屏幕输出的历史记录,请执行下列任一操作:
    • 使用 prev 和 next 命令。
    • 点击屏幕左上角附近带下划线的 <-- 和 --> 链接。
  • 命令(和一些命令参数)的 Tab 补齐功能。
  • 要将屏幕输出重定向到文件(而不是屏幕),请使用 bash 样式重定向结束命令。例如,以下命令会将 pt 命令的输出重定向到 /tmp/xent_value_slices.txt 文件:

tfdbg> pt cross_entropy/Log:0[:, 0:10] > /tmp/xent_value_slices.txt


查找 nan 和 inf
在第一个 Session.run() 调用中,没有出现存在问题的数值。您可以使用命令 run 或其简写形式 r 转到下一次运行。
提示:如果您反复输入 run 或 r,则将能够依序在 Session.run() 调用之间移动。
您还可以使用 -t 标记一次向前移动多个 Session.run() 调用,例如:

tfdbg> run -t 10
在每次 Session.run() 调用之后,您无需重复输入 run 并在 run-end 界面中手动搜索 nan 和 inf(例如,通过使用上表中显示的 pt 命令),而是可以使用以下命令让调试程序反复执行 Session.run() 调用(不在 run-start 或 run-end 提示符处停止),直到第一个 nan 或 inf 值出现在图中。这类似于一些程序式语言调试程序中的条件断点:

tfdbg> run -f has_inf_or_nan
注意:上述命令可正常运行,因为在创建封装会话时已为您注册了一个名为 has_inf_or_nan 的张量过滤器。此过滤器会检测 nan 和 inf(如前所述)。如果您已注册任何其他过滤器,则可以使用“run -f”让 tfdbg 一直运行,直到任何张量触发该过滤器(导致过滤器返回 True)为止。

def my_filter_callable(datum, tensor):
  # A filter that detects zero-valued scalars.
  return len(tensor.shape) == 0 and tensor == 0.0

sess.add_tensor_filter('my_filter', my_filter_callable)
然后在 tfdbg run-start 提示符处运行,直到您的过滤器被触发:

tfdbg> run -f my_filter
请参阅此 API 文档,详细了解与 add_tensor_filter() 搭配使用的谓词 Callable 的预期签名和返回值。
如屏幕所示,在第一行中,has_inf_or_nan 过滤器在第四次 Session.run() 调用期间第一次被触发:Adam 优化器前向-后向训练通过了图。在本次运行中,36 个(共 95 个)中间张量包含 nan 或 inf 值。这些张量按时间先后顺序列出,具体时间戳显示在左侧。在列表顶部,您可以看到第一次出现错误数值的第一个张量:cross_entropy/Log:0。
要查看张量的值,请点击带下划线的张量名称 cross_entropy/Log:0 或输入等效命令:

tfdbg> pt cross_entropy/Log:0
向下滚动一点,您会发现一些分散的 inf 值。如果很难用肉眼找到出现 inf 和 nan 的地方,可以使用以下命令执行正则表达式搜索并突出显示输出:

tfdbg> /inf
或者:

tfdbg> /(inf|nan)
您还可以使用 -s 或 --numeric_summary 命令获取张量中的数值类型的快速摘要:

tfdbg> pt -s cross_entropy/Log:0
您可以从摘要中看到 cross_entropy/Log:0 张量的若干个元素(共 1000 个)都是 -inf(负无穷大)。
为什么会出现这些负无穷大的值?为了进一步进行调试,通过点击顶部带下划线的 node_info 菜单项或输入等效的 node_info (ni) 命令,显示有关节点 cross_entropy/Log 的更多信息:

tfdbg> ni cross_entropy/Log
您可以看到,此节点的指令类型为 Log,输入为节点 Softmax。运行以下命令可进一步查看输入张量:

tfdbg> pt Softmax:0
检查输入张量中的值,并搜索其中是否存在零:

tfdbg> /0\.000
确实存在零。现在很明显,错误数值的根源是节点 cross_entropy/Log 取零的对数。要在 Python 源代码中找出导致错误的行,请使用 ni 命令的 -t 标记来显示节点构造的回溯:

tfdbg> ni -t cross_entropy/Log
如果您点击屏幕顶部的“node_info”,tfdbg 会自动显示节点构造的回溯。
从回溯中可以看到该操作是在以下行构建的 - debug_mnist.py

diff = y_ * tf.log(y)
tfdbg 有一个可以轻松将张量和指令追溯到 Python 源文件中的行的功能。它可以用行创建的指令或张量注解 Python 文件的行。要使用此功能,只需点击 ni -t <op_name> 命令的堆栈追踪输出中带下划线的行编号,或者使用 ps(或 print_source)命令,例如:ps /path/to/source.py。例如,以下屏幕截图显示了 ps 命令的输出。


解决问题
要解决此问题,请修改 debug_mnist.py,将原始行:

diff = -(y_ * tf.log(y))
更改为 softmax 交叉熵的在数值上稳定的内置实现:

diff = tf.losses.sparse_softmax_cross_entropy(labels=y_, logits=logits)
用 --debug 标记重新运行,如下所示:

python -m tensorflow.python.debug.examples.debug_mnist --debug
在 tfdbg> 提示符处输入以下命令:

run -f has_inf_or_nan`
确认没有任何张量被标记为包含 nan 或 inf 值,并且准确率现在继续上升(而不是停滞不变)。大功告成!


调试 tf-learn Estimator 和 Experiment
本部分介绍了如何调试使用 Estimator 和 Experiment API 的 TensorFlow 程序。这些 API 提供的部分便利性是它们在内部管理 Session。这样一来,上面的部分介绍的 LocalCLIDebugWrapperSession 就不适用了。幸运的是,您仍然可以使用 tfdbg 提供的特殊 hook 对其进行调试。
调试 tf.contrib.learn Estimator
目前,tfdbg 可以调试 tf-learn Estimator 的 fit()evaluate() 方法。要调试 Estimator.fit(),请创建一个 LocalCLIDebugHook 并将其用作 monitors 参数的一部分。例如:

# First, 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

# Create a LocalCLIDebugHook and use it as a monitor when calling fit().
hooks = [tf_debug.LocalCLIDebugHook()]

classifier.fit(x=training_set.data,
               y=training_set.target,
               steps=1000,
               monitors=hooks)
要调试 Estimator.evaluate(),请为 hooks 参数分配钩子,如下例所示:

accuracy_score = classifier.evaluate(x=test_set.data,
                                     y=test_set.target,
                                     hooks=hooks)["accuracy"]
debug_tflearn_iris.py(基于 tf-learn 的鸢尾花教程)包含如何搭配使用 tfdbg 和 Estimator 的完整示例。要运行此示例,请执行以下操作:

python -m tensorflow.python.debug.examples.debug_tflearn_iris --debug

调试 tf.contrib.learn Experiment
tf.contrib.learn 中,Experiment 是一个比 Estimator 更高级别的构造。它提供了用于训练和评估模型的单个界面。为了调试对 Experiment 对象的 train() 和 evaluate() 调用,在调用该对象的构造函数时,您可以分别使用关键字参数 train_monitors 和 eval_hooks。例如:

# First, 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

hooks = [tf_debug.LocalCLIDebugHook()]

ex = experiment.Experiment(classifier,
                           train_input_fn=iris_input_fn,
                           eval_input_fn=iris_input_fn,
                           train_steps=FLAGS.train_steps,
                           eval_delay_secs=0,
                           eval_steps=1,
                           train_monitors=hooks,
                           eval_hooks=hooks)

ex.train()
accuracy_score = ex.evaluate()["accuracy"]
要在 Experiment 模式下构建并运行 debug_tflearn_iris 示例,请执行以下操作:

python -m tensorflow.python.debug.examples.debug_tflearn_iris \
    --use_experiment --debug
LocalCLIDebugHook 还允许您配置 watch_fn,后者可用于灵活指定在不同的 Session.run() 调用期间要查看哪些 Tensor,这些调用作为 fetches 和 feed_dict 以及其他状态的函数。如需了解详情,请参阅此 API 文档




使用 TFDBG 调试 Keras 模型
要结合使用 TFDBG 和 Keras,请允许 Keras 后端使用 TFDBG 封装的会话对象。例如,要使用 CLI 封装容器:

import tensorflow as tf
from keras import backend as keras_backend
from tensorflow.python import debug as tf_debug

keras_backend.set_session(tf_debug.LocalCLIDebugWrapperSession(tf.Session()))

# Define your keras model, called "model".
model.fit(...)  # This will break into the TFDBG CLI.


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

本版积分规则

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