【tensorflow基礎學習】計算圖

 

 

初識計算圖與張量

       Tensorflow程序中的計算過程可以表示爲一個計算圖(computation Graph,也稱一個有向圖(Directed Graph)),其作用與外觀都可以類比程序流程圖來理解,在計算圖上我們可以直觀地看出數據的計算流程。

        計算圖中的每一個運算操作可以視爲一個節點(Node),每一個節點可以有任意個輸入和任意個輸出。

        如果一個運算的輸入取值自另一個運算的輸出,那麼稱這兩個運算存在依賴關係。存在依賴關係的兩個節點之間通過邊(Edge)相互連接。值得注意的是,有一類特殊的邊中不存在數據流動,而是起着依賴控制(control dependencies)的作用。通俗的講,就是讓它的起始節點執行完成後再執行目標節點,以達到進行靈活的條件控制的目的。

        張量(tensor)就是在邊中流動(flow)的數據,其數據類型可以在編程時事先定義,也可以根據計算圖的上下文結構推斷而來。

        Tensorflow之名的得來也是參考了上述所有概念。Tensor翻譯成中文就是“張量”,“張量”這個概念在數學和物理學中都會涉及,在此不會對它的精確定義進行解釋,可以將其簡單又形象地理解爲數組:flow翻譯成中文就是“流“,指的是張量數據沿着邊在不同的節點間流動併發生轉化。

計算圖—tensorflow的計算模型

        在學習程序設計的起步階段,對於晦澀難懂的算法,我們通常會選擇繪製程序流程圖的方式來加強理解。相較於枯燥乏味的代碼,這種圖的直觀性似乎更能勾起我們繼續探索的慾望。在程序流程圖中,可以使用不同的形狀代表不同的操作,比如菱形是判斷,長方形是處理等。此外,還可以使用帶箭頭的線指明程序的執行方向。

       計算圖有着流程圖類似的作用。在計算圖中不同的形狀代表着不同的運算。使用tensorboard工具可視化tensorflow程序的計算圖時,可以在主窗口左側看到計算圖中可能會出現的所有形狀及其解釋。

       通常將tensorflow的計算圖稱爲程序的“計算模型”,這個名稱的得來也正是因爲計算圖有着將計算過程可視化的作用。詳細地介紹計算圖可以從簡單的向量相加的例子開始:

a = tf.constant([1.0, 2.0], name="a")#常量是一種輸出值永遠固定的計算
b = tf.constant([3.0, 4.0], name="b")
result = a + b#常量相加的計算
print(a.graph is tf.get_default_graph())#通過graph屬性可以獲取張量所屬的計算圖
print(b.graph is tf.get_default_graph())

        編寫tensorflow程序時,系統會自動維護一個默認的計算圖(這樣就不需要每次編寫陳程序的時再自行定義計算圖了)。在上面的程序運行過程中,tensorflow會自動將定義的所有計算添加到默認的計算圖。通過函數get_default_graph()可以獲取對當前默認計算圖的引用。所以在上面的代碼中,判斷a和b是否屬於默認的計算圖會輸出True,因爲我們沒有指定a和b屬於哪一個計算圖。

       使用默認的計算圖可以滿足一般情況下的需要,當我們需要更多的計算圖來完成工作的時候,可以通過Graph()函數來生成新的計算圖。對於生成的計算圖,我們可以通過as_default()函數將其指定爲默認的。以下代碼展示了使用Graph()函數來生成兩個計算圖及使用as_default()函數將生成的計算圖指定爲默認:

#使用Graph()函數創建一個計算圖
g1 = tf.Graph()
with g1.as_default():#將定義的計算圖使用as_default()函數設置爲默認
    #創建計算圖中的變量並設置初始值
    a = tf.get_variable("a", [2], initializer=tf.ones_initializer())
    b = tf.get_variable("b", [2], initializer=tf.zeros_initializer())

#使用Graph()函數創建另一個計算圖
g2 = tf.Graph()
with g2.as_default():
    a = tf.get_variable("a", [2], initializer=tf.zeros_initializer())
    b = tf.get_variable("b", [2], initializer=tf.ones_initializer())
with tf.Session(graph=g1) as sess:
    tf.global_variables_initializer().run()#初始化計算圖中的所有變量
    with tf.variable_scope("", reuse=True):
        print(sess.run(tf.get_variable("a")))
        print(sess.run(tf.get_variable("b")))
#輸出
#[1. 1.]
#[0. 0.]
with tf.Session(graph=g2) as sess:
    tf.global_variables_initializer().run()
    with tf.variable_scope("", reuse=True):
        print(sess.run(tf.get_variable("a")))
        print(sess.run(tf.get_variable("b")))
#輸出
#[0. 0.]
#[1. 1.]

        在這個樣例程序中,我們用到了一些沒有學過的知識,比如使用get_variable()函數創建變量、使用with/as運行會話,以及使用variable_scope()函數控制變量空間等,後面介紹。我門重點關注使用Graph()函數生成的兩個計算圖g1和g2。在初始化會話時,可以通過參數graph將創建好的計算圖交由會話執行。

        對於每一個計算圖,tensorflow通過5個默認的“集合(collection)”管理其中不同類別的個體。這裏所謂的個體可以是張量、變量或者運行tensorflow程序所需要的隊列等。下表彙總了這些集合及其管理的內容。

                                                                  Tensorflow維護的默認集合及其內容

名稱

內容

Tf.GraphKeys.VARIABLES

所有變量

Tf.GraphKeys.TRAINABLE_VARIABLES

可學習(訓練)的變量(一般指神經網絡中的參數)

Tf.GraphKeys.SUMMARIES

日誌生成相關的變量

Tf.GraphKeys.QUEUE_RUNNERS

處理輸入的QueueRunner

Tf.GraphKeys.MOVING_AVERVGE_VARIABLES

所有計算了滑動平均值的變量

        函數add_to_collection()可以將個體加入一個或多個集合中,而get_collection()函數用來獲取一個集合中的所有個體,這兩個函數是最常用的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章