TensorFlow变量Variable

落爺英雄遲暮 提交于 2019-12-01 18:41:50

变量通过 tf.Variable 类进行操作,可以通过运行op改变它的值。
与 tf.Tensor 对象不同,tf.Variable 存在于单个 session.run 调用的上下文之外。

创建变量

创建变量的最佳方式是调用 tf.get_variable 函数。
这个函数的本意是获取已存在的变量,因而必须指定变量名称。当变量不存在时,将会创建一个。

my_variable = tf.get_variable("my_variable", [1,2,3])# 指定dtype和initializermy_int_variable = tf.get_variable("my_int_variable", [1,2,3], dtype=tf.int32, initializer=tf.zeros_initializer)# 初始化为Tensor的值,不能指定形状my_ten_variable = tf.get_variable("other_var", dtype=tf.int32, initializer=tf.constant([23,42]))

变量集合

默认情况下,每个 tf.Variable 都放置在以下两个集合中:

  • tf.GraphKeys.GLOBAL_VARIABLES:可在多个设备间共享
  • tf.GraphKeys.TRAINABLE_VARIABLES:将计算梯度并迭代更新

如果不希望变量被训练,可以将其添加到 tf.GraphKeys.LOCAL_VARIABLES 集合中:

# 直接添加my_local = tf.get_variable("local", shape=(), collections=[tf.GraphKeys.LOCAL_VARIABLES])# 指定不可训练my_nontrainable = tf.get_variable("nontrainable", shape=(), trainable=False)# 添加变量到指定的集合中tf.add_to_collection("my_collection", my_local)# 获取集合内的所有对象tf.get_collection("my_collection")

自定义的集合不需要显式创建,直接用在add_to_collection()方法中即可。

变量初始化

变量在使用前必须初始化。
高级框架如 tf.estimator.Estimator, tf.contrib.slim, Keras 等在训练前会自动初始化变量;而使用低级别API编程时需要手动初始化变量。

要在训练前一次性初始化所有可训练变量,使用 tf.global_variable_initializer()。该函数会返回一个op,负责初始化 tf.GraphKeys.GLOBAL_VARIABLES 集合中的所有变量。运行这个op就会将集合里的所有变量初始化。

# 全部初始化session.run(tf.global_variables_initializer())# 单个变量初始化session.run(my_variable.initializer)# 查询哪些变量尚未初始化print(session.run(tf.report_uninitialized_variables()))

注意:tf.global_variable_initializer 并不会指定变量的初始化顺序。如果某个变量的初始值取决于另一变量,那么初始化时很有可能出现错误。
解决方法:在变量未完全初始化的上下文中使用某个变量的值时,用 variable.initialized_value() 替代 variable .

大专栏  TensorFlow变量Variable>使用变量

要在计算图中使用 tf.Variable 的值,只需将其视为普通的 tf.Tensor。
要为变量赋值,可以使用 assign, assgin_add 以及 tf.Variable 类中的友元。

# 使用变量v = tf.get_variable("v", shape=(), initializer=tf.zeros.initializer())w = v + 1# 变量赋值assignment = v.assign_add(1)sess.run(assignment)

共享变量

TensorFlow 支持两种共享变量的方法:

  • 显式传递 tf.Variable 对象
  • 在 tf.variable_scope 对象内隐式包装 tf.Variable 对象

在真实模型中,每个层被多次创建时,重名的变量必须指明是要创建新变量,还是沿用已有的变量。
创建新变量:

def (input, kernel_shape, bias_shape):	weights = tf.get_variable("weights", kernel_shape, initializer=tf.random_normal_initializer()	biases = tf.get_variable("biases", bias_shape, initializer=tf.constant_initializer(0))	conv = tf.nn.conv2d(input, weights, strides=[1 1 1 1], padding='SAME')	return tf.nn.relu(conv+biases)def my_image_filter(input_images):	with tf.variable_scope("conv1"):		relu1 = conv_relu(input_images, [5,5,32,32], [32])	with tf.variable_scope("conv2"):		relu2 = conv_relu(input_iamges, [5,5,32,32], [32])

共享变量(沿用已有的):

# 调用 scope.reuse_variables() 以触发重用with tf.variable_scope("model") as scope:	output1 = my_image_filter(input1)	scope.reuse_variables()	output2 = my_image_filter(input2)# 使用相同名称的作用域with tf.variable_scope("model"):	output1 = my_image_filter(input1)with tf.variable_scope("model", reuse=True):	output2 = my_image_filter(input2)# 直接写名称是危险的,因此也可以根据另一作用域初始化with tf.variable_scope("model") as scope:	output1 = my_image_filter(input1)with tf.variable_scope(scope, reuse=True):	output2 = my_image_filter(input2)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!