読者です 読者をやめる 読者になる 読者になる

いまさらTensorflow 始めます。第二撃  変数とプレースホルダー

tensorflowを始めることになったので、記憶の定着もかねて、先人たちの記録をまとめて整理していく。

TensorFlowの定数「tf.constant」以外に、変数「Variable」とプレースホルダー「placeholder」がある。

ライブラリのインポート

import tensorflow as tf

変数は「tf.Variable」で変数を宣言する。 変数に値を代入するときは「tf.assign」を使う。 変数var1に、定数const2の値を足した結果を代入して、さらにvar1とadd_opを積算するグラフを構築する。 変数を使うには、セッション内で「tf.initialize_all_variables()」を実行して、変数を初期化する必要がある。

var1 = tf.Variable(0)#変数宣言
const2 = tf.constant(3)#定数3

add_op = tf.add(var1, const2)#変数var1と定数const2のsum
update_var1 = tf.assign(var1, add_op)#変数var1にadd_opを代入
mul_op = tf.multiply(add_op, update_var1)#代入した値とadd_opの積


with tf.Session() as sess:
  sess.run(tf.initialize_all_variables())

  print(sess.run([mul_op]))
  print(sess.run([mul_op]))

結果

WARNING:tensorflow:From sample.py:24: initialize_all_variables (from tensorflow.python.ops.variables) is deprecated and will be removed after 2017-03-02.
Instructions for updating:
Use `tf.global_variables_initializer` instead.
[9]
[36]

WARNING出たけどとりあえず無視。 それぞれの変数の値はセッション内でこんな感じで変化していると考えられる。

with tf.Session() as sess:
  sess.run(tf.initialize_all_variables())

  print(sess.run([mul_op]))
  # var1=0 const2=3 add_op=3 update_var1=3 var1=3 
  # mul_op=9 
  print(sess.run([mul_op]))
  # var1=3 const2=3 add_op=6 update_var1=6 var1=6 
  # mul_op=36 

WARNINGは「tf.initialize_all_variables()」を使わないで「tf.global_variables_initializer()」を使えということかな?

ちょっと修正。 修正したら出なくなった。

Sessionを二回まわしてみる

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  print(sess.run([mul_op]))
  print(sess.run([mul_op, mul_op]))

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  print(sess.run([mul_op]))
  print(sess.run([mul_op, mul_op]))
Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: a097:00:00.0)
[9]
[36, 36]
Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: a097:00:00.0)
[9]
[36, 36]

それぞれ同じ値が表示された。 mul_opはSession処理の過程で変数を更新する。 そのため、セッション間で変数の値は引き継がれない。 それぞれのセッションで変数が独立している。

変数代入のタイミング 変数に値が代入されるタイミングは、runに指定したオペレーションがすべて完了した後。

with tf.Session() as sess:
  sess.run(tf.initialize_all_variables())
  
  print(sess.run([mul_op]))
  print(sess.run([mul_op, mul_op]))
  print(sess.run([mul_op, mul_op, mul_op]))

これを実行すると、以下のようになる。

[9]
[36, 36]
[81, 81, 81]

runに渡したオペレーションがそれぞれ終わってから値が表示される。

プレースホルダ

プレースホルダー「placeholder」はデータを格納する場所。 データは未定のままグラフを構築し、実際の値は実行時に入れることになる。 プレースホルダーを利用するケースは、ファイルから読み込んだデータをグラフに与えて処理する場合が考えられる。

var1 = tf.Variable(0)
holder2 = tf.placeholder(tf.int32)
add_op = tf.add(var1, holder2)
update_var1 = tf.assign(var1, add_op)
mul_op = tf.multiply(add_op, update_var1)

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  result = sess.run(mul_op, feed_dict={holder2: 5})

  print(result)

これを実行すると以下のような答えが出る。

Creating TensorFlow device (/gpu:0) -> (device: 0, name: Tesla K80, pci bus id: a097:00:00.0)
25

処理の中を書くとこんな感じ。

var1 = tf.Variable(0)#変数 var1=0
holder2 = tf.placeholder(tf.int32)#プレースホルダーholder2 int32型
add_op = tf.add(var1, holder2)#オペレーション 変数var1とholder2のsum
update_var1 = tf.assign(var1, add_op)#var1にadd_opを代入
mul_op = tf.multiply(add_op, update_var1)#add_opとupdate_var1の積

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())#変数の初期化
  result = sess.run(mul_op, feed_dict={holder2: 5})
  #add_opとupdate_var1の積を実行。holder2=5の場合の処理を行う。
  #add_op = tf.add(var1, holder2)#add_op=5
  #update_var1 = tf.assign(var1, add_op)#var1=5 update_var1=5
  #mul_op = tf.multiply(add_op, update_var1)#mul_op=25
  #result = sess.run(mul_op, feed_dict={holder2: 5})#result=mul_op
  print(result)#25

下みたいに、プレースホルダーの値を入れないでrunするとエラーが出る。

var1 = tf.Variable(0)
holder2 = tf.placeholder(tf.int32)
add_op = tf.add(var1, holder2)
update_var1 = tf.assign(var1, add_op)
mul_op = tf.multiply(add_op, update_var1)

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  result = sess.run(mul_op)

  print(result)

エラーはこんな感じ。

Invalid argument: You must feed a value for placeholder tensor 'Placeholder' with dtype int32
[[Node: Placeholder = Placeholder[dtype=DT_INT32, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
(~中略~)
tensorflow.python.framework.errors_impl.InvalidArgumentError: You must feed a value for placeholder tensor 'Placeholder' with dtype int32
[[Node: Placeholder = Placeholder[dtype=DT_INT32, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]
Caused by op u'Placeholder', defined at:
(~中略~)
InvalidArgumentError (see above for traceback): You must feed a value for placeholder tensor 'Placeholder' with dtype int32
[[Node: Placeholder = Placeholder[dtype=DT_INT32, shape=[], _device="/job:localhost/replica:0/task:0/gpu:0"]()]]

参考:

www.buildinsider.net

sample2.py全文

var1 = tf.Variable(0)#変数宣言
const2 = tf.constant(3)#定数3

add_op = tf.add(var1, const2)#変数var1と定数const2のsum
update_var1 = tf.assign(var1, add_op)#変数var1にadd_opを代入
mul_op = tf.multiply(add_op, update_var1)#代入した値とadd_opの積



with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  print(sess.run([mul_op]))
  print(sess.run([mul_op, mul_op]))

with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  print(sess.run([mul_op]))
  print(sess.run([mul_op, mul_op]))


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

  print(sess.run([mul_op]))
  print(sess.run([mul_op, mul_op]))
  print(sess.run([mul_op, mul_op, mul_op]))



var1 = tf.Variable(0)#変数 var1=0
holder2 = tf.placeholder(tf.int32)#プレースホルダーholder2 int32型
add_op = tf.add(var1, holder2)#オペレーション 変数var1とholder2のsum
update_var1 = tf.assign(var1, add_op)#var1にadd_opを代入
mul_op = tf.multiply(add_op, update_var1)#add_opとupdate_var1の積



with tf.Session() as sess:
  sess.run(tf.global_variables_initializer())
  result = sess.run(mul_op, feed_dict={holder2: 5})

  print(result)

#with tf.Session() as sess:
#  sess.run(tf.global_variables_initializer())
#  result = sess.run(mul_op)
#
#  print(result)