tensorflow 2.0 の紹介（日本語訳）

Define-by-run である Eager Execution がデフォルトとなり、 API も大きく変わりそうな tensorflow 2.0。
紹介の動画が詳しくそれらを説明してくれているので ~~英語のリスニング練習のために~~ 大まかな内容を日本語に書き起こしました。
[![TensorFlow2.0](http://img.youtube.com/vi/WTNH0tcscqo/0.jpg)](https://www.youtube.com/watch?v=WTNH0tcscqo)

スクリーンショットはすべて上記動画のもので文章は基本的にはそれらの要点を引用し訳したものとなります。
訳は意訳で、細かい部分は書いていません。
動画の意図と異なる部分などありましたらご連絡ください。

# 最初に
（このセクションは動画の翻訳ではありません）
この動画では eager execution (eager-mode) の話が沢山出てきます。
eager execution を理解するには Define-and-run と Define-by-run の違いを理解しておく必要があります。

- **Define-and-run**: 計算グラフを定義(Define)してからデータを流し込み(run)結果を得る
- **Define-by-run**: python の通常コードのように、 `x + y` とグラフ定義をすると同時にグラフが実行されて結果が得られる

従来の tensorflow は Define-and-run で、 PyTorch は Define-by-run です。
eager execution は tensorflow で Define-by-run を可能にする仕組みです。

# 概要
すばやく理解できるよう、先に動画後半のまとめスライドです。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/076602ff-0828-8231-ca24-0b5e48e53b84.png)](https://youtu.be/WTNH0tcscqo?t=734)

- 「簡単に使える」を重要視
    - クリーンな API
    - オブジェクト指向的な書き方
    - python 的な書き方
    - eager execution がデフォルトに
    - パフォーマンスのため graph-mode も混在して使える

preview が今年の末、その後正式版が2,3週間後(few weeks later)にリリースされる

# なぜ 2.0 を作るのか
PyTorch の追い上げがすごい。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/8465dd07-5314-ea76-b26e-3319db4dfe22.png)](https://youtu.be/WTNH0tcscqo?t=54)

PyTorch と比較すると、以下の点で従来の tensorflow は辛い。これらを2.0では解決したい。

- 問題1: PyTorch の方がシンプルでわかりやすい
    - eager execution をデフォルトにする
- 問題2: PyTorch のほうが python 的
    - よりオブジェクト指向的にしてグローバルな状態をへらす
- 問題3: PyTorch のほうがクリーン（tensorflow は同じような関数がたくさんあったり）
    - いろいろ消すぜ



# 問題1: PyTorch の方がシンプルでわかりやすい
## (Define-by-run な) eager-mode がデフォルトに
(Define-by-run な) PyTorch のコードはとてもシンプル
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/ca440d85-5681-254b-d7cf-102384d6bf80.png)](https://youtu.be/WTNH0tcscqo?t=83)

(Define-and-run な) Tensorflow だとこんなに大変
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/ef91b652-a703-dec4-a94d-465cb133aa03.png)](https://youtu.be/WTNH0tcscqo?t=89)

従来の tensorflow はその他以下のような問題点も。
（コードは動画参照）

- ノードの実行順は保証されないので、不定な結果を出すグラフを作れてしまう
- nan などの値が作られるときにどこでそれがおこっているかわからない
    - 問題がグラフを作るところに有ったとしてもそれが発覚するのはグラフを実行するときだから
    - デバグのためのノード（tf.Printとか）はあるが使い方がトリッキーだ
- 同様の理由で、速度のプロファイリングを取るのも難しい

そこで tensorflow 2.0 ではこうなる。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/a552606c-c53e-73f0-2dee-66e70133f5ee.png)](https://youtu.be/WTNH0tcscqo?t=198)

すでに実装されている eager execution がデフォルトになる。

## eager-mode と graph-mode を混合して使用できる
- (Define-and-run の) graph-mode にも利点がある
    - パフォーマンスが良い
        - 特に Deep なモデルで小さなバッチサイズの場合
    - XLA を使うことでより速度・メモリ使用量のパフォーマンスを高められる
        - 複数のオペレーションをマージして一つの演算にしたり
    - 様々なデバイスや環境に移植しやすい

tensorflow 2.0 では eager-mode と graph-mode を混ぜて使える。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/d6b949d1-585d-5001-a52e-016dd4061f54.png)](https://youtu.be/WTNH0tcscqo?t=268)

`@tf.contrib.eager.defun` を使うことである関数のみグラフモードで実行することが可能
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/53ab70b5-2865-7f31-7656-bdad28ea6691.png)](https://youtu.be/WTNH0tcscqo?t=298)

更に autograph を使うことで通常の python 関数を tensorflow の Graph にできる。
eager に実行すれば eager-mode で実行される。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/8208ec22-a718-2bad-a3fe-33d728d5e809.png)](https://youtu.be/WTNH0tcscqo?t=307)

一方 graph　の中で実行すれば graph-mode で実行される。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/dc5c5a1a-ae9f-144a-b66d-d22cd761f9dc.png)](https://youtu.be/WTNH0tcscqo?t=340)

ループを使った複雑な関数等でも Autograph は使える。
[![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/a6ba0483-4760-53ea-e88a-9da5c4d638c3.png)](https://youtu.be/WTNH0tcscqo?t=364)


# 問題2: PyTorch のほうが python 的
PyTorch のほうがオブジェクト志向的で python 的だ。

## 重み共有
Siamese Network の例。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/9d250ac1-2b73-8763-3d2e-ff7dcf098924.png)

従来の tensorflow では tf.variable_scope と tf.get_variable を使って「変数名」で重みを共有する。

tensorflow 2.0 では keras API を使うようになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/3efb16d4-a530-2630-f157-49169446481a.png)
Dense という処理のオブジェクトを作り、それを複数の入力に適用することで重みの共有を表現している。

