一、同一模型下装载不同的权重参数
1.使用完一个模型后,在后边加上代码tf.reset_default_graph()用于清除默认图形堆栈并重置全局默认图形
注意事项:https://www.w3cschool.cn/tensorflow_python/tensorflow_python-nmgf2idd.html
2.对每个模型创建多个计算图(Graph)
tf中可以定义多个计算图,不同计算图上的张量和运算是相互独立的,不会共享。计算图可以用来隔离张量和计算,同时提供了管理张量和计算的机制。计算图可以通过Graph.device函数来指定运行计算的设备,为TensorFlow充分利用GPU/CPU提供了机制。
使用方法见:https://blog.youkuaiyun.com/dcrmg/article/details/79028032
二、 共享变量
当训练复杂模型时,经常需要共享大量的变量,但我们经常会遇到以下问题:如创建一个简单地图像滤波器模型,假如只是用tf.Variable,模型可以写成如下形式:
def my_image_filter(input_images):
conv1_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
name="conv1_weights")
conv1_biases = tf.Variable(tf.zeros([32]), name="conv1_biases")
conv1 = tf.nn.conv2d(input_images, conv1_weights,
strides=[1, 1, 1, 1], padding='SAME')
relu1 = tf.nn.relu(conv1 + conv1_biases)
conv2_weights = tf.Variable(tf.random_normal([5, 5, 32, 32]),
name="conv2_weights")
conv2_biases = tf.Variable(tf.zeros([32]), name="conv2_biases")
conv2 = tf.nn.conv2d(relu1, conv2_weights,
strides=[1, 1, 1, 1], padding='SAME')
return tf.nn.relu(conv2 + conv2_biases)
模型有4个不同的变量:conv1_weights, conv1_biases, conv2_weights, conv2_biases。
当我们想两次调用模型时(模型参数相同),不会出现错误,但这两次调用的模型会创建两套不同的参数集。
# First call creates one set of 4 variables.
result1 = my_image_filter(image1)
# Another set of 4 variables is created in the second call.
result2 = my_image_filter(image2)
而且当模型更加复杂时,我们会需要创建更多的变量,当代码更改时,调用者需要创建更多或更少的不同变量。
为了实现共享变量,tensorflow采用了两个函数:
tf.variable_scope(<scope_name>): 管理传递给tf.get_variable()的names的命名空间
tf.get_variable(<name>, <shape>, <initializer>): 创建或返回一个给定名字的变量
实现过程的代码:
def conv_relu(input, kernel_shape, bias_shape):
# Create variable named "weights".
weights = tf.get_variable("weights", kernel_shape,
initializer=tf.random_normal_initializer())
# Create variable named "biases".
biases = tf.get_variable("biases", bias_shape,
initializer=tf.constant_initializer(0.0))
conv = tf.nn.conv2d(input, weights,
strides=[1, 1, 1, 1], padding='SAME')
return tf.nn.relu(conv + biases)
在单独的函数中创建卷积的代码,使用tf.get_variable()函数创建两个变量“weights”和“biases”,在调用的过程中希望同一输入数据进行不同卷积时创建不同的变量名称。而不同数据输入(多样本训练)获取相同的参数,因此采用tf.variable_scope()函数为每个卷积创建各自的变量命名空间。代码如下:
def my_image_filter(input_images):
with tf.variable_scope("conv1"):
# Variables created here will be named "conv1/weights", "conv1/biases".
relu1 = conv_relu(input_images, [5, 5, 32, 32], [32])
with tf.variable_scope("conv2"):
# Variables created here will be named "conv2/weights", "conv2/biases".
return conv_relu(relu1, [5, 5, 32, 32], [32])
输出的变量名称带有各自的命名空间:conv1/weights,conv1/biases;conv2/weights,conv2/biases;
但是当我们直接两次调用该方法时(对两个测试集用同一个模型进行测试时,依次直接向模型送入数据时)就会产生以下错误:
result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
# Raises ValueError(... conv1/weights already exists ...)
这是因为tf.get_variable() 会检查已存在的变量是不是意外地共享。为了避免该错误并且可以使用同一模型和参数,我们需要设置reuse_variables()
with tf.variable_scope("image_filters") as scope:
result1 = my_image_filter(image1)
scope.reuse_variables() # or
#tf.get_variable_scope().reuse_variables()
result2 = my_image_filter(image2)
对于reuse_variables()的使用有两种状态:False和True,该过程是通过tf.get_variable()的检查来工作的
1.当False 时,作用域就是为创建新变量所设置的。这种情况下会通过 tf.get_Variable() 所提供的形状和数据类型来重新创建变量. 创建变量的全称将会由当前变量作用域名 + 所提供的名字所组成 , 并且还会检查来确保没有任何变量使用这个全称 . 如果这个全称已经有一个变量使用了,那么方法将会抛出
ValueError 错误 .# Raises ValueError(… conv1/weights already exists …)------如上边情况
情况 2 :当True 时,作用域是为重用变量所设置,这种情况下,调用就会搜索一个已经存在的变量,他的全称和当前变量的作用域名+ 所提供的名字是否相等。如果不存在相应的变量,就会抛出 ValueError 错误。如果变量找到了,就返回这个变量。
tf.variable_scope(<scope_name>) 变量作用域的主方法带有一个名称,它将会作为前缀用于变量名 , 并且带有一个重用标签来区分以上的两种情况。当前变量作用域可以用 tf.get_variable_scope() 进行检索并且 reuse 标签可以通过调用 tf.get_variable_scope().reuse_variables() 设置为 True。
参考博客:
https://www.cnblogs.com/max-hu/p/7113554.html
https://blog.youkuaiyun.com/yuehanliushuang/article/details/63253320
本文详述了TensorFlow中如何在同一模型下装载不同权重参数的方法,包括使用tf.reset_default_graph()清除默认图形堆栈及创建多个计算图。深入探讨了共享变量的实现,利用tf.variable_scope()和tf.get_variable()函数管理变量命名空间,避免重复创建变量,并介绍了reuse_variables()的使用技巧。
1万+

被折叠的 条评论
为什么被折叠?



