tensorflow 筆記12:函數區別:placeholder,variable,get_variable,參數共享


一、函數意義: 

1、tf.Variable() 變量

W = tf.Variable(<initial-value>, name=<optional-name>)

用於生成一個初始值為initial-value的變量。必須指定初始化值

x = tf.Variable()

x.initializer          # 初始化單個變量

x.value()              # 讀取op

x.assign()             # 寫入op

x.assign_add()         # 更多op

x.eval()               # 輸出變量內容

2、tf.get_variable()  共享變量

原函數:

tf.get_variable(
    name,
    shape=None,
    dtype=None,
    initializer=None,
    regularizer=None,
    trainable=None,
    collections=None,
    caching_device=None,
    partitioner=None,
    validate_shape=True,
    use_resource=None,
    custom_getter=None,
    constraint=None,
    synchronization=tf.VariableSynchronization.AUTO,
    aggregation=tf.VariableAggregation.NONE
)
例如:
W = tf.get_variable(name, shape=None, dtype=tf.float32, initializer=None,
       regularizer=None, trainable=True, collections=None)

獲取已存在的變量(要求不僅名字,而且初始化方法等各個參數都一樣),如果不存在,就新建一個。 
可以用各種初始化方法,不用明確指定值。

3、tf.placeholder() 傳入變量

原函數:

tf.placeholder(dtype, shape=None, name=None)

placeholder 是 Tensorflow 中的占位符,暫時儲存變量.

Tensorflow 如果想要從外部傳入data, 那就需要用到 tf.placeholder(), 然后以這種形式傳輸數據 

sess.run(***, feed_dict={input: **}).

4、tf.constant() 常量(保存模型的時候也會保存這個常量)

原函數:

tf.constant(
    value,
    dtype=None,
    shape=None,
    name='Const',
    verify_shape=False
)

二、函數對比:

 tf.Variable() 和 tf.get_variable() 的區別

1. 初始化更方便

比如用xavier_initializer:

W = tf.get_variable("W", shape=[784, 256],
       initializer=tf.contrib.layers.xavier_initializer())

2. 方便共享變量

因為tf.get_variable() 會檢查當前命名空間下是否存在同樣name的變量,可以方便共享變量。

tf.Variable 每次都會新建一個變量。

需要注意的是tf.get_variable() 要配合reusetf.variable_scope() 使用。

所以推薦使用tf.get_variable()

3、代碼示例

在 Tensorflow 當中有兩種途徑生成變量 variable, 一種是 tf.get_variable(), 另一種是 tf.Variable(). 
  • 如果想要達到重復利用變量的效果, 我們就要使用 tf.variable_scope(), 並搭配 tf.get_variable()這種方式產生和提取變量.
  • 不像 tf.Variable() 每次都會產生新的變量, tf.get_variable() 如果遇到了同樣名字的變量時, 它會單純的提取這個同樣名字的變量(避免產生新變量).
  • 而在重復使用的時候, 一定要在代碼中強調 scope.reuse_variables(), 否則系統將會報錯, 以為你只是單純的不小心重復使用到了一個變量.
with tf.variable_scope("a_variable_scope") as scope:
    initializer = tf.constant_initializer(value=3)
    var3 = tf.get_variable(name='var3', shape=[1], dtype=tf.float32, initializer=initializer)
    scope.reuse_variables()# 如果不寫這句話,就會報錯,明明重復,聲明var3 下面還會使用
    var3_reuse = tf.get_variable(name='var3',)
    var4 = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    var4_reuse = tf.Variable(name='var4', initial_value=[4], dtype=tf.float32)
    
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(var3.name)            # a_variable_scope/var3:0
    print(sess.run(var3))       # [ 3.]
    print(var3_reuse.name)      # a_variable_scope/var3:0
    print(sess.run(var3_reuse)) # [ 3.]
    print(var4.name)            # a_variable_scope/var4:0
    print(sess.run(var4))       # [ 4.]
    print(var4_reuse.name)      # a_variable_scope/var4_1:0
    print(sess.run(var4_reuse)) # [ 4.]

4、tf.name_scope() 和 tf.variable_scope()  對比

來源莫煩:https://morvanzhou.github.io/tutorials/machine-learning/tensorflow/5-12-scope/

import tensorflow as tf

with tf.name_scope("a_name_scope"):
    initializer = tf.constant_initializer(value=1)
    var1 = tf.get_variable(name='var1', shape=[1], dtype=tf.float32, initializer=initializer)
    var2 = tf.Variable(name='var2', initial_value=[2], dtype=tf.float32)
    var21 = tf.Variable(name='var2', initial_value=[2.1], dtype=tf.float32)
    var22 = tf.Variable(name='var2', initial_value=[2.2], dtype=tf.float32)


with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print(var1.name)        # var1:0
    print(sess.run(var1))   # [ 1.]
    print(var2.name)        # a_name_scope/var2:0
    print(sess.run(var2))   # [ 2.]
    print(var21.name)       # a_name_scope/var2_1:0
    print(sess.run(var21))  # [ 2.0999999]
    print(var22.name)       # a_name_scope/var2_2:0
    print(sess.run(var22))  # [ 2.20000005]
可以看出使用 tf.Variable() 定義的時候, 雖然 name 都一樣, 但是為了不重復變量名, Tensorflow 輸出的變量名並不是一樣的. 
所以, 本質上 var2, var21, var22 並不是一樣的變量. 而另一方面, 使用tf.get_variable()定義的變量不會被tf.name_scope()當中的名字所影響.

5、訓練和測試時參數復用

讓 train_rnn 和 test_rnn 在同一個 tf.variable_scope('rnn') 之下,並且定義 scope.reuse_variables(), 使我們能把 train_rnn 的所有 weights, biases 參數全部綁定到 test_rnn 中.

這樣,不管兩者的 time_steps 有多不同, 結構有多不同, train_rnn W, b 參數更新成什么樣, test_rnn 的參數也更新成什么樣.

with tf.variable_scope('rnn') as scope:
    sess = tf.Session()
    train_rnn = RNN(train_config)
    scope.reuse_variables()# 這句話表示,所有訓練中的參數,在測試中都能使用,如果不寫,會報錯
    test_rnn = RNN(test_config)
    sess.run(tf.global_variables_initializer())

三、初始化變量:

初始化所有變量:

init = tf.global_variables_initializer() 

with tf.Session() as sess:
    sess.run(init)    

初始化一個變量子集:

init_ab = tf.variables_initializer([a, b], name = "init_ab")

with tf.Session() as sess:
    sess.run(init_ab)       

初始化單個變量:

W = tf.Variable(tf.zeros([784, 10])) 

with tf.Session() as sess:
    sess.run(W.initializer)   

隨機數,生成器:

函數名 隨機數分布 主要參數
tf.random_normal 正態分布 平均值、標准差、取值類型
tf.truncated_normal 正態分布,如果隨機數偏離均值超過2個標准差,就重新隨機 平均值、標准差、取值類型
tf.random_uniform 平均分布 最小值、最大值、取值類型
tf.random_gamma gamma分布 形狀參數alpha、尺度參數beta、取值類型

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM