如何从 virtualenv 中的 python 脚本运行 Tensorboard?

Posted

技术标签:

【中文标题】如何从 virtualenv 中的 python 脚本运行 Tensorboard?【英文标题】:How to run Tensorboard from python scipt in virtualenv? 【发布时间】:2017-06-28 18:15:47 【问题描述】:

Tensorboard 应该像这样从命令行开始:

tensorboard --logdir=path

我需要从代码中运行它。直到现在我都用这个:

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

但是 tensorboard 没有启动,因为它没有包含在系统路径中。我在 Windows 上使用 PyCharm 和 virtualenv。我不想更改系统路径,所以唯一的选择是从 virtualenv 运行它。这个怎么做?

【问题讨论】:

【参考方案1】:

使用 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() 创建一个守护线程,当你的进程完成时会自动终止

【讨论】:

关于如何抑制/重定向输出使其不在标准输出中显示的任何想法? 导入 tensorflow,在调用 tensorboard 启动之前尝试以下操作:tf.logging.set_verbosity(tf.compat.v1.logging.ERROR) 在下面的 STDOUT 抑制解决方案中添加。【参考方案2】:

答案可能有点晚了,但这在 Python 3.6.2 中对我有用:

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

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

tf.flags.FLAGS.variable = value

希望对你有帮助。

【讨论】:

目前(tb 版本 1.10.0,tf 版本 1.9.0),以这种方式设置标志会抛出 UnrecognizedFlagError。如果我首先通过调用.DEFINE_string(...) 来设置它们,tb 仍然看不到它们并且以ValueError: A logdir or db must be specified. 失败。难道没有“有效”的方式从 python 调用 tb 吗? @WunschPunsch 我正在使用 tb 1.9 和 tf 1.9,它仍然有效。我不知道 1.10 版是否有所改变。但是,请确保您运行from tensorboard import main as tb 之前 tf.flags.FLAGS.logdir = "/path/to/graphs/" 如果这个答案对你不起作用,请查看我对 TensorBoard 1.9 及更高版本的答案:***.com/a/51732122/2650622 不工作。请参阅此答案 (11.10.18):***.com/a/52295534/5470144【参考方案3】:

当我遇到同样的问题时,您可以使用受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 请求!

【讨论】:

这是唯一几乎可行的答案(11.10.18)。但是,您需要更改为 tb.configure(argv=[None, '--logdir', my_directory]),因为新的张量板在 argv[1:] 开始解析 另外,我把program.TensorBoard的参数改成了plugins=default.get_plugins(), assets_zip_provider=default.get_assets_zip_provider() 我还使用了logging.getLogger('tensorflow').setLevel(logging.ERROR) 来抑制 tensorboard 的详细信息输出。【参考方案4】:

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

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

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

【讨论】:

这在环境中不起作用,因为os.system 尚未激活特定的环境名称(至少对于 Windows,这无论如何都不起作用) 由于全局解释器锁,我会使用多处理而不是线程,以减少不必要的资源(CPU 和内存)共享和同步开销。张量板从磁盘加载其信息,与正在运行的进程没有通信——因此这种方式的并行性是多余的。【参考方案5】:

对于 Tensorboard 2.1.0,这对我有用:

python -m tensorboard.main --logdir $PWD/logs

你必须先激活你的环境。 (在我的例子中,conda install 有一个致命错误,所以我需要通过pipconda 中重新安装tf。)

【讨论】:

【参考方案6】:

如果你的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 

【讨论】:

【参考方案7】:

要在指定的虚拟环境中从 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()

【讨论】:

很好的解决方案 - 谢谢!【参考方案8】:

从 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())

【讨论】:

【参考方案9】:

Tensorboard 2 (2019) 的完整解决方案,可自动打开适用于 Windows 和 Linux 的 Chrome 浏览器。适用于两种环境:conda 和 virtualenv。 此解决方案会抑制 Tensorboard 输出,因此它不会(令人讨厌地)显示在标准输出中

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() 方法正在等待子过程停止。由于张量板进程不会自行停止,这将导致终端无响应。一个简单的解决方法是将行 self.server.terminate()self.chrome.terminate() 添加到 TensorboardSupervisorfinalize() 方法中,以显式终止子进程,以便主进程可以结束。 是的,我完全同意。我已经更新了解决方案,因为它在我当前的代码框架中 - 它确实包括您刚刚提到的丢失的终止。谢谢你。【参考方案10】:

以下将打开一个 Chrome 选项卡并启动 TensorBoard。只需提供所需的目录和您的系统名称。

import os
os.system(
    "cd <directory> \
    && google-chrome http://<your computer name>:6007 \
    && tensorboard --port=6007 --logdir runs"
) 

【讨论】:

【参考方案11】:

遇到了同样的问题: 当您在 Windows 上工作时,您可以使用批处理文件来全自动打开 tensorboard,如下面的示例所示。

您可能想在可见的控制台窗口 (cmd.exe) 中打开 tensorboard。在您的 IDE (pycharm) 中调用一个批处理文件将在 IDE 中运行它,因此在后台运行,这意味着您看不到控制台。因此,您可以使用一种解决方法:调用一个批处理文件,然后调用该批处理文件来启动 tensorboard。

注意:我使用Anaconda 作为本示例的虚拟环境

batch_filename = 'start_tb.bat'  # set filename for batch file
tb_command = 'tensorboard --logdir=' + log_dir  # join strings for tensorflow command

# creates batch file that will call seconds batch file in console window (cmd.exe)
with open(os.path.join('invoke.bat'), "w") as f:
    f.writelines('start ' + batch_filename)

# created batch file that activates Anaconda environment and starts tensorboard
with open(os.path.join(batch_filename), "w") as f:
    f.writelines('\nconda activate YOURCondaEnvNAME  && ' + tb_command)  # change to your conda environment, or other virtualenv

# starts tensorboard using the batch files (will open console window)
# calls the 'invoke.bat' that will call 'start_tb.bat'
os.system('invoke.bat')

# starts tensorboard in default browser >> ATTENTION: must be adapted to local host
os.system('start "" http://YOUR-COMPUTER-NAME:6006/')  # just copy the URL that tensorboard runs at on your computer

有时您可能需要在浏览器中刷新 tensorboard,因为它在正确设置之前已经打开。

【讨论】:

【参考方案12】:

尝试从 python 运行

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

在 PyCharm 中为我工作(但在 linux 上,所以如果 shell 语法不同,那么你必须调整它)

【讨论】:

另一种方法是调整 PyCharm 环境设置中的环境变量,以便将可执行张量板的路径添加到 PATH,但发布的答案更简洁、更通用,恕我直言

以上是关于如何从 virtualenv 中的 python 脚本运行 Tensorboard?的主要内容,如果未能解决你的问题,请参考以下文章

如何将Python virtualenv移至其他系统(计算机)并使用站点软件包中的软件包

如何在virtualenv环境中安装指定的python版本

如何将模块从一个 virtualenv 复制到另一个

python virtualenv virtualenvwrapper

Python - 使用 virtualenv 手动安装包

如何配置全局主管以使用 pyenv 和 virtualenv