TensorFlowを算数で理解する

TensorFlowは主に機械学習、特に多層ニューラルネットワーク(ディープラーニング)を実装するためのライブラリになりますが、その基本的な仕組みを理解するのにそうした難しい話は特に必要ありません。

本記事では、TensorFlowの仕組みを、算数程度の簡単な計算をベースに紐解いていきたいと思います。

## TensorFlowの特徴

初めに、TensorFlowの特徴についてまとめておきたいと思います。
TensorFlowは、その名前の通りTensor(多次元配列、行列などに相当)のFlow(計算処理)を記述するためのツールです。その特徴としては、以下のような点が挙げられます。

* スケーラビリティ
 * PC、サーバー、はてはモバイル端末まで、各マシンのリソースに応じてスケールする。つまり、低スペックなものでもそれなりに動くし、GPUを積んだハイスペックなサーバーであればそのリソースをフルに活用した計算が可能ということです。この「計算」は機械学習に限らないため、大規模な行列演算等が必要なシーンでも同様に活用することができます。
 * これが、特徴として挙げられているポータビリティとパフォーマンスに寄与しています。
* 簡易/柔軟な記述方式
 * これは割とどのライブラリでも言われることですが、簡易且つ柔軟な記法が可能です
 * 自動微分の機能が内蔵されており、計算処理と目的関数を定義するだけで学習できるのは強みと言えると思います
* 多数のプログラミング言語からの利用
 * 現在(2015/11/12)はC++/Pythonのみですが、将来的にはSWIGにより他言語からも利用可能なインタフェースが提供される予定です
* 可視化機能
 * TensorBoardという構築した計算フローの可視化機能が付属しています

それとやはり特筆すべきなのは、Googleの中の各種サービス(検索ランキング、画像分類)で使用された実績があるということだと思います。

上記の内容については、公式ページの以下の部分に詳しく記載されているため、ご参考ください。

