Tensorflow学习笔记(三)--变量作用域

变量作用域机制主要由两个函数实现:

tf.get_variable(<name>, <shape>, <initializer>)
tf.variable_scope(<scope_name>)

常用的initializer有

tf.constant_initializer(value) # 初始化一个常量值,
tf.random_uniform_initializer(a, b) # 从a到b均匀分布的初始化,
tf.random_normal_initializer(mean, stddev) # 用所给平均值和标准差初始化正态分布.

对如下实例,

with tf.variable_scope(conv1):
    # Variables created here will be named "conv1/weights".
    weights = tf.get_variable('weights',kernel_shape,
              initializer=tf.random_normal_initializer())

    # Variables created here will be named "conv1/biases".
    biases = tf.get_variable('biases',biases_shape,
              initializer=tf.constant_intializer(0.0))

变量作用域的tf.variable_scope()带有一个名称,它将会作为前缀用于变量名,并且带有一个重用标签(后面会说到)来区分以上的两种情况。嵌套的作用域附加名字所用的规则和文件目录的规则很类似。

对于采用了变量作用域的网络结构,结构伪代码如下:

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_intializer(0.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"):
    # 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])

如果连续调用两次my_image_filter()将会报出ValueError:

result1 = my_image_filter(image1)
result2 = my_image_filter(image2)
# Raises ValueError(... conv1/weights already exists ...)

若不在网络架构中采用变量作用域则不会报错,但是会产生两组变量,而不是共享变量。

变量作用域是怎么工作的?

理解tf.get_variable()

情况1:当tf.get_variable_scope().reuse == False时,该方法用来创建新变量。

with tf.variable_scope("foo"):
    v = tf.get_variable("v", [1])
assert v.name == "foo/v:0"

该情况下方法会生成一个“foo/v”,并检查确保没有其他变量使用该全称。如果该全程已经有其他的变量在使用了,则会抛出ValueError。

情况2:当tf.get_variable_scope().reuse == True时,该方法是为重用变量所设置

with tf.variable_scope("foo"):
    v = tf.get_variable("v", [1])
with tf.variable_scope("foo", reuse=True):
    v1 = tf.get_variable("v", [1])
assert v1 == v

该情况下会搜索一个已存在的“foo/v”并将该变量的值赋给v1,若找不到“foo/v”变量则会抛出ValueError。

注意reuse标签可以被手动设置为True,但不能手动设置为False。reuse 参数是不可继承的,所以当你设置一个变量作用域为重用作用域时,那么其所有的子作用域也将会被重用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值