如何在虚拟环境中从Python脚本运行Tensorboard?

31

Tensorboard应该从命令行启动,如下所示:

tensorboard --logdir=path

我需要从代码中运行它。 到目前为止,我使用的是:

import os
os.system('tensorboard --logdir=' + path)

然而,由于未包含在系统路径中,因此TensorBoard无法启动。我在Windows上使用PyCharm和virtualenv。我不想更改系统路径,因此唯一的选项是从virtualenv中运行它。如何做到这一点?

12个回答

34

使用Tensorboard 2 API (2019):

from tensorboard import program

tracking_address = log_path # the path of your log file.

if __name__ == "__main__":
    tb = program.TensorBoard()
    tb.configure(argv=[None, '--logdir', tracking_address])
    url = tb.launch()
    print(f"Tensorflow listening on {url}")

注意:tb.launch()会创建一个守护线程,在您的进程结束时自动终止。


2
有什么办法可以抑制/重定向输出,使其不显示在stdout中吗? - Le Frite
导入tensorflow,然后在调用tensorboard之前尝试以下操作:tf.logging.set_verbosity(tf.compat.v1.logging.ERROR) - n00dle
下面添加了一个解决标准输出抑制的方案。 - Mano

11

可能有点晚了,但这是在Python 3.6.2中对我有效的解决方法:

import tensorflow as tf
from tensorboard import main as tb
tf.flags.FLAGS.logdir = "/path/to/graphs/"
tb.main()

这将使用默认配置运行张量板,并在“/path/to/graphs/”中查找图表和摘要。当然,您可以使用以下方法更改日志目录并设置任意数量的变量:

tf.flags.FLAGS.variable = value

希望这能有所帮助。


5
目前(tb版本1.10.0,tf版本1.9.0),用这种方式设置标志会抛出“UnrecognizedFlagError”的错误。如果我先通过调用.DEFINE_string(...)来设置它们,tb仍然无法看到它们,并且会出现“ValueError:必须指定logdir或db。”的故障。难道没有一种“有效”的方法可以从Python中调用tb吗? - Wunsch Punsch
@WunschPunsch 我正在使用tb 1.9和tf 1.9,它仍然可以工作。我不知道在版本1.10上是否有所改变。但是,请确保在tf.flags.FLAGS.logdir = "/path/to/graphs/"之前运行from tensorboard import main as tb - Rive
如果这个答案对你不起作用,请查看我对TensorBoard 1.9及以上版本的回答:https://dev59.com/cFgQ5IYBdhLWcg3w1nVA#51732122 - Agost Biro
无法工作,请参考此答案(11.10.18): https://dev59.com/cFgQ5IYBdhLWcg3w1nVA#52295534 - Elad Weiss
Tensorboard 2.6.0 有更新吗? - sravan953

10

由于我遇到了相同的问题,你可以使用受tensorboard\main.py启发的这些行:

from tensorboard import default
from tensorboard import program

tb = program.TensorBoard(default.PLUGIN_LOADERS, default.get_assets_zip_provider())
tb.configure(argv=['--logdir', my_directory])
tb.main()

使用my_directory作为您要检查的文件夹。如果想避免在tb.main()之后被阻塞,请不要忘记创建一个单独的线程。

最好的问候

编辑 Tensorboard V1.10:

由于某些个人原因,我以不同的方式写出来:

class TensorBoardTool:

    def __init__(self, dir_path):
        self.dir_path = dir_path

    def run(self):
        # Remove http messages
        log = logging.getLogger('werkzeug')
        log.setLevel(logging.ERROR)
        # Start tensorboard server
        tb = program.TensorBoard(default.PLUGIN_LOADERS, default.get_assets_zip_provider())
        tb.configure(argv=['--logdir', self.dir_path])
        url = tb.launch()
        sys.stdout.write('TensorBoard at %s \n' % url)

编辑 Tensorboard V1.12:

根据 Elad Weiss 和 tsbertalan 对于 Tensorboard 版本 1.12 的说明。

    def run(self):
        # Remove http messages
        log = logging.getLogger('werkzeug').setLevel(logging.ERROR)
        # Start tensorboard server
        tb = program.TensorBoard(default.get_plugins(), default.get_assets_zip_provider())
        tb.configure(argv=[None, '--logdir', self.dir_path])
        url = tb.launch()
        sys.stdout.write('TensorBoard at %s \n' % url)

然后只需要运行以下命令:

# Tensorboard tool launch
tb_tool = TensorBoardTool(work_dir)
tb_tool.run()

这将允许您在主进程运行时同时运行Tensorboard服务器,而不会干扰HTTP请求!


1
这是唯一几乎可行的答案(11.10.18)。您需要将however更改为tb.configure(argv=[None, '--logdir', my_directory]),因为新的tensorboard从argv[1:]开始解析。 - Elad Weiss
此外,我将 program.TensorBoard 的参数更改为 plugins=default.get_plugins(), assets_zip_provider=default.get_assets_zip_provider() - tsbertalan
我还使用了 logging.getLogger('tensorflow').setLevel(logging.ERROR) 来抑制来自tensorboard的冗长信息输出。 - tsbertalan

