TensorFlow graphs (TensorFlow的圖)
目前為止狱从,我們只將“圖”作為Tensorflow中某種抽象的、全方位的存在钱反。甚至沒有問過在我們開始編碼時操作如何自動附加到圖上」羝現(xiàn)在讓我們看一些例子,并關(guān)注TensorFlow Graph 對象允悦,學習一些例子到如何創(chuàng)建更多的圖,如何使用多種圖互相結(jié)合的例子虑啤。
創(chuàng)建一個圖的例子---圖的構(gòu)造器不需要任何變量:
import tensorflow as tf
# Create a new graph:
g = tf.Graph()
一旦你的graph (圖)初始化了,我們可以使用 Graph.as_default() 方法 獲取他的上下文管理器, 并來添加操作(OPs)隙弛。結(jié)合with語句,我們可以使用上下文管理器糖TensorFlow知道我們要將操作添加到特定的圖中:
可能你會問為什么之前的例子中狞山,我們在添加Ops的時候不需要指定圖呢全闷?為了方便起見,TensorFlow在加載庫的時候會自動創(chuàng)建圖铣墨,并且將這個圖指定為默認圖室埋。因此办绝,在Graph.as_default()上下文管理器之外定義的任何操作伊约、張量等都將會自動放置在默認圖形中:
with g.as_default():
# Create Operations as usual; they will be added to graph `g`
a = tf.mul(2, 3)
# Placed in the default graph
in_default_graph = tf.add(1,2)
# Placed in graph `g`
with g.as_default():
in_graph_g = tf.mul(2,3)
如果你想要獲得默認圖的句柄,可以使用tf.get_default_graph()函數(shù):
default_graph = tf.get_default_graph()
在大多數(shù)的TensorFlow程序中孕蝉,都只是用默認圖(graph)來處理屡律。不過,當你定義的多個模型沒有相互內(nèi)在的依賴的情況下降淮,創(chuàng)建多個圖的時候很有用超埋。當在一個文件中定義多個圖形,它要么不使用默認的圖形佳鳖,要么立即處理分配給它的最佳實踐霍殴。
Correct - Create new graphs, ignore default graph:
#正確的創(chuàng)建一個圖,而不使用默認圖
import tensorflow as tf
g1 = tf.get_default_graph()
g2 = tf.Graph()
with g1.as_default():
# Define g1 Operations, tensors, etc.
Incorrect: Mix default graph and user-created graph styles
#(不正確的方式)
import tensorflow as tf
g2 = tf.Graph()
# Define default graph Operations, tensors, etc.
...
with g2.as_default():
# Define g2 Operations, tensors, etc.
...
TensorFlow Sessions
正如之前的練習中所討論的一樣系吩,Session(會話)是負責graph(圖)執(zhí)行的来庭。其構(gòu)造函數(shù)函數(shù)?
有三個可選參數(shù):
?target? 指定要使用的引擎。對于很多應(yīng)用來說穿挨,其默認值是空字符串月弛。當在一個分布式的設(shè)置中使用的session 肴盏, 這個參數(shù)會用于連接 tf.train.Server 實例 (會在本書最后一張?zhí)峒埃?br>
?graph 指定在session中要加載的Graph 對象。
?config 允許用戶選擇session的配置帽衙,例如限制CPU或者是GPU的使用數(shù)量菜皂,設(shè)置圖中的優(yōu)化參數(shù)、日志選項厉萝。在典型的tensorflow程序中恍飘,session對象的創(chuàng)建可以不需要修改任何默認參數(shù)。
PS: 這參數(shù)對實驗調(diào)試很有幫助冀泻, 可以控制CPU 常侣、 GPU 的核數(shù)
import tensorflow as tf
# 用默認的圖創(chuàng)建操作、tensor 等
a = tf.add(2, 5)
b = tf.mul(a, 3)
# 在默認圖中開啟session
sess = tf.Session()
注意弹渔,這兩種調(diào)用是有區(qū)別的:
sess = tf.Session()
sess = tf.Session(graph = tf.get_default_graph() )
一旦一個session開啟胳施,你可以使用它主要的方法run()來計算期望的tensor輸出:
sess.run(b) # 返回結(jié)果21
Session.run() 需要一個參數(shù)--fetches , 同時也有三個可選參數(shù):feed_dict, options 和run_metadata 肢专。由于run_metadata和options在試驗中至今還沒有用到舞肆,并且時間有限, 我們不會覆蓋options 或者run_metadata的講解博杖。 但是feed_dict需要重點理解椿胯,后面會講到。
Fetches
fetches 可以接受任何圖中的用戶想要執(zhí)行的元素(既可以是操作Operation剃根,也可以是Tensor)哩盲。假如所需的對象的一個Ten 那么 run() 輸出的結(jié)果將會是一個Numpy 數(shù)組(array)。如果這個所需的 對象時Operation, 那么輸出的結(jié)果是None狈醉。
在上面的例子中廉油,我們設(shè)置fetches 給tensor b(是tf.mul()操作的輸出)。這是告訴Tensorflow:這個Session應(yīng)該找到計算b的值所需要的節(jié)點苗傅,并按照計算順序執(zhí)行抒线,最后輸出b。我們可以傳遞的值輸一個圖的元素:
```python
sess.run([a,b]) ## 返回值的是? [7, 21]
```
當fetchs是一個列表渣慕,run() 的輸出結(jié)果將會是也將是列表嘶炭,這個列表的值是響應(yīng)元素的輸出。在本例中逊桦,我們要求的是a和b的順序值眨猎。 由于a和b都是tensor(張量),我們會接受他們的值强经,并且作為輸出睡陪。
除了可以使用fetches來獲取Tensor的輸出以外, 我們也會看到例子中我們給fetchs 一個引用著Operation 的字典(direct)夕凝,在運行的時候會很有用宝穗。這個例子中的tf.initialize_all_variables()
是用于對所有的Tensorflow 變量(variable)的并行化做準備用的(variable 對象會在最后一節(jié)涉及到)户秤。我們依舊將Op作為fetches的參數(shù)傳遞。但是Session.run() 的返回結(jié)果將會是None:
```python
## 準備計算所需要初始化的變量逮矛,但是返回結(jié)果將會是‘None’
sess.run(tf.initialize_all_variables())
```
Feed dictionary
feed_dict參數(shù)可以使用圖中的Tensor值來覆蓋(overide)鸡号,這可以看做將一個python字典對象作為輸入。字典的key是引用的Tensor對象须鼎,可以被覆蓋鲸伴,key的值可以是數(shù)字、字符串晋控、列表以及Numpy 數(shù)組(之前也提到過)汞窗。字典中的value必須是與tensor 的key是同一類型(或者是可以轉(zhuǎn)化為統(tǒng)一類型)。讓我們展示一下如何使用feed_dict 覆蓋之前graph 中 a的值:
```python
import tensorflow as tf
## 創(chuàng)建操作赡译、tensor 等等(使用的是默認圖)
a = tf.add(2,3)
b = tf.mul(a,3)
## 使用默認的圖開啟一個'Session'
sess = tf.Session()
## 定義一個字典用于取代原來的值a=15
replace_dict={a:15}
# 傳遞參數(shù) repalce_dict 作為 feed_dict? 的值:
sess.run(b, feed_dict=replace_dict) # 返回 45
```
PS: 這里的dict是python 中的一個數(shù)據(jù)結(jié)構(gòu)仲吏,這種數(shù)據(jù)結(jié)構(gòu)類似于java里的map, 都是key-value形式的蝌焚,簡稱為鍵值對形式裹唆, 這里為了區(qū)別術(shù)語就直接使用key、value只洒。
注意即使a會被正常的計算為7 许帐, 我們傳遞到deed_dict 中的字典會將值替換成15。 feed_dict 在很多環(huán)境下極其的有用毕谴。由于tensor的值是是之前提供的成畦,這個圖不需要計算任何tensor的正常依賴。這就意味著如果你有一個巨大的圖并且想要用假數(shù)據(jù)(虛擬值dummy value)測試圖的一部分涝开,tensorflow不會把時間浪費在不必要的計算中循帐。 feed_dict 在指定輸入值得時候也是很用的,我們會在將在即將到來的占位符部分中介紹忠寻。
當你使用完了session, 應(yīng)該調(diào)用它的close() 方法去釋放資源:
```python
#? 開啟會話
sess = tf.Session()
#? 運行圖惧浴、 寫統(tǒng)計摘要等等
.....
# 關(guān)閉圖
sess = close()
```
我們也可以使用as_default() 方法把 Session 當做上下文管理器(Context Manager)來使用存和。類似通過某種操作可以隱式的使用Graph 對象奕剃。你可以將某個會話設(shè)置為由某些函數(shù)自動使用。最常見的函數(shù)是 Operation.run() 和 Tensor.eval()? 捐腿, 這些動作可以看做是你已經(jīng)把他們傳遞給了Session.run()了纵朋。
```python
# 定義一個普通的變量
a = tf. constant( 5)
# 開啟一個會話
sess = tf. Session( )
#? 使用with代碼塊, 將Session 作為內(nèi)部默認的會話
with sess. as_default( ) :
a. eval( ) # 自動關(guān)閉
# 不得不手動的關(guān)閉
sess. close( )
MORE on INTERACTIVESESSION
在這本書的前面我們提到過InteractiveSession(互動會話)? 是TensorFlow? session 的另一種類型茄袖,但是我們不會用到它操软。所有的InteractiveSession 又會在運行的時候都會自動地將自己設(shè)置為默認session。當使用交互式的Python Shell 的時候卻很方便宪祥,因為你可以使用a.eval() 或者a.run() 而不必顯式的輸出sess.run([a])聂薪。不過家乘,如果你要拼湊多個session的話,這會有一點棘手藏澳。維護一致的圖形使得調(diào)試更加容易仁锯,所以我們堅持使用常規(guī)的Session對象。
現(xiàn)在我們已經(jīng)對運行圖形有了很好的理解翔悠,讓我們看看如何正確地指定輸入節(jié)點并結(jié)合使用feed_dict业崖。
==簡書翻譯到此