* [TensorFlow Home/TensorFlow Features](http://tensorflow.org/)
* [Additional Resources/Example Uses](http://tensorflow.org/resources/uses.html#example-uses)


## TensorFlowの仕組み

TensorFlowの仕組みは、以下のようになっています。

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/22f25697-e54e-5928-defc-ea20cd077187.png)

TensorFlowのGraphは、Nodeとedgeで構成されます。
Nodeは計算処理(図中緑の円)か、末端における入力/出力(図中青色の円)を表します。edgeは、計算結果の値である多次元配列、つまりtensorを表します。
そして、GraphはSessionに割り当てて計算を行います。Sessionは、計算可能になったNode(edgeから送られてくる計算結果がすべてそろったNode)を非同期/並列に計算していきます。計算に際しては、どのDevice(cpu/gpu)で行うのかの割振りも行います。

これが、TensorFlowにおける計算処理の全貌となります。公式ページの以下の部分に記述されているため、ご参考ください。

[Getting Started](https://www.tensorflow.org/get_started/get_started)

また、末端における入力/出力、具体的にはファイルの読み込みや計算結果の保存などについては、以下の箇所にまとまっています。

* ファイル読み込み等: [Tensorflow How to/Reading data](http://tensorflow.org/how_tos/reading_data/index.html#reading-data)
* 変数の初期化/保存/読み込みについて: [Tensorflow How to/Variables: Creation, Initialization, Saving, and Loading](http://tensorflow.org/how_tos/variables/index.html#variables-creation-initialization-saving-and-loading)

何れも実際にデータを使って計算する際はよく利用する処理なので、要確認です。


## TensorFlowによる演算

では、実際にTensorFlowを利用して算数・・・簡単な演算を行ってみたいと思います。
今回ご紹介するコードは、以下のリポジトリにまとめています。

[icoxfog417/tensorflow-arithmetic](https://github.com/icoxfog417/tensorflow-arithmetic)

[tensorflow-arithmetic.ipynb](https://github.com/icoxfog417/tensorflow-arithmetic/blob/master/tensorflow-arithmetic.ipynb)から、iPython notebookを参照することができます。

## インストール

インストール方法については、以下を参照してください。`pip install`で入れるのが推奨です。

[Getting Started/Download and Setup](http://tensorflow.org/get_started/os_setup.html#download-and-setup)

* 0.6.0から、Python3に対応しました([Release 0.6.0](https://github.com/tensorflow/tensorflow/blob/master/RELEASE.md#release-060))。
* 0.12からWindowsにも対応しました([TensorFlow 0.12 が Windows をサポート](https://developers-jp.googleblog.com/2016/12/tensorflow-0-12-adds-support-for-windows.html))

## 演算

では、実際にTensorFlowを使って計算してみます。
最初は、以下の式を書いてみます(算数というにはちょっと数学よりですが)。

$$
y = x^2 + b
$$

TensorFlowで書いた式が、以下になります。

```py
import tensorflow as tf

def x2_plus_b(x, b):
    _x = tf.constant(x)
    _b = tf.constant(b)
    result = tf.square(_x)
    result = tf.add(result, _b)
    return result
```

図で表すと以下のような感じになります。

![image](https://qiita-image-store.s3.amazonaws.com/0/25990/5d39aa15-6408-e034-64e0-bb1ad76aab2b.png)

これで式は完成したので、実際に`Session`を使って実行してみましょう。

```
with tf.Session() as sess:
    result = sess.run([x2_plus_b(2., 3.)])
    print(result)
```

実行結果(`print`の出力)は以下のようになります。

```
[7.0]
```

$2^2 + 3 = 7$なので、きちんと計算できていることがわかります。利用可能な演算用のメソッドは、ドキュメントに記載されています。

[TensorFlow API/Math](http://tensorflow.org/api_docs/python/math_ops.html#math)

また、引数は`placeholder`という形で与えることもできます。

```
import tensorflow as tf

p_x = tf.placeholder(tf.float32)
p_b = tf.placeholder(tf.float32)
p_x2_plus_b = tf.add(tf.square(p_x), p_b)

with tf.Session() as sess:
    result = sess.run([p_x2_plus_b], feed_dict={p_x: [2.], p_b: [3.]})
    print(result)
```

`placeholder`には、`Session`の実行時に`feed_dict`を利用して値を受け渡します。


## 可視化

TensorFlowには、TensorBoardという強力なビジュアライゼーションツールが付いている点も特徴の一つになっています。これを使って、式の計算結果を可視化してみましょう。

`pip`でインストールしていれば、`tensorboard`というコマンドが実行可能になっているはずです。これを利用して可視化を行うのですが、まずは可視化する対象の値を出力していきます。

```py
import tensorflow as tf

def monitor_calculation(x, b):
    title = "b = {0}".format(b)
    c = x2_plus_b(float(x), float(b))
    s = tf.scalar_summary(title, c)
    m = tf.merge_summary([s])  # if you are using some summaries, merge them
    return m

with tf.Session() as sess:
    writer = tf.train.SummaryWriter("log", graph_def=sess.graph_def)    
    xaxis = range(-10, 12)

    for b in range(3):
        for x in xaxis:
            summary_str = sess.run(monitor_calculation(x, b))
            writer.add_summary(summary_str, x)
```

ポイントとしては、`tf.scalar_summary`で計算した値をsummaryしておく点です。こうして計算したsummaryを、`tf.train.SummaryWriter`で書き出していきます。

上記の処理を実行すると、`log`フォルダ内にファイルが出力されます。その後に、`tensorboard`を以下のように実行します。

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

(パスは絶対パスが確実)。そうすると、以下のようにグラフが表示されると思います(※起動してから表示されるまでに結構時間がかかります。ずっと表示されないと思っていたら唐突に出てきたりすることが結構ありました)。

<img width="370" alt="graph.png" src="https://qiita-image-store.s3.amazonaws.com/0/25990/0d7dbeee-98d1-74a6-424e-119b39ba027e.png">

これで、計算した値をプロットするといったことが簡単にできます。機械学習時には、誤差や精度などをプロットすることで学習状況を把握することもできるでしょう。

また、「GRAPH」のタブでは、構築した式(=グラフ)をビジュアライズしたものを見ることができます。

<img width="180" alt="graph.png" src="https://qiita-image-store.s3.amazonaws.com/0/25990/2bc971ed-3cc6-660a-255e-cf2ff677be7c.png">

グラフを描画する際のテクニック(名称空間を使って処理を作ってまとめたりなど)は、以下に記載されているので参考にしてください。

[TensorBoard: Graph Visualization](http://tensorflow.org/how_tos/graph_viz/index.html#tensorboard-graph-visualization)

また、TensorBoardの使い方については以下を参考にしてください。

[TensorBoard: Visualizing Learning](http://tensorflow.org/how_tos/summaries_and_tensorboard/index.html#tensorboard-visualizing-learning)

summaryの書き出し方法については、mnistのサンプルが参考になります。`mnist.py`の方に処理の記述があり(ここで`scalar_summary`などを使用)、`fully_connected_feed.py`の方で`mnist.py`で定義した処理を組み合わせて実行処理を行っています。

* [mnist.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/mnist.py)
* [fully_connected_feed.py](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/examples/tutorials/mnist/fully_connected_feed.py)


以上が、TensorFlowの基本的な仕組みになります。本内容は、[Getting Started](http://tensorflow.org/get_started/index.html)の内容をさらったような形となっています。

これからTensorFlowで機械学習をやってみた系の記事がどんどん出てくると思うので、それらを理解するための一助になれば幸いです。