[Keras/TensorFlow] KerasでTensorBoardの利用

# 目的
ゼロからKerasとTensorFlow(TF)を自由自在に動かせるようになる。
そのための、End to Endの作業ログ(備忘録)を残す。
※環境はMacだが、他のOSでの汎用性を保つように意識。
※アジャイルで執筆しており、精度を逐次高めていく予定。


# 環境
- Mac: 10.12.3
- Python: 3.6
- TensorFlow: 1.0.1
- Keras: 2.0.2


# To Do
[Keras(Tensorflow)の環境構築](http://qiita.com/agumon/items/4d7826c2c39d0af868bd)
[KerasでMINSTの学習と予測](http://qiita.com/agumon/items/4c6ff24bfd77a5c8101d)
[KerasでTensorBoardの利用](http://qiita.com/agumon/items/114da6921c5dc4f7d7f9) <---いまココ
[Kerasで重みファイルの保存/読み込み](http://qiita.com/agumon/items/91f897b7f260f6aeca95)
[Kerasで自前データの学習と予測](http://qiita.com/agumon/items/ab2de98a3783e0a93e66) 
[Kerasで転移学習](http://qiita.com/f2um2326/items/60f7bcc8ae26b5004a3a#_reference-5d15f52415912c9c2182)


# 参考
http://qiita.com/supersaiakujin/items/568605f999ef5cc741be


# 流れ
TensorBoardを表示されるためには、モデルを学習した時に出力されるlogファイルが必要になる。そのため、log用ディレクトリの作成とサンプルスクリプトにlog吐き出しを追加する必要がある。
ここでは、logのディレクトリの作成、サンプルファイルの作成と実行、TensorBoardを開く。


# log用ディレクトリの作成

```
mkdir ~/tflog
```

# サンプルファイル作成
~/にmnist_mlp_tb.pyを配置


こちらのファイルの以下をベースは変更した。
https://github.com/fchollet/keras/blob/master/examples/mnist_mlp.py

スクリプト中の### add for TensorBoard と ### で囲まれた部分が追加箇所。


```py:mnist_mlp_tb.py

from __future__ import print_function

import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.optimizers import RMSprop


batch_size = 128
num_classes = 10
epochs = 3

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(60000, 784)
x_test = x_test.reshape(10000, 784)
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = keras.utils.to_categorical(y_train, num_classes)
y_test = keras.utils.to_categorical(y_test, num_classes)


### add for TensorBoard
import keras.callbacks
import keras.backend.tensorflow_backend as KTF
import tensorflow as tf

old_session = KTF.get_session()

session = tf.Session('')
KTF.set_session(session)
KTF.set_learning_phase(1)
### 

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(10, activation='softmax'))

model.summary()

model.compile(loss='categorical_crossentropy',
              optimizer=RMSprop(),
              metrics=['accuracy'])



### add for TensorBoard
tb_cb = keras.callbacks.TensorBoard(log_dir="~/tflog/", histogram_freq=1)
cbks = [tb_cb]
###


history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    
                    ## add 1 line
                    callbacks=cbks,
                    
                    validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])


### add for TensorBoard
KTF.set_session(old_session)
###
```

ポイントはログの吐き出し先の指定

```
tb_cb = keras.callbacks.TensorBoard(log_dir="~/tflog/", histogram_freq=1)
```


# サンプルファイル実行
```
spyder ~/mnist_mlp_tb.py
```
実行ボタン▶を押す。


# TensorBoardを開く
ターミナルでtensorboardを起動する。
この時にlogディレクトリのパスを与える。

```
tensorboard --logdir=~/tflog/
```

ブラウザで以下に接続するとTensorBoardが表示される。

```
localhost:6006
```

以下が表示される。
<img width="1069" alt="tb_main.png" src="https://qiita-image-store.s3.amazonaws.com/0/175092/46d1b60e-6b60-8a82-e7ee-832524557835.png">



# TensorBoardの表示を理解
まずはGRAPHSタブの理解。公式サイトにはいろいろ書いてあり、読解を試みる。
https://www.tensorflow.org/get_started/graph_viz
日本語：http://tensorflow.classcat.com/2016/02/13/tensorflow-how-tos-graph-visualization/

気になっているのは：

- ブロック(ノード)の意味
- サブブロック(ノード)の意味
- ブロックの色の意味
- 線(リンク)の意味
- 線の太さの意味
- 繋がり方の意味


<img width="1072" alt="tb_graphs_00.png" src="https://qiita-image-store.s3.amazonaws.com/0/175092/2f56edac-05be-1653-2541-575d626616f2.png">

公式サイトから、オブジェの意味を理解してみる。

<img width="749" alt="スクリーンショット 2017-04-10 16.35.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/175092/379c0907-2715-0f00-4336-b9993d087dea.png">

dense_1のブロックをクリックすると、以下が展開される。そもそもdense_1の基は
model.add(Dense(512, activation='relu', input_shape=(784,)))
であり、ツリー構造を下から上へ辿っていくと、kernelがおそらく入力画像?でbiasと加算してRelu関数に渡される流れ、になっていることが分かる。


<img width="610" alt="tb_graphs_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/175092/18a9af86-7277-e80a-a828-0b83a66969d5.png">


# 執筆中