1. 程式人生 > >TensorFlow 學習(三) 圖和會話

TensorFlow 學習(三) 圖和會話

    資料流圖是一種常用於平行計算的程式設計模型。大多數TensorFlow程式都是從資料流圖構建階段開始,這些函式可構建新的 tf.Operation(節點)和 tf.Tensor(邊緣)物件並將它們新增到 tf.Graph 例項中。TensorFlow 提供了一個預設圖,此圖是同一上下文中的所有 API 函式的明確引數

tf.graph圖資訊

  • 圖結構。 圖的節點和邊緣,表示各個操作組合在一起的方式,但不規定它們的使用方式。圖結構與彙編程式碼類似:檢查圖結構可以傳達一些有用的資訊,但它不包含原始碼傳達的所有實用上下文資訊。

  • 圖集合。 TensorFlow 提供了一種在 tf.graph

    中儲存 元資料集合 的通用機制。tf.add_to_collection 函式允許您將物件列表與一個鍵關聯(其中 tf.GraphKeys 定義了部分標準鍵),tf.get_collection 允許您查詢與某個鍵關聯的所有物件。TensorFlow 庫的許多部分會使用此資源:例如,當您建立 tf.Variable  時,系統會預設將其新增到表示“全域性變數”和“可訓練變數”的集合中。當您後續建立 tf.train.Saver 或  tf.train.Optimizer 時,這些集合中的變數將用作預設引數。

tf.graph 圖建立

  • 呼叫 可建立單個 tf.Operation,該操作可以生成值 42.0,將該值新增到預設圖中,並返回表示常量值的 tf.Tensor。

  • 呼叫 tf.matmul(x, y) 可建立單個 tf.Operation,該操作會將  tf.Tensor 物件 x 和 y 的值相乘,將其新增到預設圖中,並返回表示乘法運算結果的 tf.Tensor

  • 執行 v = tf.Variable(0) 可向圖新增一個 tf.Operation

    ,該操作可以儲存一個可寫入的張量值,該值在多個 tf.Session.run 呼叫之間保持恆定。tf.Variable 物件會封裝此操作,並可以像張量一樣使用,讀取已儲存的值的當前值。tf.Variable 物件也具有 assign 和 assign_add 等方法,這些方法可建立 tf.Operation 物件,這些物件在執行時將更新已儲存的值。

  • 呼叫 tf.train.Optimizer.minimize 可將操作和張量新增到計算梯度的預設圖中,並返回一個 tf.Operation,該操作在執行時會將這些梯度應用到一組變數上。

在會話中執行圖 tf.Session

  1. 執行圖的結構
  2. 分配資源計算
  3. 掌握資源(變數的資源,佇列,執行緒)

    tf.Session : 會話物件封裝執行操作物件和計算張量物件的環境。Session 也會分配記憶體來儲存當前變數的值

    TensorFlow 使用 tf.Session 類物件可以訪問本地的裝置,也可以訪問使用分散式TensorFlow 執行時的遠端裝置。由於 tf.Session 擁有物理資源(例如 GPU 和網路連線),因此通常(在 with 程式碼塊中)用作上下文管理器,並在您退出程式碼塊時自動關閉會話。您也可以在不使用 with 程式碼塊的情況下建立會話,但應在完成會話時明確呼叫 tf.Session.close 以便釋放資源

     注意:較高階的 API(例如 tf.train.MonitoredTrainingSession 或 tf.estimator.Estimator)將為您建立和管理 tf.Session。這些 API 接受可選的 target 和 config 引數(直接接受,或作為 tf.estimator.RunConfig 物件的一部分)。

使用會話兩種方式程式碼執行例子:

import tensorflow as tf

# 建立張量節點。op操作
a = tf.constant(3, name="a")
b = tf.constant(4, name = "b")
addsum = tf.add(a,b, name = "c")

# 兩種方式執行會話:
# 1. 使用上下文管理器 with
with tf.Session() as sess:
    print("with: {0}".format(sess.run(addsum)))

# 2. 使用 close 方式
sess = tf.Session()
print("run: %d" % (sess.run(addsum)))
sess.close()

#################################
#            執行結果            #
#################################
with: 7
run: 7

構建 tf.Graph 程式碼執行例子

  • tf.Graph 會定義 tf.Operation 物件的名稱空間:單個圖中的每個操作必須具有唯一名稱。如果請求的名稱已被佔用,TensorFlow 將在操作名稱上附加 "_1"、"_2" 等字元,以便確保名稱的唯一性。通過使用多個明確建立的圖,您可以更有效地控制為每個操作指定什麼樣的名稱。
  • 預設圖會儲存與新增的每個 tf.Operation 和 tf.Tensor 有關的資訊。如果您的程式建立了大量未連線的子圖,更有效的做法是使用另一個 tf.Graph 構建每個子圖,以便回收不相關的狀態。
