想手動實現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->3->2,2->3->1這樣的順序!
#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只適合合併不關心順序的操作,多步更新不能亂用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.