tf中assign()函数可用于对变量进行更新包括变量的value和shape。
涉及以下函数:
- tf.assign(ref, value, validate_shape = None, use_locking = None, name=None)
- tf.assign_add(ref, value, use_locking = None, name=None)
- tf.assign_sub(ref, value, use_locking = None, name=None)
- tf.variable.assign(value, use_locking=False)
- tf.variable.assign_add(delta, use_locking=False)
- tf.variable.assign_sub(delta, use_locking=False)
这6个函数本质上是一样的,都是用来对变量值进行更新,其中tf.assign还可以更新变量的shape。
解释一下它们的意思:tf.assign是用value的值赋给ref,这种赋值会覆盖掉原来的值,即更新而不会创建一个新的tensor。tf.assign_add相当于ref=ref+value来更新ref。tf.assign_sub相当于ref=ref-value来更新ref。tf.variable.assign相当于tf.assign(ref, value)。同理tf.variable.assign_add和tf.variable.assign_sub。
下面对tf.assign函数进行详细说明。
tf.assign(ref, value, validate_shape = None, use_locking = None, name=None)
args:
- ref:一个可变的张量。应该来自变量节点,节点可能未初始化,参考下面的例子。
- value:张量。必须具有与 ref 相同的类型。是要分配给变量的值。
- validate_shape:一个可选的 bool。默认为 True。如果为 true, 则操作将验证 "value" 的形状是否与分配给的张量的形状相匹配;如果为 false, "ref" 将对 "值" 的形状进行引用。
- use_locking:一个可选的 bool。默认为 True。如果为 True, 则分配将受锁保护;否则, 该行为是未定义的, 但可能会显示较少的争用。
- name:操作的名称(可选)。
返回:
一个在赋值完成后将保留 "ref" 新值的张量。
现在举三个例子,说明三个问题:
例子1:assign操作会初始化相关的节点,并不需要tf.global_variables_initializer()初始化,但是并非所有的节点都会被初始化。
#-*-coding:utf-8-*- import tensorflow as tf import numpy as np weights=tf.Variable(tf.random_normal([1,2],stddev=0.35),name="weights") biases=tf.Variable(tf.zeros([3]),name="biases") x_data = np.float32(np.random.rand(2, 3)) # 随机输入2行3列的数据 y = tf.matmul(weights, x_data) + biases update=tf.assign(weights,tf.random_normal([1,2],stddev=0.50))#正确 #update=weights.assign(tf.random_normal([1,2],stddev=0.50))#正确,和上句意义相同 #init=tf.global_variables_initializer() with tf.Session() as sess: #sess.run(init) for _ in range(2): sess.run(update) print(sess.run(weights))#正确,因为assign操作会初始化相关的节点 print(sess.run(y))#错误,因为使用了未初始化的biases变量
例子2:tf.assign()操作可以改变变量的shape,只需要令参数validate_shape=False,默认为True。
#-*-coding:utf-8-*- import tensorflow as tf x = tf.Variable(0) y = tf.assign(x, [5,2], validate_shape=False) with tf.Session() as sess: sess.run(tf.global_variables_initializer()) print (sess.run(x))#输出0 print (sess.run(y))#输出[5 2] print (sess.run(x))#输出[5 2]
例子3:assign都会在图中产生额外的操作,可用tf.Variable.load(value, session)实现从图外赋值不产生额外的操作。
#-*-coding:utf-8-*- import tensorflow as tf x = tf.Variable(0) sess = tf.Session() sess.run(tf.global_variables_initializer()) print(sess.run(x)) # 输出 0 x.load(5, sess) print(sess.run(x)) # 输出 5