Tensorflow tf.scatter_update不更新浮点值

时间:2018-10-28 06:59:46

标签: python tensorflow

如果将变量的类型定义为float,似乎tf.scatter_update不会更新该变量。这是您可以尝试的代码:

import tensorflow as tf

def cond(size, i):
    return tf.less(i,size)

def body(size, i):
    b=2*7.5+c

    with tf.variable_scope("a", reuse=tf.AUTO_REUSE):
        a = tf.get_variable("a",[6],dtype=tf.float32)

        a = tf.scatter_update(a,i,b)

        with tf.control_dependencies([a]):
            return (size, i+1)

with tf.Session() as sess:
    c=tf.constant(4.0)
    i = tf.constant(0)
    size = tf.constant(6)
    _,i = tf.while_loop(cond,
            body,
            [size, i])

    a = tf.get_variable("a",[6],dtype=tf.float32)

    init = tf.initialize_all_variables()
    sess.run(init)
    print(sess.run([a,i]))

结果将是随机的!由于我没有故意初始化变量以查看其更新方式,因此似乎从未对其进行更新,并且每次都会打印出随机初始化。您会看到类似以下内容:

[array([-0.35466522,0.44001752,0.21131486,-0.48532146,0.3019274,        -0.19926369],dtype = float32),6]

这是一个错误吗?如您所见,我仍在使用tf.control_dependencies,并且仅当变量a的类型设置为float时才会发生。

2 个答案:

答案 0 :(得分:0)

您的预期输出是吗?

[array([19., 19., 19., 19., 19., 19.], dtype=float32), 6]

这两种模式会产生这种结果。

模式1

import tensorflow as tf

def cond(size, i):
    return tf.less(i,size)

def body(size, i):
    b=2*7.5+c

    with tf.variable_scope("a", reuse=tf.AUTO_REUSE):
        a = tf.get_variable("a",[6],dtype=tf.float32)

        a = tf.scatter_update(a,i,b)
        with tf.control_dependencies([a]):
            return (size, i+1)

with tf.Session() as sess:
    c=tf.constant(4.0)
    i = tf.constant(0)
    size = tf.constant(6)
    _,i = tf.while_loop(cond,
            body,
            [size, i])

    with tf.variable_scope("a", reuse=tf.AUTO_REUSE):
        a = tf.get_variable("a",[6],dtype=tf.float32)

        init = tf.initialize_all_variables()
        sess.run(init)

        print(sess.run([a,i]))

模式2

def body(size, i):
    b=2*7.5+c

    a = tf.get_variable("a",[6],dtype=tf.float32)

    a = tf.scatter_update(a,i,b)
    #Reuse variables 
    tf.get_variable_scope().reuse_variables()

    with tf.control_dependencies([a]):
        return (size, i+1)

with tf.Session() as sess:
    c=tf.constant(4.0)
    i = tf.constant(0)
    size = tf.constant(6)
    _,i = tf.while_loop(cond,
            body,
            [size, i])

    a = tf.get_variable("a",[6],dtype=tf.float32)

    init = tf.initialize_all_variables()
    sess.run(init)

    print(sess.run([a,i]))

答案 1 :(得分:0)

作为GitHub Tensorflow问题,您的问题得到了更好的解答here

我会在这里尝试总结一下。主要有两个问题:

  1. 在运行会话之前检索变量a时,它必须在变量作用域“ a”下,否则您将创建一个新变量。正如@MohanRadhakrishnan提到的。
  2. sess.run([a,i])未定义ai的评估顺序。 a可以在循环初始化之前,之后或之中以及在循环a初始化之前进行求值。因此,您可以获得不同的结果。因此,在这种情况下,必须在运行sess.run(i)之前先运行sess.run(a)来定义顺序。由于更多的并行化,这会在GPU上引起更多问题。

因此代码将是:

def cond(size, i):
    return tf.less(i, size)

def body(size, i):
    b = 2 * 7.5 + c

    with tf.variable_scope("a", reuse=tf.AUTO_REUSE):
        a = tf.get_variable("a", [6], dtype=tf.float32)

        a = tf.scatter_update(a, i, b)

        with tf.control_dependencies([a]):
            return (size, i + 1)

with tf.Session() as sess:
    c = tf.constant(4.0)
    i = tf.constant(0)
    size = tf.constant(6)
    _, i = tf.while_loop(cond,
                         body,
                         [size, i])

    with tf.variable_scope("a", reuse=tf.AUTO_REUSE):  # Issue 1. Reuse 'a'.
        a = tf.get_variable("a", [6], dtype=tf.float32)

    init = tf.initialize_all_variables()
    sess.run(init)
    print(sess.run(i))  # issue 2. Define the order of operation.  
    print(sess.run(a))