【问题标题】:Print statement inside TensorFlow functionTensorFlow 函数中的打印语句
【发布时间】:2018-04-11 18:31:38
【问题描述】:

我是 TensorFlow 新手,我正在尝试在一个函数中打印一个向量的形状,该函数将从 TensorFlow 会话中调用。

问题是这一行(显示已注释掉)仅在最初定义此函数模板时执行(而不是在 TensorFlow 会话期间的每次迭代中)。如何添加打印语句,以便在每次 TensorFlow 迭代时调用它?

def Q(X):
    # f_debug.write('Q(X) :: X.shape :: ' + str(X.shape) + '\n')

    h = tf.nn.relu(tf.matmul(X, Q_W1) + Q_b1)
    z = tf.matmul(h, Q_W2) + Q_b2
    return z

【问题讨论】:

  • f_debug 只是您要输出调试信息的文件吗?
  • 有什么原因不能只使用python内置的print()函数吗?
  • 挑战在于函数 Q 可能也不会在每次 TF 迭代时运行。稍后在代码中,句柄 z 将在每次迭代时被解析,从而导致它所依赖的 TF 节点的解析链,例如句柄 h。您可以使用tf.print 将打印节点添加为 z 的依赖项,当 z 被解析时将打印出来。
  • 这花了我很长时间才能理解我的代码,但是像 Q 这样的函数只是“图形生成器”函数,它们返回一个可以执行的句柄节点(一个张量)像 z /稍后解决。

标签: python logging tensorflow


【解决方案1】:

这是一个需要注意的重要点,也是 TF 中的常见混淆。 tensorflow 不会在会话中调用该函数,没有 python 函数会调用,tf.py_func 除外,这可能是您问题的解决方法。

Tensorflow 调用您的函数 Q 只是为了获取符号操作,然后将这些操作添加到依赖关系图中。在会话期间,依赖图是执行计算所依赖的全部。即使您正在使用tf.whiletf.cond 或其他控制流操作。这些都不会在会话期间调用 python,它们只是按照您的定义循环依赖关系图中的元素。

一般来说,除了使用 Tensorflow 调试器(一点也不难配置)之外,没有什么好的方法可以停止执行 tensorflow 中间图执行。但作为一种解决方法,您可能会通过定义 tf.py_func python 函数而侥幸逃脱。该函数将张量编组到 python 对象中,并在会话执行期间调用 python(它效率不高,但在某些情况下很方便)。

您可能需要使用with tf.control_dependencies(...): 来强制您的tf.py_func 操作运行(因为如果它内部只有一个打印语句,它将没有任何依赖关系)。

免责声明:我没有以这种方式使用tf.py_func,也不是为此目的而构建的。

【讨论】:

    【解决方案2】:

    这是 TensorFlow 1 的具体解释。我确信 TF 2 中的 Eager Execution 会改变其中的一些内容。见docs for tf.print

    我在 py_func 函数中使用常规的 print() 语句没有任何运气。您可以使用tf.print 在 TF 图(py_func 或其他)的执行“内部”打印语句。我只熟悉它在 TF 1 中的使用,但它通过创建新的打印操作并将其添加到 TF 图中来工作:

    def Q(X):
        # Note that at least sometimes, X.shape can be resolved before the
        # graph is executed, so you may only need this for the *value* of X
    
        # Create a new print op
        printop = tf.print('Q:', X)
    
        # Force printop to be added to the graph by setting it as a 
        # dependency for at least one operation that will be run
        with tf.control_dependencies([printop]):
            h = tf.nn.relu(tf.matmul(X, Q_W1) + Q_b1)
            z = tf.matmul(h, Q_W2) + Q_b2
            return z
    

    已经遇到了一些情况,这并没有像我希望的那样工作(我相信是由于多线程)。如果您找不到图形的节点来附加 printop 操作,这也可能会很棘手——例如,如果您试图在函数的最后一行打印一些东西。

    但这似乎对我来说大部分时间都有效。

    Docs on tf.print().

    【讨论】:

      猜你喜欢
      • 2016-08-14
      • 1970-01-01
      • 2013-11-05
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-05
      相关资源
      最近更新 更多