1. 程式人生 > >TensorFlow作用域:name_scope和variable_scope

TensorFlow作用域:name_scope和variable_scope

在TensorFlow中有兩個作用域,一個是name_scope,另一個是variable_scope。variable_scope主要是給variable_name加字首的,也給op_name加字首;name_scope是給op_name加字首。

1、variable_scope示例

variable_scope變數作用域機制在TensorFlow中主要由兩部分組成:

v = tf.get_variable()#通過所給的名字建立或是返回一個變數
tf.variable_scope()#為變數指定名稱空間

當reuse=False時,

with tf.variable
_scope("foo") : v = tf.get_variable("v",[1]) v2 = tf.get_variable("v",[1])

丟擲錯誤,因為v這個變數已經被定義過了。

作用域可以共享變數:

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

輸出:True

1.獲取變數作用域
#可以直接通過tf.variable_scope()來獲取變數作用域
with tf.variable_scope("foo") as foo_scope:
    v = tf.get_variable("v",[1])

with tf.variable_scope(foo_scope):
    w = tf.get_variable("w",[1])

如果在開啟的一個變數作用域裡使用之前預先定義的一個作用域,則會跳過當前變數作用域,保持預先存在的作用域不變

with tf.variable_scope("foo") as foo_scope:
    print(foo_scope.name)
with
tf.variable_scope("bar") : with tf.variable_scope("barz") as other_scope: print(other_scope.name) #如果在開啟的一個變數作用域裡使用之前預先定義的一個作用域,則會跳過當前變數的作用域,保持預先存在的作用域不變 with tf.variable_scope(foo_scope) as foo_scope2: print(foo_scope2.name)#保持不變

輸出:

foo
bar/barz
foo

2、name_scope示例

TesnsorFlow中常常會有數以千計的節點,在視覺化的過程中很難一下子展示出來,因此用name_scope為變數劃分範圍,在視覺化中,這表示在計算圖中的一個層級。

with tf.name_scope('conv1') as scope:
    w1 = tf.Variable([1], name='weights')
    b1 = tf.Variable([0.3], name='bias')

with tf.name_scope('conv2') as scope:
    w2 = tf.Variable([1], name='weights')
    b2 = tf.Variable([0.3], name='bias')

print (w1.name)
print (w2.name)
print (b1.name)
print (b2.name)

輸出:

conv1/weights:0
conv2/weights:0
conv1/bias:0
conv2/bias:0

name_scope會影響op_name,不會影響用get_variable()建立的變數,而會影響通過Variable()建立的變數。

import tensorflow as tf

with tf.variable_scope("foo") :
    with tf.name_scope("bar"):
        v = tf.get_variable("v",[1])
        b = tf.Variable(tf.zeros([1]),name='b')
        x = 1.0 + v

print(v.name)
print(b.name)
print(x.op.name)

輸出:

foo/v:0
foo/bar/b:0
foo/bar/add

可以看出,name_scope對用get_variable建立的變數的名字不會有任何影響,而Variable建立的操作會被加上字首,並且會給操作加上名字字首。