TensorflowでMNISTデータ認識＋多層ニューラルネット＋TensorboardでEVENTS＆GRAPHS表示

#はじめに

[前回](http://qiita.com/WaterIsland/items/7438dcbd4667748f1100)は単にMNIST画像認識をやりました、という内容だった。
しかし、Tensorflowの処理結果をCUIで確認するなんて宝の持ち腐れだ。
というわけで、Tensorboardを使ってブラウザにGUI表示しますよ、が今回の課題である。

星の数ほど同じことをしているサイトがあり、それを実行した結果、気がついたことも含めて書きためていく。

#ソース

今回作ったソースのリンクを以下に貼り付ける。
[mnizst_SDG_graph.py](https://github.com/WaterIsland/DLStudy/blob/master/tensorflow/source/mine/mnist/mnist_SGD_graph.py)

> IPythonnのstartupファイルを設定しなくてもいいようにimportを追加 2016/10/08
> loss関数のcross_entropyの式を間違えていたので修正 2016/10/10



相変わらず冒頭の変数宣言は気に入らないなと思いつつ、今後の拡張性を意識してinference()・loss()・training()をクラス化している。
＃　test()はおまけで入れた程度。
＃　次回ぐらいには、モジュール化します。


# 実装の概要

グラフ(graph)、セッション(session)、スコープ(scope)、サマリー(summary)、サマリーライター(summary writer)が今回導入した概念である。


# 実行環境
ざっくり以下の環境。
・Mac OS X 10.10.5
・Python 3.5.1
・virtualenv
・IPython


# 処理内容（特筆すべき処理）
ざっくり（といいつつ割と細かく）説明すると、
1. with tf.Graph().as_default(): でグラフの開始を宣言
2. sess = tf.InteractiveSession() でセッションを作成
3. with tf.name_scope('inference') as scope: のようなブロックを使い、TensorboradのGRAPHSに表示させる要素名およびその要素に含ませる項目を列記（見た目のため、placeholder にも名前を設定）
4. tf.scalar_summary('cross_entropy', cross_entropy) で、Tensorboard の EVENTS で entropy を 'cross_entropy'という名前でサマリーとして表示するように登録
5. tf.merge_all_summaries() で、これまで登録したサマリーを集約
6. tf.train.SummaryWriter('data', graph=sess.graph) で、Tensorboard用ログを出力するパスとGRAPHSに表示させるグラフを設定
7. [前回](http://qiita.com/WaterIsland/items/7438dcbd4667748f1100)使った train_step.run を使わず、sess.run([train_step, cross_entropy], feed_dict=feed_dict) で、監視対象（cross_entropy）も一緒に渡して学習を実施
8. sess.run(summary_op, feed_dict=feed_dict) で、Tensorboard の EVENTS で表示するサマリーを取得
9. summary_writer.add_summary(summary_str, step) で、Tensorboard用ログにひたすら追記
10. summary_writer.close() で、ログをクローズ
11. sess.close() で、セッションをクローズ

# 処理内容（ここだけ気をつけて）
1. [InteractiveSession](https://www.tensorflow.org/versions/r0.11/api_docs/python/client.html#InteractiveSession)は、IPythonなどのshellライクな環境で活躍します。
2. summary_writer.close() で、ログをクローズしないと、Tensorbord の EVENTS が最後のステップまで出力されません。いくつものサイトのサンプルを実行した結果、気がついたのでメモ。ツッコミ待ち案件。
3. tf.InteractiveSession() してるので、sess.close() が必要です。セッションも withブロック使えや、という案件。

# 処理結果

こんな感じである。いい感じです。CUIの次はGUIでの結果の確認へ。
![スクリーンショット 2016-10-07 12.06.25.png](https://qiita-image-store.s3.amazonaws.com/0/143341/95cc53c9-1ec8-1ce1-87c8-1239fc497054.png)

## 処理結果（inspectしよう！）
Tensorboard で表示する前に、ログに何が出力されているかを確認できる。
```tensorborad --logdir=<絶対パス> --inspect```
表示するとこんな感じ。
graph は GRAPHS、 scalars は EVENTS に表示される内容。
![スクリーンショット 2016-10-07 12.06.47.png](https://qiita-image-store.s3.amazonaws.com/0/143341/717538bf-2c88-ed55-621a-8ba4edab94fc.png)

## 処理結果（Tensorborad を実行しよう！）
```tensorborad --logdir=<絶対パス> ```
やってしまいがちなのは、"--logdir="の後ろにログファイル名を指定することである。ディレクトリを指定しよう。
![スクリーンショット 2016-10-10 21.57.56.png](https://qiita-image-store.s3.amazonaws.com/0/143341/6d26b3fd-947c-375a-41e4-3c157a861a8d.png)


### 処理結果（Tensorborad で EVENTS を見よう！）
その後、ブラウザで http://0.0.0.0:6006/ にアクセスすれば、初期画面に EVENTS が表示される。
![スクリーンショット 2016-10-07 12.07.45.png](https://qiita-image-store.s3.amazonaws.com/0/143341/169b411c-c260-81a7-fba4-85a0475d4dd3.png)

cross_entoropy を押すと、こんな感じ。
グラフ上にカーソルを合わせると、CUIの値と同じ値になっていることがわかる。
![スクリーンショット 2016-10-07 12.07.54.png](https://qiita-image-store.s3.amazonaws.com/0/143341/bb961571-4132-2789-e369-74c2a2e24063.png)

### 処理結果（Tensorborad で GRAPHS を見よう！）
GRAPHS を押すと、こんな感じである。
プログラム中で指定した名前で表示されていることがわかるだろう。
![スクリーンショット 2016-10-07 12.08.06.png](https://qiita-image-store.s3.amazonaws.com/0/143341/9f7a3e2b-3000-0630-8629-c3e8e87cda1f.png)

んで、 inference にカーソルを合わせると、プラスボタンが表示される。
![スクリーンショット 2016-10-07 12.53.43.png](https://qiita-image-store.s3.amazonaws.com/0/143341/da106416-905a-3616-eb8c-a4a8ad482afd.png)

それを押すとこんな感じである。中身見えました。
![スクリーンショット 2016-10-07 12.09.29.png](https://qiita-image-store.s3.amazonaws.com/0/143341/7dcf9240-a9de-e1d4-6a24-4d63d4b08238.png)

調子に乗って y1 の中も見ると、MatMul(input, W1) と b1 が add され、Reluされていることがわかる。プログラム中の y1 = tf.nn.relu(tf.matmul(input_placeholder, W1) + b1) が実現できていることが確認できました。
![スクリーンショット 2016-10-07 12.09.55.png](https://qiita-image-store.s3.amazonaws.com/0/143341/8ac969c4-6571-ac57-344c-132d5e86f792.png)

＃　やろうと思えば、学習ステップごとのグラフも出力可能である。以前、調子に乗って試したらPCが悲鳴をあげたのでやめている今日。いいマシン欲しい。

というわけで、描画編は一旦終了しようと思う。
次は AutoEncoder か畳み込みネット(Convolutional Neural Net)に挑戦しよう！