Python 在tensorflow图中创建计数器

Python 在tensorflow图中创建计数器,python,tensorflow,Python,Tensorflow,我想在图表中创建一个计数器。每当函数运行时,它都会增加。这就是我现在正在尝试的。有什么想法吗 # init variable tf_i = tf.Variable(1, name='v', dtype=tf.int32, expected_shape=()) # init assign op tf_i_plus_one = tf.assign_add(tf_i, 1) sess.run(tf.global_variables_initializer()) # simple test fx d

我想在图表中创建一个计数器。每当函数运行时,它都会增加。这就是我现在正在尝试的。有什么想法吗

# init variable
tf_i = tf.Variable(1, name='v', dtype=tf.int32, expected_shape=())

# init assign op
tf_i_plus_one = tf.assign_add(tf_i, 1)
sess.run(tf.global_variables_initializer())

# simple test fx
def test(x):
    v = tf.get_variable('v', shape=())
    return x + v

# run test fx
z = tf.placeholder(tf.float32, shape=(), name='z')
out = test(z)

print(sess.run(out, feed_dict={z: 4}))
sess.run(tf_i_plus_one)

print(sess.run(out, feed_dict={z: 4}))
我现在得到:

Attempting to use uninitialized value v_1

如果只需要函数的计数器,请尝试以下操作:

def wrap_with_counter(fn, counter):
    def wrapped_fn(*args, **kwargs):
        # control_dependencies forces the assign op to be run even if we don't use the result
        with tf.control_dependencies([tf.assign_add(counter, 1)]):
            return fn(*args, **kwargs)
    return wrapped_fn
用法示例:

dense_counter = tf.get_variable(
    dtype=tf.int32, shape=(), name='dense_counter',
    initializer=tf.zeros_initializer())
wrapped_dense = wrap_with_counter(tf.layers.dense, dense_counter)


batch_size = 4
n_features = 8
# dummy input
x = tf.random_normal(
    shape=(batch_size, n_features), dtype=tf.float32, name='x')

out = wrapped_dense(x, 1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    c0 = sess.run(dense_counter)
    print(c0)  # 0
    sess.run(out)
    c1 = sess.run(dense_counter)
    print(c1)  # 1

如果只需要函数的计数器,请尝试以下操作:

def wrap_with_counter(fn, counter):
    def wrapped_fn(*args, **kwargs):
        # control_dependencies forces the assign op to be run even if we don't use the result
        with tf.control_dependencies([tf.assign_add(counter, 1)]):
            return fn(*args, **kwargs)
    return wrapped_fn
用法示例:

dense_counter = tf.get_variable(
    dtype=tf.int32, shape=(), name='dense_counter',
    initializer=tf.zeros_initializer())
wrapped_dense = wrap_with_counter(tf.layers.dense, dense_counter)


batch_size = 4
n_features = 8
# dummy input
x = tf.random_normal(
    shape=(batch_size, n_features), dtype=tf.float32, name='x')

out = wrapped_dense(x, 1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    c0 = sess.run(dense_counter)
    print(c0)  # 0
    sess.run(out)
    c1 = sess.run(dense_counter)
    print(c1)  # 1

谢谢非常有用。然而,为了理解tf如何处理图中的变量分配或更新,您对此有什么见解吗?根据经验,在实例化会话/do变量初始化之前,完全构建您的图。您在上面遇到的错误让我感到惊讶-我本以为变量v已经存在,不允许存在,但如果您将图形构造与会话运行分开,那么事情就更可预测了
tf.assign\u add
返回一个表示更新结果的张量,但如果会话中调用的任何内容都不依赖该结果,则不会运行该结果,因此更新也不会运行。添加
tf.control\u dependencies
是解决这一问题的一种方法。我可以在
Dateset
map/filter/apply函数中使用类似的方法来获取增量变量(例如
global\u步骤
)?再见,谢谢。非常有用。然而,为了理解tf如何处理图中的变量分配或更新,您对此有什么见解吗?根据经验,在实例化会话/do变量初始化之前,完全构建您的图。您在上面遇到的错误让我感到惊讶-我本以为变量v已经存在,不允许存在,但如果您将图形构造与会话运行分开,那么事情就更可预测了
tf.assign\u add
返回一个表示更新结果的张量,但如果会话中调用的任何内容都不依赖该结果,则不会运行该结果,因此更新也不会运行。添加
tf.control\u dependencies
是解决这一问题的一种方法。我可以在
Dateset
map/filter/apply函数中使用类似的方法来获取增量变量(例如
global\u步骤
)?看见