tensorflow-條件迴圈控制(4)
例如非嚴格語義的示例:在下面的示例中,計數器i的最終值不依賴於x。while_loop可並行地增加計數器,並更新x。
#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Thu Sep 6 10:16:37 2018 @author: myhaspl """ import tensorflow as tf import tensorflow as tf n = 10 x = tf.constant(0) c = lambda i, x: i < n b = lambda i, x: (tf.Print(i + 1, [i],"i:"), tf.Print(x + 1, [x], "x:")) i, out = tf.while_loop(c, b, (0, x)) with tf.Session() as sess: print(sess.run([i,out]))
i:[0]x:[0]
x:[1]
i:[1]
i:[2]
x:[2]
i:[3]
x:[3]
i:[4]
x:[4]
i:[5]
x:[5]
i:[6]
x:[6]
i:[7]
i:[8]x:[7]
i:[9]
x:[8]
x:[9]
[10, 10]
>>
觀察上面例子,x和i是平行計算的,以至於在i為8時,x還是7
i:[6]
x:[6]
i:[7]
i:[8]x:[7]
下面的例子將x設為列表,每次迭代對列表的每個元素加1
#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Thu Sep 6 10:16:37 2018 @author: myhaspl """ import tensorflow as tf import tensorflow as tf n = 10 x = tf.constant(list(range(n))) c = lambda i, x: i < n b = lambda i, x: (tf.Print(i + 1, [i],"i:"), tf.Print(x + 1, [x], "x:")) i, out = tf.while_loop(c, b, (0, x)) with tf.Session() as sess: print(sess.run([i,out]))
i:[0]
x:[0 1 2...]i:[1]
x:[1 2 3...]i:[2]
x:[2 3 4...]
i:[3]
x:[3 4 5...]
i:[4]
x:[4 5 6...]
x:[5 6 7...]i:[5]
x:[6 7 8...]i:[6]
x:[7 8 9...]i:[7]
x:[8 9 10...]
i:[8]
i:[9]
x:[9 10 11...]
[10, array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19], dtype=int32)]
因為一個迴圈迭代中的迴圈計數器依賴於前一個迭代中的值迴圈計數器本身不能並行遞增。
#!/usr/bin/env python2 # -*- coding: utf-8 -*- """ Created on Thu Sep 6 10:16:37 2018 @author: myhaspl """ import tensorflow as tf def b(i): return tf.Print(i + 2, [i],"i:") def c(i): return tf.less(i,n) n = tf.constant(10) i = tf.constant(0) res = tf.while_loop(c, b, [i]) with tf.Session() as sess: print sess.run(res)
i:[0]
i:[2]
i:[4]
i:[6]
i:[8]
10
i這個計算器本身,每次迭代增加,因此依賴於前一個迭代中的值。因此,如果我們只想要計數器i的最終值(我們在行列印(sess.run(i)),那麼x永遠不會遞增,但是計數器i將在單個執行緒上更新。如下所示:
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 6 10:16:37 2018
@author: myhaspl
"""
import tensorflow as tf
def b(i,x):
return (tf.Print(i + 2, [i],"i:"),tf.Print(x + 1, [x],"x:"))
def c(i,x):
return tf.less(i,n)
n = 10
i = 0
x = tf.constant(list(range(n)))
i,out = tf.while_loop(c, b, (i,x))
with tf.Session() as sess:
print sess.run(i)
i:[0]
i:[2]
i:[4]
i:[6]
i:[8]
10
相反,如果我們希望輸出值(我們在行列印(sess.run(out))上列印),那麼計數器可以在自己的執行緒上遞增,而x可以在單獨的執行緒上並行遞增。
注意:因為i每次遞增2,所以x只會遞增5次,每次增加1
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 6 10:16:37 2018
@author: myhaspl
"""
import tensorflow as tf
def b(i,x):
return (tf.Print(i + 2, [i],"i:"),tf.Print(x + 1, [x],"x:"))
def c(i,x):
return tf.less(i,n)
n = 10
i = 0
x = tf.constant(list(range(n)))
i,out = tf.while_loop(c, b, (i,x))
with tf.Session() as sess:
print sess.run(out)
i:[0]
x:[0 1 2...]i:[2]
x:[1 2 3...]i:[4]
i:[6]x:[2 3 4...]
x:[3 4 5...]
i:[8]
x:[4 5 6...]
[ 5 6 7 8 9 10 11 12 13 14]
在極端情況下,可以想象,遞增計數器的執行緒在x遞增一次之前一直執行到完成。唯一不可能發生的事情是執行緒更新x永遠不可能超過計數器執行緒,因為遞增x的執行緒取決於計數器的值。下面模擬了這種情況(i>6時,x更新遞增)
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 6 10:16:37 2018
@author: myhaspl
"""
import tensorflow as tf
def b(i,x):
i=tf.Print(i + 1, [i],"i:")
x=tf.cond(i<=5,lambda: tf.Print(x,[x],"x:"),lambda: tf.Print(x + 1, [x],"x:"))
return (i,x)
def c(i,x):
return tf.less(i,n)
n = 10
i = 0
x = 0
i,out = tf.while_loop(c, b, (i,x))
with tf.Session() as sess:
print sess.run(out)
i:[0]
x:[0]
i:[1]
x:[0]
i:[2]
x:[0]
i:[3]
x:[0]
i:[4]
i:[5]
i:[6]x:[0]
x:[0]
i:[7]
x:[1]
i:[8]
i:[9]
x:[2]
x:[3]
x:[4]
5
組合tf.cond與tf.while_loop
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Thu Sep 6 10:16:37 2018
@author: myhaspl
@email:[email protected]
二分法猜數字
"""
import tensorflow as tf
def body(a,b,guessnum,num):
center = tf.div(tf.add(a, b),2)
a,b,num= tf.cond(guessnum>center, lambda: (center,b,center), lambda: (a,center,center))
return (tf.Print(a,[a],"a:"),tf.Print(b,[b],"b:"),guessnum,num)
def c(a,b,guessnum,num):
return tf.not_equal(guessnum,num)
guessnum = tf.constant(71)
mynum = tf.constant(-1)
a = tf.constant(0)
b = tf.constant(100)
a,b,guessnum,num = tf.while_loop(c, body, (a,b,guessnum,mynum))
with tf.Session() as sess:
print sess.run(num)
b:[100]
a:[50]
a:[50]
b:[75]
b:[75]
a:[62]
b:[75]
a:[68]
a:[68]
b:[71]
71