TensorFlowの基礎

きっと今後も似たような話をすることが多そうなのでQiitaのプレゼンテーションモードにしてみようとも思ったらうまくいかなかったので、結局PDF化したものを[SpakerDeckに用意しました](https://speakerdeck.com/rindai87/tensorflowfalseji-chu)が、それなりに書いたのでQiitaの方も残しておきます。

[SpeakerDeck](https://speakerdeck.com/rindai87/tensorflowfalseji-chu)にあるものと内容としてはほぼ同じです。


## TensorFlowの概要

まずはTensorFlowの概要っぽい部分のお話です。

### TensorFlowとは？

- [TensorFlowのサイト](https://www.tensorflow.org/)
- Googleがオープンソース化した機械学習ライブラリ
- 2015年11月に公開
- Google社内で実際に使われているものである（らしい）
  - 私はGooglerではないので伝聞形式とする

### TensorFlowのモデル

![graph.png](https://qiita-image-store.s3.amazonaws.com/0/1046/8f408d89-fec6-d7ac-c9af-8e90a809a23b.png)

1. 学習モデルをTensor計算のグラフとして定義する
  - Tensorは多次元配列のこと
  - Tensorが流れる計算グラフを作るのでTensorFlowという名前になったかと
2. 学習を実際にどう行うかも定義する
  - 学習の評価方法
  - 最適化の方法
  - CPUで計算 or GPUで計算
  - スタンドアロン or 分散
  - etc...
3. 定義した計算をデバイス上で実行させる

### TensorFlowの歴史

この一年で急速に、かつ着実に機能を追加してきています。

![history.png](https://qiita-image-store.s3.amazonaws.com/0/1046/dea19019-6f88-662f-8a80-5a195e8cdbd5.png)

### TensorBoardなどのツール

TensorBoardはTensorFlowのポイントの１つです。グラフを可視化してくれたり、処理の経過を可視化してくれたり様々な機能を提供してくれる便利ツールです。

![tensorboard.png](https://qiita-image-store.s3.amazonaws.com/0/1046/8622cfc0-fc57-d0fe-8ffe-9072a4ea2bc7.png)


### その他のTensorFlow情報

下記は会場でのみお話します。某所から共有頂きました資料をベースにお話します。

- Google内でのTensorFlowの利用例
- TensorFlowの活用事例
- TensorFlowコミュニティ
- 企業でのTensorFlow

## TensorFlowの基本

続いて、TensorFlowの技術的な部分の基本をお話します。
以前、DevFest Tokyoで話した[資料](https://speakerdeck.com/rindai87/talk-about-ml-and-dl-for-happy-engineers-life)からの抜粋となりますので、興味が湧いた方は[フルバージョン](https://speakerdeck.com/rindai87/talk-about-ml-and-dl-for-happy-engineers-life)も参照してみてください。

### TensorFlowの超基本

TensorFlowはグラフベースで計算を行います。

![base.png](https://qiita-image-store.s3.amazonaws.com/0/1046/d964384b-da45-a344-fdfe-f1d3b818eff3.png)


### TensorFlowのパラダイム

- はじめにテンソル（Tensor）の演算グラフを作ります
- グラフの事項単位をセッション（Session）と言います
- 定数(constant)、変数(Variable)、プレースホルダ
- (Placeholder)を宣言できます
- 作ったグラフはデバイス（CPUやGPU）に展開され実行されます
- 分散処理も実行可能です

### ここだけ押さえればTensorFlowの基本っぽいのが分かる簡単な例

1. 足し算
  - 演算（Operation）
2. カウントアップ
  - 変数（Variable）
3. 入力値を色々と変える
  - プレースホルダー（Placeholder）
4. セッションを使う
  - セッション（Session）
5. 高ランクなテンソルの演算
  - テンソル（Tensor）

### 例1：足し算 - Operation

```python
# （定数）+（定数）の足し算
import tensorflow as tf

# 入力となる定数の定義
x = tf.constant(1, name="x")
y = tf.constant(2, name="y")

add_op = tf.add(x, y)

with tf.Session() as sess:
    print(sess.run(add_op))
```

演算がグラフのノードとなるようなグラフを定義します。

![ex1.png](https://qiita-image-store.s3.amazonaws.com/0/1046/f9c93d96-eddc-9338-ec67-88d2d5341d9b.png)

### 例2：カウントアップ - Variable

```python
import tensorflow as tf

# cntという変数（カウンター）の定義
cnt = tf.Variable(0, name="cnt")
inc = tf.constant(1, name="inc")

# カウントアップ
add_op = tf.add(cnt, inc)

# cntの値を更新
up_op = tf.assign(cnt, add_op)

with tf.Session() as sess:
    # 変数を使う場合はまず初期化が必要
    sess.run(tf.global_variables_initializer())

    # カウントアップを計3回実行
    print(sess.run(up_op))
    print(sess.run(up_op))
    print(sess.run(up_op))
```

代入可能な箱としてVariableというものがあります。計算結果を保持させることを目的に利用します。計算を始める前に初期化が必要です。

![ex2.png](https://qiita-image-store.s3.amazonaws.com/0/1046/bd55b39f-70b0-d219-19b8-bfab1bdae5db.png)

### 例3：入力値を色々と変える - Placeholder

```python
import tensorflow as tf

# 定数の定義
x = tf.constant(1, name="x")
# プレースホルダーという箱を用意する
y = tf.placeholder(tf.int32, name="y")

# x+yの演算を定義
add_op = tf.add(x, y)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    # プレースホルダーには、feed_dictという仕組みを通じて値を外挿できる
    print(sess.run(add_op, feed_dict={y:1}))
    print(sess.run(add_op, feed_dict={y:3}))
```

Placeholderは実行時にfeed_dictという仕組みを通じて値を外挿できる仕組み。つまり、入力データの箱として利用します。

![ex3.png](https://qiita-image-store.s3.amazonaws.com/0/1046/c04c652b-e6a5-6f97-29e8-a1d2fa88a188.png)


### 例4：セッションを使う - Session

```python
import tensorflow as tf

cnt = tf.Variable(0, name="cnt")
inc = tf.constant(1, name="inc")

add_op = tf.add(cnt, inc)
up_op = tf.assign(cnt, add_op)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(up_op))
    print(sess.run(up_op))
    print(sess.run(up_op))


with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(up_op))
    print(sess.run(up_op))
    print(sess.run(up_op))
```

![ex4.png](https://qiita-image-store.s3.amazonaws.com/0/1046/3b70b0e0-cdf3-0206-1950-3283bef5e8f4.png)


### 例5：高ランクなテンソルの演算 - Tensor![ex5-2.png](https://qiita-image-store.s3.amazonaws.com/0/1046/f04ab059-c1cb-a9df-d0ea-62bde5a11146.png)


```python
import  tensorflow as tf

# ランク2のテンソル（行列）の定義
x = tf.constant([[1,2], [1,2]], tf.int32, name="x")
y = tf.constant([[3,4], [3,4]], tf.int32, name="y")

# 行列の足し算
add_op = tf.add(x, y)

with tf.Session() as sess:
    print(sess.run(x))
    print(sess.run(y))
    print(sess.run(add_op))
```

これまでは単なる数値の計算を行っていましたが、テンソルは多次元配列であり、その特殊な形式として数値があります。すなわち、ここまでと同じ処理を多次元に拡張しても動作します。

![ex5-1.png](https://qiita-image-store.s3.amazonaws.com/0/1046/656b29cd-095b-ccdc-8d8f-f7050699e2fe.png)


今回はランク2のテンソル、すなわち行列の足し算を行っています。


## 次にどうする？

残念ながらここまででディープラーニングや機械学習ができるようになったわけではありませんが、TensorFlwoの基本中の基本は理解頂けたかと思います。より深くTensorFlow自体や、あるいは深層学習について学びたい方はのTensorFlow本家の[チュートリアル](https://www.tensorflow.org/get_started/get_started)を進めていくのが良いでしょう。