1. 程式人生 > >TensorFlow學習筆記(4) 變數管理

TensorFlow學習筆記(4) 變數管理

隨著神經網路的結構更加複雜,引數更多時,需要一個更好的方式來傳遞和管理變數。在TF中提供了通過變數的名字來建立或者獲取一個變數的機制,通過這個機制不同函式可以直接通過變數的名字來直接使用變數。這機制主要是通過tf.get_variable和tf.variable_scope實現的。

除了tf.Variable建立函式,TF也提供了tf.get_variable函式來建立或者獲取變數。當tf.get_variable用來建立變數時,其功能與tf.Variable是等價的。比如:

v = tf.get_variable('v', shape=[1], initializer=tf.constant_initializer(1.0))
v = tf.Variable(tf.constant(1.0, shape=[1], name='v'))

tf.Variable和tf.get_variable最大的區別在於指定變數名稱的引數。對於tf.Variable,變數名稱是一個可選的引數,通過name='v'給出。但是對於tf.get_variable函式,變數名稱是一個必填的引數,tf.get_variable會根據這個名字去建立引數。但是如果試圖建立一個已經存在的名字,那麼這個函式就會報錯。

如果需要通過tf.get_variable來獲取一個已經建立的變數,則需要通過tf.variable_scope來生成一個上下文管理器來控制tf.get_variable函式獲取已建立的變數:

#在名字為foo的名稱空間中建立名字為v的變數
with tf.variable_scope('foo'):
    v = tf.get_variable('v',[1],initializer=tf.constant_initializer(1.0))

#由於已經存在v,所以以下程式碼將會報錯
with tf.variable_scope('foo'):
    v = tf.get_variable('v',[1])
#Variable foo/v already exists, disallowed. Did you mean to set reuse=True in VarScope?

#在生成上下文管理器時,將reuse設定為True,即可獲取變數
with tf.variable_scope('foo', reuse=True):
    v = tf.get_variable('v',[1])
tf.variable_scope函式會建立一個TF的名稱空間,在名稱空間內建立的變數名稱都會帶上這個空間名字作為字首,所以這個函式也提供了一個管理變數名稱空間的方式:
v1= tf.get_variable('v', [1])
print(v1.name)
#v:0
#0表示是這個變數運算的第一個結果

with tf.variable_scope('foo'):
    v2 = tf.get_variable('v', [1])
    print(v2.name)
#foo/v:0

with tf.variable_scope('foo'):
    with tf.variable_scope('bar'):
        v3 = tf.get_variable('v', [1])
        print(v3.name)
#foo/bar/v:0

with tf.variable_scope('',reuse=True):
    v5 = tf.get_variable('foo/bar/v', [1])
    print(v5 = v3)
    #True
使用這種方法對本文剛開始的TF模型進行改進,這種方法可以提高複雜程式的可讀性:
def inference(input_tensor,avg_class,regularizer):
    if avg_class==None:
        with tf.variable_scope('layer1'):
            weights = tf.get_variable('weights', [INPUT_NODE, LAYER1_NODE], initializer=tf.truncated_normal_initializer(stddev=0.1))
            biases = tf.get_variable("biases", [LAYER1_NODE], initializer=tf.constant_initializer(0.0))
            layer1 = tf.nn.relu(tf.matmul(input_tensor, weights) + biases)


        with tf.variable_scope('layer2'):
            weights = tf.get_variable('weights', [LAYER1_NODE, OUT_NODE], initializer=tf.truncated_normal_initializer(stddev=0.1))
            biases = tf.get_variable("biases", [OUT_NODE], initializer=tf.constant_initializer(0.0))
            layer2 = tf.matmul(layer1, weights) + biases
        return layer2
    
    else:
        with tf.variable_scope('layer1',reuse=True):
            weights = tf.get_variable('weights', [INPUT_NODE, LAYER1_NODE], initializer=tf.truncated_normal_initializer(stddev=0.1))
            biases = tf.get_variable("biases", [LAYER1_NODE], initializer=tf.constant_initializer(0.0))
            layer1 = tf.nn.relu(tf.matmul(input_tensor,avg_class.average(weights))+avg_class.average(biases))


        with tf.variable_scope('layer2',reuse=True):
            weights = tf.get_variable('weights', [LAYER1_NODE, OUT_NODE], initializer=tf.truncated_normal_initializer(stddev=0.1))
            biases = tf.get_variable("biases", [OUT_NODE], initializer=tf.constant_initializer(0.0))
            layer2 = tf.matmul(layer1,avg_class.average(weights))+avg_class.average(biases)
        return layer2

x = tf.placeholder(tf.float32, [None, INPUT_NODE], name='x-input')
y = inference(x)

#若需要使用訓練好的神經網路進行推導時
new_x = ...
new_y = inference(new_x, True)


源自:Tensorflow 實戰Google深度學習框架_鄭澤宇