10

您应该在单独的线程中启动TensorBoard

def launchTensorBoard():
    import os
    os.system('tensorboard --logdir=' + tensorBoardPath)
    return

import threading
t = threading.Thread(target=launchTensorBoard, args=([]))
t.start()

3
这在环境中无法工作,因为os.system没有激活特定的环境名称(至少对于Windows来说是这样的)。 - Alexander McFarlane
由于全局解释器锁的存在,我建议使用多进程而不是线程来减少不必要的资源(CPU和内存)共享和同步开销。TensorBoard从磁盘加载信息,与运行中的进程无需通信,因此这种情况下的并行是多余的。 - Mano

9
对于Tensorboard 2.1.0版本,以下方法适用于我的情况:
python -m tensorboard.main --logdir $PWD/logs

首先,您必须先激活您的环境。(在我的情况下,conda install 出现了致命错误,所以我需要在 conda 中通过 pip 重新安装 tf。)


5

一个完整的Tensorboard 2(2019)解决方案,可以自动在Chrome浏览器中打开,适用于Windows和Linux。适用于conda和virtualenv两种环境。该解决方案抑制了Tensorboard的输出,因此不会(令人恼火地)显示在stdout中。

from multiprocessing import Process
import sys
import os

class TensorboardSupervisor:
    def __init__(self, log_dp):
            self.server = TensorboardServer(log_dp)
            self.server.start()
            print("Started Tensorboard Server")
            self.chrome = ChromeProcess()
            print("Started Chrome Browser")
            self.chrome.start()

    def finalize(self):
        if self.server.is_alive():
            print('Killing Tensorboard Server')
            self.server.terminate()
            self.server.join()
        # As a preference, we leave chrome open - but this may be amended similar to the method above


class TensorboardServer(Process):
    def __init__(self, log_dp):
        super().__init__()
        self.os_name = os.name
        self.log_dp = str(log_dp)
        # self.daemon = True

    def run(self):
        if self.os_name == 'nt':  # Windows
            os.system(f'{sys.executable} -m tensorboard.main --logdir "{self.log_dp}" 2> NUL')
        elif self.os_name == 'posix':  # Linux
            os.system(f'{sys.executable} -m tensorboard.main --logdir "{self.log_dp}" '
                      f'--host `hostname -I` >/dev/null 2>&1')
        else:
            raise NotImplementedError(f'No support for OS : {self.os_name}')
    
    
class ChromeProcess(Process):
    def __init__(self):
        super().__init__()
        self.os_name = os.name
        self.daemon = True

    def run(self):
        if self.os_name == 'nt':  # Windows
            os.system(f'start chrome  http://localhost:6006/')
        elif self.os_name == 'posix':  # Linux
            os.system(f'google-chrome http://localhost:6006/')
        else:
            raise NotImplementedError(f'No support for OS : {self.os_name}')

初始化:

tb_sup = TensorboardSupervisor('path/to/logs')

完成培训/测试后:

tb_sup.finalize()

对我来说,这种方法导致了死锁。由于.join()方法正在等待子进程停止,因此主要的训练/测试过程不会终止。由于tensorboard进程本身不会停止,这将导致终端无响应。一个简单的解决方法是在TensorboardSupervisorfinalize()方法中添加行self.server.terminate()self.chrome.terminate(),以显式终止子进程,使主进程可以结束。 - schurinkje
1
是的,我完全同意。我已经更新了解决方案,因为它在我的当前代码框架中 - 这确实包括你刚提到的缺失终止。谢谢你。 - Mano

3

如果你的Python解释器路径为:

/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/bin/python3.6

你可以运行这个命令来替代使用tensorboard

/usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/bin/python3.6 /usr/local/Cellar/python3/3.6.1/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/tensorboard/main.py 

2

要在指定的虚拟环境中从Python脚本运行tensorboard,您需要将tensorboard更改为/path/to/your/environment/bin/tensorboard。建议使用@Dmitry建议的单独线程执行命令。

整体看起来像这样,并且对于我的tb和tf 1.14.0版本有效:

def run_tensorboard(logdir_absolute):

   import os, threading
   tb_thread = threading.Thread(
          target=lambda: os.system('/home/username/anaconda3/envs/'
                                   'env_name/bin/tensorboard '
                                   '--logdir=' + logdir_absolute),
          daemon=True)
   tb_thread.start()

1
非常好的解决方案 - 谢谢! - Michael

1

从TensorBoard版本1.9.0开始,以下内容可用于在同一Python进程中使用默认设置启动TensorBoard:

import tensorboard as tb
import tensorboard.program
import tensorboard.default

tb.program.FLAGS.logdir = 'path/to/logdir'
tb.program.main(tb.default.get_plugins(),
                tb.default.get_assets_zip_provider())

0
以下将打开一个Chrome标签并启动TensorBoard。只需提供所需的目录和您系统的名称即可。
import os
os.system(
    "cd <directory> \
    && google-chrome http://<your computer name>:6007 \
    && tensorboard --port=6007 --logdir runs"
) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接