tensorflow中更新参数顺序与tf.group中操作执行顺序

想手动实现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.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章