概要
TensorFlowの公式チュートリアルMNIST For ML BeginnersをTensorBoardで可視化して、TensorFlowとTensorBoardを理解しようとしたので、その記録です。
作成したコードはGitHubにあります。
環境
以下のプログラムは、次の環境で動作確認をしています。
Python 2.7.13
tensorflow (1.4.0)
tensorflow-tensorboard (0.4.0rc3)
公式のチュートリアル
MNIST For ML Beginnersを和訳しつつ、そのままコードにすると次のようになります。人工知能初心者の私には、このままではわかりにくかったので、TensorBoardを追加したいと考えました。
# coding:utf-8
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)
# placeholderは、値(テンソル)が入力される場所
# [None, 784]は2次元のテンソル。Noneは次元の指定なしの意味
x = tf.placeholder(tf.float32, [None, 784])
# Variableは変更可能なテンソル
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
# xW+bを計算。yはNN(ニューラルネットワーク)の出力として使う
# ソフトマックス関数を用いることで、xW+bの各要素を0~1に変換している
y = tf.nn.softmax(tf.matmul(x, W) + b)
# y_は、教師データやテストデータの正解が入力されるplaceholder
y_ = tf.placeholder(tf.float32, [None, 10])
# クロスエントロピーはコスト関数
# y(教師データの入力からNNを用いて求めた出力)とy_(教師データの正解)のクロスエントロピーを計算して、正解度をチェック
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
# 最急降下法を用いてクロスエントロピーの最小化を図る
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
# すべての変数を初期化する準備
init = tf.global_variables_initializer()
# Sessionを初期化して開始
# Sessionが、上で定義したNNのグラフ(placeholderとvariableの接続関係)と計算資源(CPU・GPU)をつないでくれる
sess = tf.Session()
sess.run(init)
# 1000回学習させる
for i in range(1000):
batch_xs, batch_ys = mnist.train.next_batch(100) # データを所得
# feed_dictを用いて、placeholderに渡す入力データを指定する
sess.run(train_step, feed_dict={x: batch_xs, y_: batch_ys})
# 学習させた後のNNが、未知のデータを正しく分類できるかの評価基準を設定
correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))
# correct_predictionは、[True, False, True, True, ・・・]といったデータ構造なので、これを0(False),1(True)に対応付けて、その平均値を計算
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
print(sess.run(accuracy, feed_dict={x: mnist.test.images, y_: mnist.test.labels}))
ちなみに、実行すると正解率0.91ぐらいが表示されます。
TensorBoardの導入
TensorBoardで扱うデータを作成するために、上のプログラムのsess.run(init)の後に次の行を追加します。
summary_writer = tf.summary.FileWriter('mnist1_data', graph=sess.graph)
こうすることで、プログラム実行時にプログラムと同じディレクトリに'mnist1_data'というディレクトリを作り、そこにTensorBoardに必要なデータを保存するようになります。
プログラム実行後、次のようにTensorBoardを実行して、http://localhost:6006にアクセスすることでグラフを確認することができます。
$ python mnist1-tensorboard.py
$ tensorboard --logdir=/ディレクトリの絶対パス/mnist1_data
これだけではわかりにくいので、次のようにplaceholderとvariableに名前をつけていきます。
x = tf.placeholder(tf.float32, [None, 784], name="x")
W = tf.Variable(tf.zeros([784, 10]), name="W")
b = tf.Variable(tf.zeros([10]), name="b")
y_ = tf.placeholder(tf.float32, [None, 10], name="y_")
これを実行すると次のようになり、それぞれに名前がついた状態になります。
こうすることで、一番下から入力xが入り、その後MatMulを用いてxWを計算し、さらにbをaddする・・というように流れが少しわかるようになってきました。
しかし、グラフが細かすぎて見にくいので、次のようにグラフをまとめたい処理の直前にtf.name_scopeを追加して処理をまとめます。
# クロスエントロピーの計算をname_scopeでまとめる
with tf.name_scope("cross-entropy"):
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y), reduction_indices=[1]))
# 最急降下法の計算をname_scopeでまとめる
with tf.name_scope("training"):
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)
先ほどまでより、非常に見やすくなりました。
この結果のグラフから、MNIST For ML Beginnersでは、
入力xをy=aW+bとして出力を求め、クロスエントロピーを用いて正解y_との比較を行ってるいることがわかります。
また、trainingでは、クロスエントロピーが最小になるWとbを見つけるために、すべてのデータを所得していることがわかります。
まとめ
MNISTチュートリアルを少し修正してあげるだけで、簡単にTensorBoardで可視化できることがわかりました。
自分のような初心者の方の理解の助けになれば幸いです。