1. 程式人生 > >tensorflow裏面共享變量、name_scope, variable_scope等如何理解

tensorflow裏面共享變量、name_scope, variable_scope等如何理解

char trac dsm 網絡 asm vars 知乎 簡單 AS

tensorflow裏面共享變量、name_scope, variable_scope等如何理解

  • name_scope, variable_scope目的:1 減少訓練參數的個數。 2 區別同名變量

  • 為什麽要共享變量?我舉個簡單的例子:例如,當我們研究生成對抗網絡GAN的時候,判別器的任務是,如果接收到的是生成器生成的圖像,判別器就嘗試優化自己的網絡結構來使自己輸出0,如果接收到的是來自真實數據的圖像,那麽就嘗試優化自己的網絡結構來使自己輸出1。也就是說,生成圖像和真實圖像經過判別器的時候,要共享同一套變量,所以TensorFlow引入了變量共享機制。

    來源:http://www.cnblogs.com/Charles-Wan/p/6200446.html

四個tf.Variable(), tf.get_variable(), tf.Variable_scope(), tf.name_scope()的區別:

  1. tf.Variable()和 tf.get_variable() :

    • tf.Variable()會自動檢測命名沖突並自行處理。tf.get_variable()有一個變量檢測機制,會檢測已經存在的變量時否設置為共享變量,如果已經存在該變量且沒有被設置為共享變量,則TensorFlow運行到第二個變量時會報。

    • tf.Variable()和 tf.get_variable()這兩種方式都用在一個name_scope下面獲取或創建一個變量的兩種方式的區別在於:tf.Variable()用於創建一個新變量,在同一個name_scope下可以創建相同名字的變量,底層實現會自動引入別名機制,兩次調用產生兩個不同的變量。tf.get_variable()用於獲取一個變量,並且不受name_scope的約束,當這個變量已經存在,則自動獲取,如果不存在,則自動創建一個變量。

    • code解析:

作者:C Li
鏈接:https://www.zhihu.com/question/54513728/answer/181819324
來源:知乎

‘‘‘
1 在tf.name_scope下時,tf.get_variable()創建的變量名不受name_scope的影響,而在未指定共享變量時,如果重名就會報錯,tf.Variable()會自動檢測有沒有變量重名,如果有則會自行處理。
‘‘‘
import tensorflow as tf
with tf.name_scope(‘name_scope_x‘):
    var1 = tf.get_variable(name=‘var1‘, shape=[1], dtype=tf.float32)
    var3 = tf.Variable(name=‘var2‘, initial_value=[2], dtype=tf.float32)
    var4 = tf.Variable(name=‘var2‘, initial_value=[2], dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name, sess.run(var1))
    print(var3.name, sess.run(var3))
    print(var4.name, sess.run(var4))
# 輸出結果:
# var1:0 [-0.30036557]   可以看到前面不含有指定的‘name_scope_x‘
# name_scope_x/var2:0 [ 2.]
# name_scope_x/var2_1:0 [ 2.]  可以看到變量名自行變成了‘var2_1‘,避免了和‘var2‘沖突

‘‘‘
2 使用tf.get_variable()創建變量,且沒有設置共享變量,重名時會報錯。
‘‘‘
import tensorflow as tf
with tf.name_scope(‘name_scope_1‘):
    var1 = tf.get_variable(name=‘var1‘, shape=[1], dtype=tf.float32)
    var2 = tf.get_variable(name=‘var1‘, shape=[1], dtype=tf.float32)
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name, sess.run(var1))
    print(var2.name, sess.run(var2))

# ValueError: Variable var1 already exists, disallowed. Did you mean 
# to set reuse=True in VarScope? Originally defined at:
# var1 = tf.get_variable(name=‘var1‘, shape=[1], dtype=tf.float32)

‘‘‘
3 共享變量方法,(要共享變量就要使用tf.get_variable(<variable_name>)
‘‘‘
import tensorflow as tf
with tf.variable_scope(‘variable_scope_y‘) as scope:
    var1 = tf.get_variable(name=‘var1‘, shape=[1], dtype=tf.float32)
    scope.reuse_variables()  # 設置共享變量
    var1_reuse = tf.get_variable(name=‘var1‘)
    var2 = tf.Variable(initial_value=[2.], name=‘var2‘, dtype=tf.float32)
    var2_reuse = tf.Variable(initial_value=[2.], name=‘var2‘, dtype=tf.float32)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var1.name, sess.run(var1))
    print(var1_reuse.name, sess.run(var1_reuse))
    print(var2.name, sess.run(var2))
    print(var2_reuse.name, sess.run(var2_reuse))
# 輸出結果:
# variable_scope_y/var1:0 [-1.59682846]
# variable_scope_y/var1:0 [-1.59682846]   可以看到變量var1_reuse重復使用了var1
# variable_scope_y/var2:0 [ 2.]
# variable_scope_y/var2_1:0 [ 2.]

‘‘‘
或者
‘‘‘
with tf.variable_scope(‘foo‘) as foo_scope:
    v = tf.get_variable(‘v‘, [1])
with tf.variable_scope(‘foo‘, reuse=True):
    v1 = tf.get_variable(‘v‘)
assert v1 == v

‘‘‘
或者
‘‘‘
with tf.variable_scope(‘foo‘) as foo_scope:
    v = tf.get_variable(‘v‘, [1])
with tf.variable_scope(foo_scope, reuse=True):
    v1 = tf.get_variable(‘v‘)
assert v1 == v

  1. tf.name_scope()與tf.variable_scope():

    • tf.name_scope()主要用於管理一個圖裏的各種op,返回的是一個以scope_name命名的context manager。一個graph會維護一個name_space的堆,每一個namespace下面可以定義各種op或者子namespace,實現一種層次化有條理的管理,避免各個op之間命名沖突。

    • tf.variable_scope()一般與tf.name_scope()配合使用,用於管理一個graph中變量的名字,避免變量之間的命名沖突,tf.variable_scope()允許在一個variable_scope下面共享變量。variable_scope的reuse的默認值為False。

    • 通常情況下,tf.variable_scope和tf.name_scope配合,能畫出非常漂亮的流程圖,但是他們兩個之間又有著細微的差別,那就是name_scope只能管住操作ops的名字,而管不住變量Variables的名字。

    with tf.variable_scope("foo"):
       with tf.name_scope("bar"):
           v = tf.get_variable("v", [1])
           x = 1.0 + v
    assert v.name == "foo/v:0"
    assert x.op.name == "foo/bar/add"

tensorflow裏面共享變量、name_scope, variable_scope等如何理解