今天說一下tensorflow的變量共享機制,首先為什麼會有變量共享機制? 這個還是要扯一下生成對抗網絡GAN,我們知道GAN由兩個網絡組成,一個是生成器網絡G,一個是判别器網絡D。G的任務是由輸入的隐變量z生成一張圖像G(z)出來,D的任務是區分G(z)和訓練資料中的真實的圖像(real images)。是以這裡D的輸入就有2個,但是這兩個輸入是共享D網絡的參數的,簡單說,也就是權重和偏置。而TensorFlow的變量共享機制,正好可以解決這個問題。但是我現在不能确定,TF的這個機制是不是因為GAN的提出才有的,還是本身就存在。
是以變量共享的目的就是為了在對網絡第二次使用的時候,可以使用同一套模型參數。TF中是由Variable_scope來實作的,下面我通過幾個栗子,徹底弄明白到底該怎麼使用,以及使用中會出現的錯誤。栗子來源于文檔,然後我寫了不同的情況,希望能幫到你。
# - * - coding:utf-8 - * -
import tensorflow as tf
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
def fc_variable():
v1 = tf.Variable(
initial_value=tf.random_normal(
shape=[2, 3], mean=0., stddev=1.),
dtype=tf.float32,
name='variable_1')
print v1
print "- v1 - * " * 5
return v1
"""
<tf.Variable 'variable_1:0' shape=(2, 3) dtype=float32_ref>
- v1 - * - v1 - * - v1 - * - v1 - * - v1 - *
"""
def variable_value(variables):
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# 如果沒有這句會報錯,是以tf在調用變量之前主要
# 先初始化
"""
tensorflow.python.framework.errors_impl.
FailedPreconditionError: Attempting to use
uninitialized value variable_1
"""
print '- * - value: - * - ' * 3
print sess.run(variables)
"""
[[ 0.00556329 0.20311342 -0.79569227]
[ 0.1700473 0.9499892 -0.46801034]]
"""
def fc_variable_scope():
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
print v.name
w = tf.get_variable("w", [1])
print w.name
with tf.variable_scope("foo", reuse=True):
v1 = tf.get_variable("v")
print v1.name
"""
foo/v:0
foo/w:0
foo/v:0
"""
# 解釋:
# 這裡說明v1和v的相同的,還有這裡用的是
# get_variable定義的變量,這個和Variable
# 定義變量的差別是,如果變量存在get_variable
# 會獲得他的值,如果不存在則建立變量
def fc_variable_scope_v2():
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
print v.name
w = tf.get_variable("w", [1])
print w.name
with tf.variable_scope("foo", reuse=False):
v1 = tf.get_variable("v")
print v1.name
"""
ValueError: Variable foo/v already exists, disallowed.
Did you mean to set reuse=True in VarScope? Originally
defined at:
"""
# 解釋:
# 當reuse為False的時候由于v1在'fool'這個scope裡面,
# 是以和v的name是一樣的,而reuse為False,變量命名就起了沖突。
def fc_variable_scope_v3():
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
print v.name
w = tf.get_variable("w", [1])
print w.name
with tf.variable_scope("foo", reuse=True):
v1 = tf.get_variable("u", [1])
print v1.name
"""
ValueError: Variable foo/u does not exist,
or was not created with tf.get_variable().
Did you mean to set reuse=None in VarScope?
"""
# 解釋:
# 當reuse為True時時候,而這裡定義了新變量u,
# 之前不存在,這樣也無法reuse。
def fc_variable_scope_v4():
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
print v.name
w = tf.get_variable("w", [1])
print w.name
with tf.variable_scope("foo", reuse=False):
v1 = tf.get_variable("u")
print v1.name
"""
ValueError: Shape of a new variable (foo/u)
must be fully defined, but instead was <unknown>.
"""
# 解釋:
# 這裡reuse為Flase,但是定義新變量的時候,
# 必須define fully變量,也就是要指定變量
# 的shape或者初始值等。
def fc_variable_scope_v5():
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
print dir(v)
print v.name
w = tf.get_variable("w", [1])
print w.name
with tf.variable_scope("foo", reuse=False):
v1 = tf.get_variable("u", [1])
print v1.name
"""
foo/v:0
foo/w:0
foo/u:0
"""
# 這樣就沒錯了
def fc_variable_scope_v6():
with tf.variable_scope("foo"):
v1 = tf.Variable(tf.random_normal(
shape=[2, 3], mean=0., stddev=1.),
dtype=tf.float32, name='v1')
print v1.name
v2 = tf.get_variable("v2", [1])
print v2.name
with tf.variable_scope("foo", reuse=True):
v3 = tf.get_variable('v2')
print v3.name
v4 = tf.get_variable('v1')
print v4.name
"""
foo/v1:0
foo/v2:0
foo/v2:0
ValueError: Variable foo/v1 does not exist, or
was not created with tf.get_variable(). Did
you mean to set reuse=None in VarScope?
"""
# 解釋:
# 這裡雖然reuse為True,但是v1是由Variable定義的,
# 不能被get。
def compare_name_and_variable_scope():
with tf.name_scope("hello") as ns:
arr1 = tf.get_variable(
"arr1", shape=[2, 10], dtype=tf.float32)
print (arr1.name)
print " - * -" * 5
with tf.variable_scope("hello") as vs:
arr1 = tf.get_variable(
"arr1", shape=[2, 10], dtype=tf.float32)
print (arr1.name)
"""
arr1:0
- * - - * - - * - - * - - * -
hello/arr1:0
"""
#解釋:
# 這裡除了name_scope和variable_scope不同,
# 其他都相同,但是從他們的name,也能看出來差別了。
if __name__ == "__main__":
fc_variable_scope_v6()
# # 需要測試那個函數,直接寫在這裡。
複制
簡單總結一下,今天的内容主要是變量定義的兩種方法,Variable個get_variable,還有變量的範圍以及reuse是什麼鬼。通過幾個栗子,應該明白了。
明天要說的是用TensorFlow實作Kmeans聚類,歡迎關注~
============End============