こちらのほうが、グローバルな状態を持たず、よりオブジェクト指向的。

## Collection が deprecated に
optimizer などで使う、学習用変数の Collection などが deprecated に。

従来の tensorflow
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/17b3c2c5-fdf8-c168-b2af-aadcca05baad.png)

tensorflow 2.0
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/ceb02a4a-6cb3-1e87-9f53-38fccb8a87e2.png)
weights 一覧は layer オブジェクトのプロパティとして取得できる。


## tensorflow 2.0 での変更
- tf.variable_scope -> 廃止
    - レイヤーを使って重みを共有
- tf.get_variable -> 廃止
    - layer.weights で重みを取得
- optimizer.minimize は loss の他に var_list を必ず取るようになる。
    - var_list=model.weights
- tf.assign(a, b) -> 廃止
    - a.assign(b) を使う
- a[1].assign(5) みたいな書き方は tensorflow 1.11 で使えるように


# 問題3: PyTorch のほうがクリーン
## keras の api と tf の api が混在しているのを整理する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/229cc97e-03a8-2f68-80d4-d922ce1a51a6.png)


## contrib を消す
一部は core api に統合。一部は別のプロジェクトとして分離。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/a902619b-d64b-b610-fb59-96691181360b.png)

## メソッドの整理
デバッグ系を tf.debugging にまとめたり
![image.png](https://qiita-image-store.s3.amazonaws.com/0/61079/3809a4c7-efd5-7642-36f1-aa79dd447b4e.png)

互換性のために以下の手段が提供される

- ミグレーションツール
    - v1 から v2 への変換
- tf.compat.v1

# Public Design Review Process
https://github.com/tensorflow/community/blob/master/governance/TF-RFCs.md

- 誰でも tensorflow の改良を提案できる
- TF-RFC でプルリクを送る
    - https://github.com/tensorflow/community/pulls

# その他
（このセクションは動画の翻訳ではありません）
本家の Roadmap も参考になると思います。
https://www.tensorflow.org/community/roadmap