import tensorflow as tf
# 構建圖
gr = tf.Graph()

# 預設的這張圖,相當於是給程式分配一段記憶體
ga = tf.get_default_graph()


with gr.as_default():
    grsum = tf.constant(23)
    
# 只能執行一張圖,可以在會話指定圖,必須是tf.Graph()的建立圖
with tf.Session(graph = gr) as sess:
    print(sess.run(grsum))

#################################
#            執行結果            #
#################################
23

tf.Session初始化三個可選引數:

  • target。如果將此引數留空(預設設定),會話將僅使用本地機器中的裝置。但是,也可以指定 "xxxx:// 網址,以便指定 TensorFlow 伺服器的地址,這使得會話可以訪問該伺服器控制的機器上的所有裝置。如何建立TensorFlow伺服器,可以參閱官網的 tf.train.Server 的API。
  • graph。預設情況下,新的 tf.Session 將繫結到當前的預設圖,並且僅能夠在當前的預設圖中執行操作。如果在程式中使用了多個圖,則可以在構建會話時指定明確的 tf.Graph。
  • config。可以指定一個控制會話行為的 tf.ConfigProto。部分配置選項包括:
    •  allow_soft_placement。將此引數設定為 True 可啟用“軟”裝置放置演算法,該演算法會忽略嘗試將僅限 CPU 的操作分配到 GPU 裝置上的 tf.device 註解,並將這些操作放置到 CPU 上。
    •  cluster_def。使用分散式 TensorFlow 時,此選項允許您指定要在計算中使用的機器,並提供作業名稱、任務索引和網路地址之間的對映。詳情請參閱 tf.train.ClusterSpec.as_cluster_def。
    • graph_options.optimizer_options。在執行圖之前使您能夠控制 TensorFlow 對圖實施的優化。
    • gpu_options.allow_growth。將此引數設定為 True 可更改 GPU 記憶體分配器,使該分配器逐漸增加分配的記憶體量,而不是在啟動時分配掉大多數記憶體。
    • log_device_placement 。 是否記錄裝置位置   
import tensorflow as tf

# 語法 placeholder 提供佔位符,run 時候通過 feed_dict 指定引數 一個字典
# 巢狀列表,元組、過載的運算子也能執行。
plt = tf.placeholder(tf.float32, [None, 3])

# feed_dict 允許呼叫者覆蓋圖中指定張量的值,提供給 placeholder 使用
# log_device_placement=True:記錄裝置位置
with tf.Session(config = tf.ConfigProto(log_device_placement=True)) as sess:
    print(sess.run(plt, feed_dict = {plt: [[1,2,3], [4,5,6], [2, 3, 4]]}))

#################################
#            執行結果            #
#################################
[[1. 2. 3.]
 [4. 5. 6.]
 [2. 3. 4.]]

執行結果返回值異常:

  • RuntimeError: 如果它 Session 處於無效狀態(例如已關閉)。
  • TypeError: 如果 fetches 或 feed_dict 鍵是不合適的型別。
  • ValueError: 如果 fetches 或 feed_dict 鍵無效或引用 Tensor 不存在。

簡單描述TensorBoard 視覺化展示圖

    圖視覺化工具是 TensorBoard 的一個元件,可在瀏覽器中視覺化圖的結構。要建立視覺化圖表,最簡單的方法是傳遞 tf.Graph(在建立 tf.summary.FileWriter 時)

# 定義一個計算圖,實現兩個向量的加法操作
# 定義兩個輸入,a為常量,b為變數
a = tf.constant([1.0, 2.0, 6.0], name='a')
b = tf.Variable(tf.random_uniform([3]), name='b')

addsum = tf.add_n([a,b], name='add')

# 生成一個具有寫許可權的日誌檔案操作物件,將當前名稱空間的計算圖寫進日誌中
#  ./log 是你要儲存的路徑,當前路徑下的log
# 到當前的路徑下。命令列終端執行: tensorboard --logdir=log/
writer=tf.summary.FileWriter('./log', tf.get_default_graph())

# 關閉
writer.close()

  注:tensorboard --logdir=log/ 這條命令必須在tensorflow 環境的當前路徑下執行

比如說我的連結地址訪問 http://DESKTOP-L04Q0FC:6006

所看到的視覺化圖

tensorboad 啟動過程:

  1. 建立,寫入日誌檔案到本地

    writer=tf.summary.FileWriter('./log', tf.get_default_graph())

  2. 關閉和儲存日誌檔案
    writer.close()

  3. 執行視覺化命令,啟動服務
    tensorboard –logdir=log/

  4. 開啟視覺化介面
    通過瀏覽器開啟伺服器訪問埠http://xxx.xxx.xxx.xxx:xxxx