2018年4月3日 更新

Python × TensorFlow ② ~TensorFlow を扱う上で必要な知識「定数・変数」~

TensorFlow を扱う上で必要な以下3つの知識のうち「定数と変数」について解説していきたいと思います.

9,086 view お気に入り 1
本記事では,TensorFlow を扱う上で必要な以下3つの知識のうち「定数と変数」について解説していきたいと思います.
・テンソル ← 前回の記事で紹介済み
[Python × TensorFlow ① ~TensorFlow を扱う上で必要な知識「テンソル」~]
https://lp-tech.net/articles/T1xBU

・定数と変数
・プレースホルダ

本記事を通じて,TensorFlow における「定数」は更新不可,「変数」は更新可,であることが分かって頂ければ幸いです.

定数

TensorFlow には,定数を生成する operation が用意されています.下記のコードで,様々な形状の定数を生成しています.定数の中身を確認するには,Session オブジェクトを作って,run() を実行する必要があります.
import tensorflow as tf

constant_tsr = tf.constant(1)  # 定数
zeros_tsr = tf.zeros(shape=[2, 3])  # 全て 0 の要素
ones_tsr = tf.ones(shape=[2, 3])  # 全て 1 の要素
filled_tsr = tf.fill(dims=[2, 3], value=5)  # 全て第二引数で指定した定数の要素
randunif_tsr = tf.random_uniform(shape=[2, 3], minval=0, maxval=10)  # 0~10 の一様分布乱数の要素
randnorm_tsr = tf.random_normal(shape=[2, 3], mean=0.0, stddev=1.0)  # 平均 0.0,標準偏差 1.0 の正規分布に従う乱数の要素

with tf.Session() as sess:
    print(sess.run(constant_tsr))
    print(sess.run(zeros_tsr))
    print(sess.run(ones_tsr))
    print(sess.run(filled_tsr))
    print(sess.run(randunif_tsr))
    print(sess.run(randnorm_tsr))
    
# 以下,実行結果
# 1
# [[0. 0. 0.]
#  [0. 0. 0.]]
# [[1. 1. 1.]
#  [1. 1. 1.]]
# [[5 5 5]
#  [5 5 5]]
# [[4.283553  5.5121    5.6653166]
#  [9.321325  7.819345  5.081849 ]]
# [[ 1.9098288   0.14842042  0.0982512 ]
#  [ 1.1339864  -1.0708878   1.6536144 ]]
define_constant.py

変数

TensorFlow で変数を定義するには,Variable () が用いられ,引数が変数の初期値となります.具体的には,TensorFlow の定数 (テンソル) や,Python object などが引数となります.

変数の中身を確認するには,Session オブジェクトを作って,run() を実行する必要があります.
しかし,先程の定数の場合と異なるのは,sess.run(tf.global_variables_initializer()) という一文を実行する必要があることです.ここでは,変数の初期化という操作を行っており,計算グラフに変数が含まれている場合は,実行する必要があります.
import tensorflow as tf

var_1 = tf.Variable(tf.constant(1))  # 定数
var_2 = tf.Variable(tf.random_normal(shape=[3, 4], mean=0.0, stddev=1.0))
var_3 = tf.Variable(2)
var_4 = tf.Variable([[1,2],[3,4]])

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(var_1))
    print(sess.run(var_2))
    print(sess.run(var_3))
    print(sess.run(var_4))
    
# 以下,実行結果
# 1 
# [[-0.744018    1.3533652   0.88719493  0.98289156]
#  [ 1.6624707  -0.6312696   1.968103    1.2462833 ]
#  [ 0.06155794  0.10990945  2.1390014   2.3669057 ]] 
# 2 
# [[1 2]
#  [3 4]]
define_variable.py

定数と変数の違いを考える

続いては,TensorFlow における「定数」と「変数」の違いについて考えようと思います.簡潔に言うと,冒頭に述べたように,TensorFlow における「定数」は更新不可,「変数」は更新可,ということです.

これを理解するために,次の実装を考えてみます.まず Python で for文を用いた,カウントアップを実装しました.ここでは,a の値 (初期値 0) が更新され行く様子が分かるかと思います.

このカウントアップの実装を TensorfFlow で行ってみたいと思います.
a = 0
b = 1
for i in range(5):
    a += b
    print(a)
    
# 以下,実行結果
# 1
# 2
# 3
# 4
# 5
python.py
下記コードが,TensorfFlow 版のカウントアップの実装です.add_op で a と b の足し算を行っています.続いて,ass_op では a を add_op (a と b の足し算の結果) に更新しています.この操作を計5回繰り返すと,以下に示した出力となります.

ここで重要なのは,変数として定義した a は更新可,すなわち assign() を適用可能であるということです.
import tensorflow as tf

a = tf.Variable(tf.constant(0))
b = tf.constant(1)
add_op = tf.add(a, b)
ass_op = tf.assign(a, add_op)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(5):
       print(sess.run(ass_op))
       
# 以下,実行結果
# 1
# 2
# 3
# 4
# 5
variable.py
一方で,先程は「変数」として定義した a を「定数」として定義すると,以下のエラー文が返ってきます.これは,TensorFlow における「定数」は更新不可であるため,assign() が適用でないことに起因します.
import tensorflow as tf

a = tf.constant(0)
b = tf.constant(1)
add_op = tf.add(a, b)
ass_op = tf.assign(a, add_op)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for i in range(5):
       print("step%i : " %(i), sess.run(ass_op))
       
# 以下のエラー文が返ってくる.
# AttributeError: 'Tensor' object has no attribute 'assign'
error.py

まとめ

16 件

この記事のキーワード

この記事のキュレーター

井上 大輝 井上 大輝