tensorflow中更新引數順序與tf.group中操作執行順序
阿新 • • 發佈:2019-01-09
想手動實現Adagrad,因為Adagrad有兩部分需要更新,因為之前合併兩個initializer用過tf.group,想當然認為tf.group可能是帶順序的,所以打算把兩個update直接group起來執行,看起來省事,感覺卻會出事,覺得很可能不帶順序,所以寫了個小demo驗證:
一個操作是a自加1,這類似adagrad的分母更新;
一個操作是給b賦值a的值,相當於使用第一步的結果。
無論跑500、3000、30000次,結果都有不確定性,經常會少1
#demo1 #when range(500)two results randomly occur:499 and 500 #when range(3000)two results randomly occur:2999 and 3000 with tf.name_scope('initial'): a = tf.Variable(0,dtype=tf.float32) b = tf.Variable(0,dtype=tf.float32) #update update1 = tf.assign_add(a,1) update2 = tf.assign(b, a) update = tf.group(update1,update2) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) for _ in range(30000): _ = sess.run(update) print(sess.run(b))
雖然結果表現出一定的隨機性,但是驗證效果不明顯,為了進一步驗證,讓a先自加,再自減,那麼b應該永遠是0才算執行順序明確!
實際測試:30000次迴圈,b的數值非常不穩定,一直上下隨機跳,最終結果有時候能到正4、5,有時候-4.
猜測是因為無序執行,造成了a只執行了一個自加或者自減,b就被賦值了,就是說,期待1->2->3的順序,實際上是1->3->2(增)、2->3->1(減)這樣的順序!(A33任意順序都可能,這兩種影響結果)
#demo2 #for _ in range(30000): output is randomly in 0,-1,-2,-3,-4 and the final output is -4 #for _ in range(30000): output is randomly in 0,1,2,3,4,5 and the final output is 4 #speculate wrong sequence: #update1,update3,update2 #update2,update3,update1 with tf.name_scope('initial'): a = tf.Variable(0,dtype=tf.float32) b = tf.Variable(0,dtype=tf.float32) #update update1 = tf.assign_add(a,1) update2 = tf.assign_sub(a,1) update3 = tf.assign(b, a) update = tf.group(update1,update2,update3) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) for _ in range(30000): _ = sess.run(update) print(sess.run(b))
tf.group的說明,沒說有順序,這就坑爹了,所以說,tf.group只適合合併不關心順序的操作,多步更新不能亂用tf.group。
Help on function group in module tensorflow.python.ops.control_flow_ops: group(*inputs, **kwargs) Create an op that groups multiple operations. When this op finishes, all ops in `inputs` have finished. This op has no output. See also @{tf.tuple$tuple} and @{tf.control_dependencies$control_dependencies}. Args: *inputs: Zero or more tensors to group. name: A name for this operation (optional). Returns: An Operation that executes all its inputs. Raises: ValueError: If an unknown keyword argument is provided.