1. 程式人生 > >tensorflow variable_scope共享變數

tensorflow variable_scope共享變數

tf.Variable(<variable_name>)用於建立一個新變數,可以建立相同名字變數,底層會自動引入別名機制,給新建立的變數名加數字,兩個變數是不相同的
tf.get_variable(<variable_name>)獲取一個變數,當變數已經存在,會報錯,顯示變數已經存在;不存在會建立一個新變數。無視name_scope

tf.get_variable(name, shape, dtype, initializer)

initializer初始化器:

tf.constant_initializer(value) 初始化一切所提供的值,
tf.random_uniform_initializer(a, b)從a到b均勻初始化,
tf.random_normal_initializer(mean, stddev) 用所給平均值和標準差初始化正態分佈
tf.truncated_normal_initializer(mean, stddev) :擷取的正態分佈
tf.zeros_initializer():全部是0
tf.ones_initializer():全是1


tf.name_scope(<scope_name>)

主要用於管理一個圖裡面的各種op,返回的是一個以scope_name命名的context manager。

import tensorflow as tf

with tf.name_scope("a_name_scope"):
    initializer = tf.constant_initializer(value=1)
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    # tf.get_variable()定義的變數不會被tf.name_scope()當中的名字所影響。
    var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
    var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)


with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print(var1.name)        # var1:0
    print(sess.run(var1))   # [ 1.]
    print(var2.name)        # a_name_scope/var2:0
    print(sess.run(var2))   # [ 2.]
    print(var21.name)       # a_name_scope/var2_1:0
    print(sess.run(var21))  # [ 2.0999999]
    print(var22.name)       # a_name_scope/var2_2:0
    print(sess.run(var22))  # [ 2.20000005]


共享變數:

tf.variable_scope(<scope_name>)
管理一個圖中的變數名,避免變數之間的命名衝突,允許在一個variable_scope下面共享變數。

如果想要達到重複利用變數的效果,我們就要使用tf.variable_scope(),並搭配tf.get_variable()這種方式產生和提取變數。不像tf.Variable()每次都會產生新的變數,tf.get_variable()如果遇到了同樣名字的變數時,需要在該變數定義的後面強調scope.reuse_variables(),表示該變數可以重複使用,否則會報錯

import tensorflow as tf

with tf.variable_scope("a_variable_scope") as scope:
    initializer = tf.constant_initializer(value=3)
    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
    scope.reuse_variables()  # 宣告前面出現的變數為共享變數
    var3_reuse = tf.get_variable(name='var3', )

    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)  # a_variable_scope/var3:0
    print(sess.run(var3))  # [ 3.]
    print(var3_reuse.name)  # a_variable_scope/var3:0
    print(sess.run(var3_reuse))  # [ 3.]
    print(var4.name)  # a_variable_scope/var4:0
    print(sess.run(var4))  # [ 4.]
    print(var4_reuse.name)  # a_variable_scope/var4_1:0
    print(sess.run(var4_reuse))  # [ 4.]


共享變數在class中的使用(tf.get_variable() + tf.variable_scope)

共享類中變數的兩種方式:

方式一:

class A(object):
    def __init__(self):
        self.a = tf.get_variable('a', [1], dtype=tf.float32)
        self.b = tf.assign(self.a, [10])


with tf.variable_scope('AA', reuse=False):
    x = A()
with tf.variable_scope('AA', reuse=True):
    y = A()

sess = tf.Session()
print(sess.run(x.b))  # [10.]
print(sess.run(y.a))  # [10.]

方式二:
class A(object):
    def __init__(self):
        self.a = tf.get_variable('a', [1], dtype=tf.float32)
        self.b = tf.assign(self.a, [10])


with tf.variable_scope('AA'):
    x = A()
    tf.get_variable_scope().reuse_variables()
    y = A()

sess = tf.Session()
print(sess.run(x.b))  # [10.]
print(sess.run(y.a))  # [10.]