在Pytorch和Keras等框架上自由使用tensorboard

前言

在这篇博文中,将向你展示如何自由的在任何Python代码中使用Tensorboard。

最近身边的一些朋友们都开始从tensorflow转战Pytorch等,Tensorflow使用静态编译的计算图并在单独的运行时环境中运行大部分应用程序,与Tensorflow相比,PyTorch允许你完全使用Python创建动态计算图,单单动态调试这一点就欲罢不能(真香警告)。

但是tensorflow的孪生兄弟tensorboard实在是有点让人难以舍弃。对于那些不了解Tensorboard的人来说,它是一个可视化工具,用于计算图形,学习进度,神经网络权重或您可能需要在一个漂亮的基于Web的环境中绘制的任何内容。 Tensorboard从命令行作为(基于Python)Web服务器运行。它读取外部代码生成的.event文件(如Tensorflow或本文中显示的代码),并在浏览器中显示它们。事实上,在任何其他深度学习框架中,还没有Tensorboard的任何替代方案。

tensorboard类的实现

Tensorboard提供以下基本功能:

  • 可视化Tensorflow图
  • 绘制一个简单的值(如学习率)
  • 绘制图像(例如激活图)
  • 绘制直方图。

第一个功能在实现上较为麻烦,但是我们可以很简单的实现后三个功能。直接上代码,后文列出详细解释:

import io
import numpy as np
from PIL import Image
import tensorflow as tf
import skimage
import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt

class Tensorboard:
    def __init__(self, logdir):
        self.writer = tf.summary.FileWriter(logdir)

    def close(self):
        self.writer.close()

    def log_scalar(self, tag, value, global_step):
        summary = tf.Summary()
        summary.value.add(tag=tag, simple_value=value)
        self.writer.add_summary(summary, global_step=global_step)
        self.writer.flush()

    def log_histogram(self, tag, values, global_step, bins):
        counts, bin_edges = np.histogram(values, bins=bins)

        hist = tf.HistogramProto()
        hist.min = float(np.min(values))
        hist.max = float(np.max(values))
        hist.num = int(np.prod(values.shape))
        hist.sum = float(np.sum(values))
        hist.sum_squares = float(np.sum(values ** 2))

        bin_edges = bin_edges[1:]

        for edge in bin_edges:
            hist.bucket_limit.append(edge)
        for c in counts:
            hist.bucket.append(c)

        summary = tf.Summary()
        summary.value.add(tag=tag, histo=hist)
        self.writer.add_summary(summary, global_step=global_step)
        self.writer.flush()

    def log_image(self, tag, img, global_step):
        s = io.BytesIO()
        Image.fromarray(img).save(s, format='png')

        img_summary = tf.Summary.Image(encoded_image_string=s.getvalue(),
                                       height=img.shape[0],
                                       width=img.shape[1])

        summary = tf.Summary()
        summary.value.add(tag=tag, image=img_summary)
        self.writer.add_summary(summary, global_step=global_step)
        self.writer.flush()

    def log_plot(self, tag, figure, global_step):
        plot_buf = io.BytesIO()
        figure.savefig(plot_buf, format='png')
        plot_buf.seek(0)
        img = Image.open(plot_buf)
        img_ar = np.array(img)

        img_summary = tf.Summary.Image(encoded_image_string=plot_buf.getvalue(),
                                       height=img_ar.shape[0],
                                       width=img_ar.shape[1])

        summary = tf.Summary()
        summary.value.add(tag=tag, image=img_summary)
        self.writer.add_summary(summary, global_step=global_step)
        self.writer.flush()


if __name__ == '__main__':
    tensorboard = Tensorboard('logs')
    x = np.arange(1, 101)
    y = 20 + 3 * x + np.random.random(100) * 100

    # Log simple values
    for i in range(0, 100):
        tensorboard.log_scalar('value', y[i], i)

    # Log images
    img = Image.open('/mnt/sda1/lvv/84504.jpg')
    img = np.asarray(img, dtype=np.uint8)
    # img = skimage.io.imread('/mnt/sda1/lvv/84504.jpg')
    tensorboard.log_image('example_image', img, 0)

    # Log plots
    fig = plt.figure()
    plt.plot(x, y, 'o')

    tensorboard.log_plot('example_plot', fig, 0)
    plt.close()
    # Log histograms
    rng = np.random.RandomState(10)
    a = np.hstack((rng.normal(size=1000), rng.normal(loc=5, scale=2, size=1000)))
    tensorboard.log_histogram('example_hist', a, 0, 'auto')

    tensorboard.close()

首先,建立一个tensorboard类,包含四个重要函数:log_scalar,log_image,log_plot和log_histogram。 我们将关注的也是这四个函数。 这些函数可以实现上文叙述的功能。

在程序的main部分,简单的演示了这些函数的用法。 其余的代码非常简单:Tensorboard类通过调用其构造函数来初始化,其中包含日志目录的路径。 构造函数依次初始化FileWriter对象。 在程序结束时,我们必须再次关闭FileWriter。

log_scalar,log_image,log_plot和log_histogram函数都将tag和global_step作为参数。 tag是要绘制的值的任意名称。 例如,你可以为loss函数设置tag =’loss’。 global_step指的是测量特定值的时间,例如时期计数或类似值。 此外,log_scalar接受数值作为其第二个参数。 这是log_scalar生成的示例标量图:

《在Pytorch和Keras等框架上自由使用tensorboard》 plot

log_image是一个类似的简单函数,它将一个numpy数组作为img参数来绘制任意图像(例如下面的例子):

《在Pytorch和Keras等框架上自由使用tensorboard》 在这里插入图片描述

log_histogram稍微复杂一些:它使用bin的bin数来计算values参数中给出的值的直方图。 计算本身就是numpy。 然后,它被送到Tensorboard:

《在Pytorch和Keras等框架上自由使用tensorboard》 在这里插入图片描述

log_plot与log_image非常相似,只是提供的输入不是image,它的figure参数需要是一个matplotlib图。 使用此函数,你可以直接在Tensorboard中显示任意matplotlib figures :

《在Pytorch和Keras等框架上自由使用tensorboard》 在这里插入图片描述

使用tensorboard

当程序 运行完成后,会在代码所在的文件夹下创建一个《在Pytorch和Keras等框架上自由使用tensorboard》文件夹,里面有一个《在Pytorch和Keras等框架上自由使用tensorboard》格式的文件,

《在Pytorch和Keras等框架上自由使用tensorboard》 在这里插入图片描述

在浏览器中打开tensorboard的正确姿势如下:
在当前目录下打开终端,输入命令:

$tensorboard  --logdir=logs   

如果出现错误,端口不可用等情况,可以指定port参数或者host参数等,参考示例:

$tensorboard --logdir=logs  --host=127.0.01  --port=8008

之后就会运行出现一个网络链接,复制粘贴到(google)浏览器中就可以。

注: 本文编译自 https://becominghuman.ai/logging-in-tensorboard-with-pytorch-or-any-other-library-c549163dee9e 内容和代码有删改。

原文作者希望通过这篇博文,帮助其他人在切换到另一个框架时可以同样使用tensorboard,而不受任何限制。 作者的GitLab上也有其他有趣的代码和项目,感兴趣的可以查看以下链接:https://gitlab.com/branislav.hollander 其中就包括了作者写的tensorboard使用代码,但是原代码中有一些错误,运行会出现错误,笔者参考大佬的代码做了一些修改,修复了这些bug,修改后的代码详见下述链接:https://github.com/LDOUBLEV/Tensorboard

    原文作者:机器学习算法工程师
    原文地址: https://www.jianshu.com/p/901910ed6bf2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