讓我們看一下以下代碼。
...
c = tf.add(a, b)
乍一看,這就像NumPy一樣,你想添加兩個張量a和b。因此,你編寫了tf.add(a, b)來返回張量c。但是,跟典型的Python代碼不同,運行tf.add不會執行它,只會構建DAG。
在有向無環圖中的DAG中,a, b和c是張量,而add是一個運算。為了執行這代碼,為了跑DAG,你需要把他作為對談(session)的一部分來運行。
...
c = tf.add(a, b)
session = tf.Session()
numpy_c = session.run(c, feed_dict= ...)
因此,你說你想要求一個c值,然後詢問該對談:「嘿,請為我評估c值。」因此,這就是運行DAG的方式,然後您在Python中返回了一個傳統的數字數組,其中包含c的值。
編寫TensorFlow代碼涉及對DAG進行編程。因此,有兩個步驟,創建圖形與運行圖形。圖定義與訓練循環是分開的,因為這是一個惰性評估模型。它最小化了Python到C++的上下文切換,並使計算非常高效。
從概念上講,這就像編寫程序,對其進行編譯,然後對某些數據運行它。但是這裡事實上沒有明確的編譯階段。要注意的是,調用tf.add之後的c不是實際值。你必須在TensorFlow對談的上下文中評估c以獲取NumPy值數組numpy_c。因此,重申一下,TensorFlow會進行惰性評估。編寫DAG,然後在對談上下文中運行DAG以獲取結果。
現在,你可以運行一種不同的模式來運行TensorFlow。它被稱為tf.eager
,在tf.eager
中,評估是立即進行的,而且並不懶惰。但是生產模式中通常不使用急切模式。它通常僅用於開發。我們將在稍後部分討論tf.eager
,但是在大多數情況下,我們將集中在惰性評估範式上。幾乎我們編寫並在生產中運行的所有代碼都將處於惰性評估模式。
在NumPy(這是Python Numeric Software的最大模組()中,a和b是NumPy數組。 NumPy透過在c中實現來提高速度,因此當您調用np.add
時,該添加就可以在c中完成。但是,當CPU運行代碼np.add(a, b)
並且NumPy數組c填充了總和時,它確實完成了。因此,當您打印c時,得到的是8, 2和10。8是5和3, 3和-1的和,等於2,等等。關鍵是np.add
立即被評估。
與NumPy不同,在TensorFlow中c不是實際值。相反,c是張量,您必須在TensorFlow會話的上下文中評估c以獲取NumPy值數組,即結果。因此,當CPU或GPU或任何硬件評估tf.add(a, b)
時,將在DAG中的有向無環圖中創建張量。但是添加本身不會在session.run
被調用之前執行。因此,如果我們調用print(c)
,則在第一個框中顯示出來的是張量類的調試輸出。它包括系統為DAG中的節點分配的唯一名稱,在本例中為add_7以及運行DAG時將顯示的值的形狀和數據類型。在運行會話並在會話上下文中評估c之後,我們可以印出結果,就像得到NumPy一樣,我們將得到8、2和10。因此,有兩個階段,即構建階段和運行階段,但是為什麼呢?為什麼TensorFlow會進行惰性評估?這是下一篇文的內容。