合理主義的グルメブログ

学生起業家の日常をツラツラと書いています。主に食事情報です。

Tensorboardをtensorflowなしで使用する

Tensorboardって便利ですよね?
簡単に可視化できるツールとして,かなり優秀だと感じでいます.

そんなtensorboardですが, チュートリアルなどを見ると, かならずtensorflowとセットで紹介されています.

でも,こんな便利なツールなんだから, tensorflow以外のときも使いたいな~っと思いました.
tensorflowなしでtensorboardを使う方法を調べて見ました.

早速結論ですが,以下のサイトが一番直感的に使えます.

A generic tensorboard logger for scalars and histograms or distributions · GitHub

少し解説すると,TensorBoardLoggerクラスを宣言することで, 簡単にtensorboardの形式でログを取ることができます.

このソースコードは,scalar(つまり折れ線グラフ)とhistgramにしか対応していません.

import numpy as np
import tensorflow as tf

class TensorBoardLogger(object):

    def __init__(self, log_dir, session=None):
        self.log_dir = log_dir
        self.writer = tf.summary.FileWriter(self.log_dir)
        self.episode = 0
        print('TensorBoardLogger started. Run `tensorboard --logdir={}` to visualize'.format(self.log_dir))

        self.histograms = {}
        self.histogram_inputs = {}
        self.session = session or tf.get_default_session() or tf.Session()

    def log(self, logs={}, histograms={}):
        # scalar logging
        for name, value in logs.items():
            summary = tf.Summary()
            summary_value = summary.value.add()
            summary_value.simple_value = value
            summary_value.tag = name
            self.writer.add_summary(summary, self.episode)

        # histograms
        for name, value in histograms.items():
            if name not in self.histograms:
                self.histogram_inputs[name] = tf.Variable(value,validate_shape=False)
                self.histograms[name] = tf.summary.histogram(name, self.histogram_inputs[name])

            input_tensor = self.histogram_inputs[name]
            summary = self.histograms[name]
            summary_str = summary.eval(session=self.session, feed_dict={input_tensor.name:value})
            self.writer.add_summary(summary_str, self.episode)

        self.writer.flush()
        self.episode += 1

このクラスの使い方は,簡単に以下のように使えます.

logger = TensorBoardLogger(log_dir='/tmp/test')
for i in range(10):
    logger.log(
        logs=dict(
            float_test=np.random.random(),
            int_test=np.random.randint(0,4),
        ),
        histograms=dict(
            actions=np.random.randint(0,3,size=np.random.randint(5,20))
        )
    )

インスタンス宣言時に,log_dir引数に保存先のディレクトリを指定します.
.log()関数により,好きな値を保存していくことができます.

あとは保存先のディレクトリをしていして, tensorboardを起動させます.
これで,localhost:6006などに接続することで結果を確認することができます(Macだと127.0.0.1:6006かな).

docker run --rm \
    -p 6006:6006 \
    -v ${LOG_DIR}:/logs \
    -w /logs \
    denden047/tensorboard \
    tensorboard --logdir /logs

※接続先は,dockerの設定よって変わります.

サンプルのソースコードをまとめると,こんな感じです.

import numpy as np
import tensorflow as tf

class TensorBoardLogger(object):

    def __init__(self, log_dir, session=None):
        self.log_dir = log_dir
        self.writer = tf.summary.FileWriter(self.log_dir)
        self.episode = 0
        print('TensorBoardLogger started. Run `tensorboard --logdir={}` to visualize'.format(self.log_dir))

        self.histograms = {}
        self.histogram_inputs = {}
        self.session = session or tf.get_default_session() or tf.Session()

    def log(self, logs={}, histograms={}):
        # scalar logging
        for name, value in logs.items():
            summary = tf.Summary()
            summary_value = summary.value.add()
            summary_value.simple_value = value
            summary_value.tag = name
            self.writer.add_summary(summary, self.episode)

        # histograms
        for name, value in histograms.items():
            if name not in self.histograms:
                self.histogram_inputs[name] = tf.Variable(value,validate_shape=False)
                self.histograms[name] = tf.summary.histogram(name, self.histogram_inputs[name])

            input_tensor = self.histogram_inputs[name]
            summary = self.histograms[name]
            summary_str = summary.eval(session=self.session, feed_dict={input_tensor.name:value})
            self.writer.add_summary(summary_str, self.episode)

        self.writer.flush()
        self.episode += 1

logger = TensorBoardLogger(log_dir='/tmp/test')
for i in range(10):
    logger.log(
        logs=dict(
            float_test=np.random.random(),
            int_test=np.random.randint(0,4),
        ),
        histograms=dict(
            actions=np.random.randint(0,3,size=np.random.randint(5,20))
        )
    )