TensorFlow入門(四) name / variable_scope 的使用

name/variable_scope 的作用

歡迎轉載,但請務必註明原文出處及作者信息。

@author: huangyongye
@creat_date: 2017-03-08

refer to: Sharing Variables

name / variable_scope 詳細理解請看: TensorFlow入門(七) 充分理解 name / variable_scope

* 起因:在運行 RNN LSTM 實例代碼的時候出現 ValueError。 *
在 TensorFlow 中,經常會看到這兩個東東出現,這到底是什麼鬼,是用來幹嘛的。在做 LSTM 的時候遇到了下面的錯誤:

ValueError: Variable rnn/basic_lstm_cell/weights already exists, disallowed.

然後谷歌百度都查了一遍,結果也不知是咋回事。我是在 jupyter notebook 運行的示例程序,第一次運行的時候沒錯,然後就總是出現上面的錯誤。後來才知道是 get_variable() 和 variable_scope() 搞的鬼。

下面就來分析一下 TensorFlow 中到底用這來幹啥。

import tensorflow as tf
# 設置GPU按需增長
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)

1. 首先看看比較簡單的 tf.name_scope(‘scope_name’).

tf.name_scope 主要結合 tf.Variable() 來使用,方便參數命名管理。

'''
Signature: tf.name_scope(*args, **kwds)
Docstring:
Returns a context manager for use when defining a Python op.
'''
# 也就是說,它的主要目的是爲了更加方便地管理參數命名。
# 與 tf.Variable() 結合使用。簡化了命名
with tf.name_scope('conv1') as scope:
    weights1 = tf.Variable([1.0, 2.0], name='weights')
    bias1 = tf.Variable([0.3], name='bias')

# 下面是在另外一個命名空間來定義變量的
with tf.name_scope('conv2') as scope:
    weights2 = tf.Variable([4.0, 2.0], name='weights')
    bias2 = tf.Variable([0.33], name='bias')

# 所以,實際上weights1 和 weights2 這兩個引用名指向了不同的空間,不會衝突
print weights1.name
print weights2.name
conv1/weights:0
conv2/weights:0
# 注意,這裏的 with 和 python 中其他的 with 是不一樣的
# 執行完 with 裏邊的語句之後,這個 conv1/ 和 conv2/ 空間還是在內存中的。這時候如果再次執行上面的代碼
# 就會再生成其他命名空間
with tf.name_scope('conv1') as scope:
    weights1 = tf.Variable([1.0, 2.0], name='weights')
    bias1 = tf.Variable([0.3], name='bias')

with tf.name_scope('conv2') as scope:
    weights2 = tf.Variable([4.0, 2.0], name='weights')
    bias2 = tf.Variable([0.33], name='bias')

print weights1.name
print weights2.name
conv1_1/weights:0
conv2_1/weights:0
import tensorflow as tf

2.下面來看看 tf.variable_scope(‘scope_name’)

tf.variable_scope() 主要結合 tf.get_variable() 來使用,實現 變量共享。

# 這裏是正確的打開方式~~~可以看出,name 參數纔是對象的唯一標識
import tensorflow as tf
with tf.variable_scope('v_scope') as scope1:
    Weights1 = tf.get_variable('Weights', shape=[2,3])
    bias1 = tf.get_variable('bias', shape=[3])

# 下面來共享上面已經定義好的變量
# note: 在下面的 scope 中的變量必須已經定義過了,才能設置 reuse=True,否則會報錯
with tf.variable_scope('v_scope', reuse=True) as scope2:
    Weights2 = tf.get_variable('Weights')

print Weights1.name
print Weights2.name
# 可以看到這兩個引用名稱指向的是同一個內存對象
v_scope/Weights:0
v_scope/Weights:0

也可以結合 tf.Variable() 一塊使用。

import tensorflow as tf
# 注意, bias1 的定義方式
with tf.variable_scope('v_scope') as scope1:
    Weights1 = tf.get_variable('Weights', shape=[2,3])
#     bias1 = tf.Variable([0.52], name='bias')

# 下面來共享上面已經定義好的變量
# note: 在下面的 scope 中的get_variable()變量必須已經定義過了,才能設置 reuse=True,否則會報錯
with tf.variable_scope('v_scope', reuse=True) as scope2:
    Weights2 = tf.get_variable('Weights')
    bias2 = tf.Variable([0.52], name='bias')

print Weights1.name
print Weights2.name
print bias2.name
v_scope/Weights:0
v_scope/Weights:0
v_scope_1/bias:0

如果 reuse=True 的scope中的變量沒有已經定義,會報錯!!

import tensorflow as tf
# 注意, bias1 的定義方式
with tf.variable_scope('v_scope') as scope1:
    Weights1 = tf.get_variable('Weights', shape=[2,3])
    bias1 = tf.Variable([0.52], name='bias')

print Weights1.name
print bias1.name

# 下面來共享上面已經定義好的變量
# note: 在下面的 scope 中的get_variable()變量必須已經定義過了,才能設置 reuse=True,否則會報錯
with tf.variable_scope('v_scope', reuse=True) as scope2:
    Weights2 = tf.get_variable('Weights')
    bias2 = tf.get_variable('bias', [1])  # ‘bias

print Weights2.name
print bias2.name

# 這樣子的話就會報錯
# Variable v_scope/bias does not exist, or was not created with tf.get_variable()
v_scope/Weights:0
v_scope/bias:0

本文代碼:https://github.com/yongyehuang/Tensorflow-Tutorial

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章