TensorFlowのバージョン1と2を比較したレシピ集（その1）

# はじめに
Tensorflowはディープラーニングの代表的なフレームワークです。
このTensorFlowは2019年10月にバージョンが2.0になり、
ソースの書き方も色々変わりました。

しかし、まだまだ1.Xのバージョンで書かれた記事が大多数で、
**あれ、これ2.0以降だとどう書くんだっけ？**
と詰まる方も多いのではないでしょうか。

私もその1人だったので、まずは基本に立ち返ろうと備忘録がてら記事にしてみました。
色々参考にしながら自分でアレンジしていますので、
もし誤りなどございましたらコメント等いただければ幸いです。

なお、紹介するサンプルはあえて細かく説明をつけずに、
ごくシンプルにver1と2の違いの差に特化して載せております。


# 環境
- Python 3.6.8
- TensorFlow 1.15.0rc3
- TensorFlow 2.1.0
- Dockerで2つのコンテナを用意して検証

# レシピ集
## データフローグラフ
### 足し算

`ver 1.15.0の場合`

```python:in
import tensorflow as tf

a = tf.constant(1, name='a')
b = tf.constant(2, name='b')
c = a + b

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

```console:out
3
Tensor("add:0", shape=(), dtype=int32)
<class 'tensorflow.python.framework.ops.Tensor'>
```

`ver 2.1.0の場合`

```python:in
import tensorflow as tf

a = tf.constant(1, name='a')
b = tf.constant(2, name='b')
c = a + b

tf.print(c)
print(c)
print(type(c))
```

```console:out
3
tf.Tensor(3, shape=(), dtype=int32)
<class 'tensorflow.python.framework.ops.EagerTensor'>
```

【参考】
[tf.print](https://www.tensorflow.org/api_docs/python/tf/print)

### 定義の出力
`ver 1.15.0の場合`

```python:in
import tensorflow as tf

a = tf.constant(1, name='a')
b = tf.constant(2, name='b')
c = a + b

with tf.Session() as sess:
    print(sess.run(c))
    print(c)

graph = tf.get_default_graph()
print(graph.as_graph_def())
```

```console:out
node {
  name: "a"
  op: "Const"
  ...(中略)...
node {
  name: "add"
  op: "AddV2"
  input: "a"
  input: "b"
  attr {
    key: "T"
    value {
      type: DT_INT32
    }
  }
}
versions {
  producer: 134
}
```

`ver 2.1.0の場合`

```python:in
import tensorflow as tf

graph = tf.Graph()
with graph.as_default():
    a = tf.constant(1, name='a')
    b = tf.constant(2, name='b')
    c = a + b
    print(graph.as_graph_def())
```

```console:out
# ver 1.15.0 と同様のため割愛
```

### 変数に定数を代入

`ver 1.15.0の場合`

```python:in
import tensorflow as tf

a = tf.Variable(10, name='a')
b = tf.constant(2, name='b')
c = tf.assign(a, a + b)

with tf.Session() as sess:
    # global_variables_initializer() : 全ての変数を初期化
    sess.run(tf.global_variables_initializer())
    print(sess.run(c))
    print(sess.run(c))

```

```console:out
12
14
```


`ver 2.1.0の場合`

```python:in
import tensorflow as tf

a = tf.Variable(10, name='a')
b = tf.constant(2, name='b')
tf.print(a.assign_add(b))
tf.print(a.assign_add(b))
```

```console:out
12
14
```

### 消えたplaceholder

`ver 1.15.0の場合`

```python:in
import tensorflow as tf

a = tf.placeholder(dtype=tf.int32, name='a')
b = tf.constant(2, name='b')
c = a + b

with tf.Session() as sess:
    print(sess.run(c, feed_dict={a: 10}))
    print(a, b, c)
```

```console:out
12
Tensor("a:0", dtype=int32) Tensor("b:0", shape=(), dtype=int32) Tensor("add:0", dtype=int32)
```

`ver 2.1.0の場合`

```python:in
import tensorflow as tf

a = tf.Variable(10, name='a')
b = tf.constant(2, name='b')

# @tf.functionでAutoGraph
@tf.function
def add(x, y):
    return x + y

c = add(a,b)
tf.print(c)
print(type(c))
print(a, b, c)
```

```console:out
12
<class 'tensorflow.python.framework.ops.EagerTensor'>
<tf.Variable 'a:0' shape=() dtype=int32, numpy=10> tf.Tensor(2, shape=(), dtype=int32) tf.Tensor(12, shape=(), dtype=int32)
```

【参考】
[Migrate your TensorFlow 1 code to TensorFlow 2](https://www.tensorflow.org/guide/migrate)

## 四則演算

`ver 1.15.0の場合`

```python:in
import tensorflow as tf

a = tf.constant(5, name='a')
b = tf.constant(2, name='b')
add = tf.add(a, b) # 加算
subtract = tf.subtract(a, b) # 減算
multiply = tf.multiply(a, b) # 乗算
truediv = tf.truediv(a, b) # 除算

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(add))
    print(sess.run(subtract))
    print(sess.run(multiply))
    print(sess.run(truediv))
    print(type(add))
```

```console:out
7
3
10
2.5
<class 'tensorflow.python.framework.ops.Tensor'>
```

`ver 2.1.0の場合`

```python:in
import tensorflow as tf

a = tf.constant(5, name='a')
b = tf.constant(2, name='b')
add = tf.math.add(a, b) # 加算
dif = tf.math.subtract(a,b) # 減算
multiply = tf.math.multiply(a, b) # 乗算
truediv = tf.math.truediv(a, b) # 除算

tf.print(add)
tf.print(dif)
tf.print(multiply)
tf.print(truediv)
print(type(add))
```

```console:out
7
3
10
2.5
<class 'tensorflow.python.framework.ops.EagerTensor'>
```
【参考】
[tf.math](https://www.tensorflow.org/api_docs/python/tf/math)

## 行列演算

`ver 1.15.0の場合`

```python:in
import tensorflow as tf

a = tf.constant([[1, 2], [3, 4]], name='a')
b = tf.constant([[1], [2]], name='b')
c = tf.matmul(a, b) # 行列a, bを乗算

with tf.Session() as sess:
    print(a.shape)
    print(b.shape)
    print(c.shape)
    print('a', sess.run(a))
    print('b', sess.run(b))
    print('c', sess.run(c))
```

```console:out
(2, 2)
(2, 1)
(2, 1)
a [[1 2]
 [3 4]]
b [[1]
 [2]]
c [[ 5]
 [11]]
```

`ver 2.1.0の場合`

```python:in
import tensorflow as tf

a = tf.constant([[1, 2], [3, 4]], name='a')
b = tf.constant([[1], [2]], name='b')
c = tf.linalg.matmul(a, b) # 行列a, bを乗算

print(a.shape)
print(b.shape)
print(c.shape)
tf.print('a', a)
tf.print('b', b)
tf.print('c', c)
```

```console:out
# ver 1.15.0 と同様のため割愛
```

# おわりに
今回は基礎中の基礎をまとめました。
次回は勾配法など記載できたらと考えております。