在向后传递中调试 nans
Posted
技术标签:
【中文标题】在向后传递中调试 nans【英文标题】:Debugging nans in the backward pass 【发布时间】:2016-03-06 21:20:53 【问题描述】:我正在尝试调试一个有些复杂且非规范的 NN 架构。计算前向传递很好,并且给了我预期的结果,但是当我尝试使用 Adam 或任何标准优化器进行优化时,即使在一次迭代后学习率非常低,我到处都会得到 nans。我正在尝试对它们进行本地化,并且想知道是否有办法捕获第一次出现的 nan 并检测它出现在哪个操作中?我尝试了tf.add_check_numerics_ops()
,但它似乎没有做任何事情,或者我使用不正确。
【问题讨论】:
你能在哪里解决这个问题?我也有同样的问题 【参考方案1】:调试 NaN 可能会很棘手,尤其是在您拥有大型网络的情况下。 tf.add_check_numerics_ops()
将操作添加到图中,断言图中的每个浮点张量不包含任何 NaN 值,但默认情况下不运行这些检查。相反,它会返回一个您可以定期或在每一步运行的操作,如下所示:
train_op = ...
check_op = tf.add_check_numerics_ops()
sess = tf.Session()
sess.run([train_op, check_op]) # Runs training and checks for NaNs
【讨论】:
问题是,一旦我运行 train_op,nans 就会在整个网络中传播,因此找不到原因是没有用的。我想做的是运行前向和后向传递,一旦生成 nan,违规操作就会抛出异常。 如果你同时运行train_op
和 check_op
,你应该会得到一个错误,报告第一个节点有一个 NaN - 你可以捕捉到引发的 tf.InvalidArgumentError
,并提取来自其.op
属性。通过操作的句柄,您可以访问其op.inputs[0]
属性以查看哪个张量具有 NaN 值。
@MohammedAlQuraishi 如果这是公认的答案,那么您应该accept 它。 :)
是否需要tf.control_dependencies
,否则订单未定义? ***.com/questions/43844510/…
当您的图表有条件或 while_loops 时,推荐的解决方案是什么?【参考方案2】:
也许你可以添加打印操作到可疑操作打印值,像这样
print_ops = []
for op in ops:
print_ops.append(tf.Print(op, [op],
message='%s :' % op.name, summarize=10))
print_op = tf.group(*print_ops)
sess.run([train_op, print_op])
要添加到所有操作,您可以按照add_check_numerics_ops
的行进行循环。
【讨论】:
以上是关于在向后传递中调试 nans的主要内容,如果未能解决你的问题,请参考以下文章
调试 'CALayer 位置包含 NaN: [nan nan]'
调试 Firebase 崩溃报告 - CALayer 位置包含 NAN