【问题标题】:Is there a way to get tensorflow tf.Print output to appear in Jupyter Notebook output有没有办法让 tensorflow tf.Print 输出出现在 Jupyter Notebook 输出中
【发布时间】:2016-10-20 06:57:26
【问题描述】:

我在 Jupyter 笔记本中使用 tf.Print 操作。它按要求工作,但只会将输出打印到控制台,而不是在笔记本中打印。有没有办法解决这个问题?

一个例子如下(在笔记本中):

import tensorflow as tf

a = tf.constant(1.0)
a = tf.Print(a, [a], 'hi')
sess = tf.Session()
a.eval(session=sess)

该代码将在控制台中打印“hi[1]”,但在笔记本中没有任何内容。

【问题讨论】:

  • 请在此处粘贴您尝试过的代码。
  • 可以捕获sys.stdout

标签: tensorflow jupyter-notebook


【解决方案1】:

2017 年 2 月 3 日更新 我已将其包装到 memory_util 包中。示例用法

# install memory util
import urllib.request
response = urllib.request.urlopen("https://raw.githubusercontent.com/yaroslavvb/memory_util/master/memory_util.py")
open("memory_util.py", "wb").write(response.read())

import memory_util

sess = tf.Session()
a = tf.random_uniform((1000,))
b = tf.random_uniform((1000,))
c = a + b
with memory_util.capture_stderr() as stderr:
    sess.run(c.op)

print(stderr.getvalue())

** 旧东西**

您可以从 IPython 核心重用 FD redirector。 (马克·桑德勒的想法)

import os
import sys

STDOUT = 1
STDERR = 2

class FDRedirector(object):
    """ Class to redirect output (stdout or stderr) at the OS level using
        file descriptors.
    """ 

    def __init__(self, fd=STDOUT):
        """ fd is the file descriptor of the outpout you want to capture.
            It can be STDOUT or STERR.
        """
        self.fd = fd
        self.started = False
        self.piper = None
        self.pipew = None

    def start(self):
        """ Setup the redirection.
        """
        if not self.started:
            self.oldhandle = os.dup(self.fd)
            self.piper, self.pipew = os.pipe()
            os.dup2(self.pipew, self.fd)
            os.close(self.pipew)

            self.started = True

    def flush(self):
        """ Flush the captured output, similar to the flush method of any
        stream.
        """
        if self.fd == STDOUT:
            sys.stdout.flush()
        elif self.fd == STDERR:
            sys.stderr.flush()

    def stop(self):
        """ Unset the redirection and return the captured output. 
        """
        if self.started:
            self.flush()
            os.dup2(self.oldhandle, self.fd)
            os.close(self.oldhandle)
            f = os.fdopen(self.piper, 'r')
            output = f.read()
            f.close()

            self.started = False
            return output
        else:
            return ''

    def getvalue(self):
        """ Return the output captured since the last getvalue, or the
        start of the redirection.
        """
        output = self.stop()
        self.start()
        return output

import tensorflow as tf
x = tf.constant([1,2,3])
a=tf.Print(x, [x])

redirect=FDRedirector(STDERR)

sess = tf.InteractiveSession()
redirect.start();
a.eval();
print "Result"
print redirect.stop()

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,并通过在我的笔记本中使用这样的函数来解决它:

    def tf_print(tensor, transform=None):
    
        # Insert a custom python operation into the graph that does nothing but print a tensors value 
        def print_tensor(x):
            # x is typically a numpy array here so you could do anything you want with it,
            # but adding a transformation of some kind usually makes the output more digestible
            print(x if transform is None else transform(x))
            return x
        log_op = tf.py_func(print_tensor, [tensor], [tensor.dtype])[0]
        with tf.control_dependencies([log_op]):
            res = tf.identity(tensor)
    
        # Return the given tensor
        return res
    
    
    # Now define a tensor and use the tf_print function much like the tf.identity function
    tensor = tf_print(tf.random_normal([100, 100]), transform=lambda x: [np.min(x), np.max(x)])
    
    # This will print the transformed version of the tensors actual value 
    # (which was summarized to just the min and max for brevity)
    sess = tf.InteractiveSession()
    sess.run([tensor])
    sess.close()
    

    仅供参考,在我的自定义函数中使用记录器而不是调用“print”对我来说很神奇,因为标准输出通常由 jupyter 缓冲,并且在“Loss is Nan”类型的错误之前没有显示——这就是重点就我而言,首先使用该功能。

    【讨论】:

      【解决方案3】:

      您可以查看启动jupyter notebook 的终端以查看消息。

      import tensorflow as tf
      
      tf.InteractiveSession()
      
      a = tf.constant(1)
      b = tf.constant(2)
      
      opt = a + b
      opt = tf.Print(opt, [opt], message="1 + 2 = ")
      
      opt.eval()
      

      在终端,我可以看到:

      2018-01-02 23:38:07.691808: I tensorflow/core/kernels/logging_ops.cc:79] 1 + 2 = [3]
      

      【讨论】:

        【解决方案4】:

        一个简单的方法,在常规 python 中尝试过,但还不是 jupyter。 os.dup2(sys.stdout.fileno(), 1) os.dup2(sys.stdout.fileno(), 2)

        解释在这里:In python, how to capture the stdout from a c++ shared library to a variable

        【讨论】:

        • 适用于我的 TF 2.0
        【解决方案5】:

        我遇到的问题是无法在 Tensorflow Graph 中运行会话,例如在训练或评估中。 这就是为什么使用sess.run(opt)opt.eval() 的选项对我来说不是解决方案。 最好的办法是使用tf.Print() 并将日志重定向到外部文件。 我使用临时文件执行此操作,然后将其传输到这样的常规文件:

        STDERR=2
        import os
        import sys
        import tempfile
        
        class captured:
            def __init__(self, fd=STDERR):
                self.fd = fd
                self.prevfd = None
            def __enter__(self):
                t = tempfile.NamedTemporaryFile()
                self.prevfd = os.dup(self.fd)
                os.dup2(t.fileno(), self.fd)
                return t
            def __exit__(self, exc_type, exc_value, traceback):
                os.dup2(self.prevfd, self.fd)
        
        with captured(fd=STDERR) as tmp:
            ...
            classifier.evaluate(input_fn=input_fn, steps=100)
        
        with open('log.txt', 'w') as f:
            print(open(tmp.name).read(), file=f)
        

        然后在我的评估中:

        a = tf.constant(1)
        a = tf.Print(a, [a], message="a: ")
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-18
          • 2018-11-25
          • 1970-01-01
          • 2023-01-13
          相关资源
          最近更新 更多