TensorFlowの基本概念メモ

これまで[Slim](https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/slim)、[Keras](https://keras.io/ja/)、[TFLearn](http://tflearn.org/)といったライブラリを使って楽をしていたが、少しだけ素のTensorFlowを触らないといけない感じがしてきたので、後で見返しそうなものをメモ。

## 基本構造

### Graph

計算の流れを表す設計図

### Session

Graphに基づいて実際に計算を実行する部分

*Graphがソースコードで、Sessionがコンパイラのようなものだと思う*
*とりあえず、Graphに定義して、Sessionで実行しなければならないと覚えておけばよさそう*

実行例

```
>>> import tensorflow as tf

>>> matrix1 = tf.constant([[3., 3.]])
>>> matrix2 = tf.constant([[2.],[2.]])
>>> product = tf.matmul(matrix1, matrix2)

>>> print(product)

Tensor("MatMul:0", shape=(1, 1), dtype=float32)

>>> with tf.Session() as sess:
>>>   result = sess.run(product)
>>>   print(result)

[[ 12.]]
```

Graphのほうは明示的じゃないけど、これでデフォルトのGraphにmatrix1, matrix2, productが追加されているらしい

### Tensor

多次元配列

### Edge

Tensorのこと

### Node

TensorとTensorを結ぶ計算

*EdgeとNodeは逆のほうがしっくりきそうだけど、このへんはあまり気にしなくていいと思う*

### Variables

変数
型（type）や形（shape）を持つ
異なる型は混ぜるな危険
Graphで定義しただけではダメで、Sessionの最初に初期化（initialize）しないと使えない

実行例

```
>>> a = tf.Variable(0.0)
>>> b = tf.constant(1)
>>> sum = tf.add(a, b)

ValueError: Tensor conversion requested dtype float32 for Tensor with dtype int32: 'Tensor("Const_4:0", shape=(), dtype=int32)'

>>> state = tf.Variable(0, name="counter")
>>> one = tf.constant(1)
>>> new_value = tf.add(state, one)
>>> update = tf.assign(state, new_value)
>>> init_op = tf.initialize_all_variables()

>>> sess = tf.Session()
>>> print(sess.run(state))

tensorflow.python.framework.errors.FailedPreconditionError: Attempting to use uninitialized value counter

>>> sess.run(init_op)
>>> print(sess.run(state))

0

>>> for _ in range(3):
      sess.run(update)
      print(sess.run(state))

1
2
3

>>> sess.close()

>>> t = tf.Variable([[[1, 1, 1], [2, 2, 2]], [[3, 3, 3], [4, 4, 4]]])
>>> shape = tf.shape(t)

>>> with tf.Session() as sess:
>>>   sess.run(tf.initialize_all_variables())
>>>   print(sess.run(shape))

[2 2 3]
```

### Placeholder

変数に後から初期値を入れるための目印
いわゆるプレースホルダー

実行例

```
>>> input1 = tf.placeholder(tf.float32)
>>> input2 = tf.placeholder(tf.float32)
>>> output = tf.mul(input1, input2)

>>> with tf.Session() as sess:
>>>   print(sess.run([output], feed_dict={input1:[7.], input2:[2.]}))

[array([ 14.], dtype=float32)]
```

## TensorBoard

TensorFlowで実行されていることを可視化するためのツール

### 経過の保存

- tf.scalar_summary(tags, values, collections=None, name=None)
 - 数値データの保存
 - AccuracyやLossなど
- tf.histogram_summary(tag, values, collections=None, name=None)
 - 活性・勾配・重みの分布など
- tf.nn.zero_fraction(value, name=None)
 - sparsityなど
 - tf.scalar_summary('sparsity', tf.nn.zero_fraction(z))のように使用
- tf.image_summary(tag, tensor, max_images=3, collections=None, name=None)
 - 重みや結果を画像として可視化
- tf.merge_all_summaries(key='summaries')
 - Summaryを1つずつrunするのは面倒なので、これでまとめる
- tf.train.SummaryWriter
　- Summaryの保存を扱うクラス
- tf.train.SummaryWriter.add_summary(summary, global_step=None)
 - Summaryをディスクに保存するメソッド

### 確認

以下でTensorBoardが起動する

```
$ tensorboard --logdir=/path/to/log
```

logdirに保存されている".\*tfevents.\*"という形式に一致する名前のファイルがログ

### 一連の操作をGraph上でまとめる

```
with tf.name_scope('name_for_operations'):
  pass
```

## 変数の保存と読み込み

tf.train.Saverオブジェクトで管理

```
saver = tf.train.Saver()

save_path = saver.save(sess, "/tmp/model.ckpt")

saver.restore(sess, "/tmp/model.ckpt")
```

## 参考

[TensorFlowを算数で理解する](http://qiita.com/icoxfog417/items/fb5c24e35a849f8e2c5d)
[TensorFlow : Get Started : 基本的な使い方](http://tensorflow.classcat.com/2016/02/03/tensorflow-get-started-basic-usage/)
[TensorFlowとTensorBoardでニューラルネットワークを可視化](http://qiita.com/sergeant-wizard/items/fdf4d64a0d221a81da34)
[TensorBoardでデータフローを可視化する](http://qiita.com/sergeant-wizard/items/c98597b8add04b8eea0b)
[TensorFlow : How To : 変数: 作成、初期化、保存そしてロード](http://tensorflow.classcat.com/2016/02/09/tensorflow-how-tos-variables/)