TensorFlow極簡入門教程

2021-03-02 人人都是極客

隨著 TensorFlow 在研究及產品中的應用日益廣泛,很多開發者及研究者都希望能深入學習這一深度學習框架。本文介紹了TensorFlow 基礎,包括靜態計算圖、張量、TensorBoard 可視化和模型參數的保存等。

TensorFlow 基礎

TensorFlow 是一種採用數據流圖(data flow graphs),用於數值計算的開源軟體庫。其中 Tensor 代表傳遞的數據為張量(多維數組),Flow 代表使用計算圖進行運算。數據流圖用「節點」(nodes)和「邊」(edges)組成的有向圖來描述數學運算。「節點」一般用來表示施加的數學操作,但也可以表示數據輸入的起點和輸出的終點,或者是讀取/寫入持久變量(persistent variable)的終點。邊表示節點之間的輸入/輸出關係。這些數據邊可以傳送維度可動態調整的多維數據數組,即張量(tensor)。

計算圖與會話

學習 TensorFlow 的第一步是了解它的主要特色——「計算圖」方法。基本上所有的TensorFlow 代碼都包含兩個重要部分:

1. 創建「計算圖」,表示計算的數據流

2. 運行「會話」,執行圖中的運算

事實上,TensorFlow 將計算的定義與其執行分開。這兩個部分將在以下各節中詳細說明。在此之前,請記住第一步是導入 TensorFlow !

import tensorflow as tf

這樣,Python 就可以訪問 TensorFlow 的所有類、方法和符號。使用此命令,TensorFlow 庫將在別名「tf」下導入,以便以後我們可以使用它而不必每次鍵入其全稱「TensorFlow」。

1. 計算圖

TensorFlow 的創意中的最大創意是數值計算被表達成計算圖。換種說法,任何 TensorFlow 程序的骨幹都是一個計算圖。正如 TensorFlow 官網上提及的,「一個計算圖是被組織到圖節點上的一系列 TensorFlow 運算」。

首先,什麼是節點和運算?最好的解釋方式是,舉個例子。假設我們為函數「f(x,y)=x^2y+y+2」編寫代碼。TensorFlow 中的計算圖如下所示:

圖 2:TensorFlow 構建的計算圖。

如上圖所示,計算圖有一系列由邊互相連接的節點構成。每個節點稱為 op,即 operation(運算)的縮寫。因此每個節點代表一個運算,可能是張量運算或生成張量的操作。每個節點以零或更多張量為輸入,並生成一個張量作為輸出。

現在我們來構建一個簡單的計算圖。

import tensorflow as tf
a = 2
b = 3
c = tf.add(a, b, name='Add')
print(c)
______________________________________________________
Tensor("Add:0", shape=(), dtype=int32)

生成的計算圖和變量為:

圖 3:左:生成的圖在 Tensorboard 中可視化;右:生成的變量(在 debug 模式下運行時從 PyCharm 調試器獲取的屏幕截圖)

為了實際評估節點,必須在會話內運行計算圖。簡言之,編寫的代碼只生成僅僅用來確定張量的預期大小以及對它們執行的運算的圖。但是,它不會為任何張量賦值。

因此,TensorFlow Graph 類似於 Python 中的函數定義。它「不會」為你執行任何計算(就像函數定義不會有任何執行結果一樣)。它「僅」定義計算操作。

2. 會話(Session)

在 TensorFlow 中,所有不同的變量和運算都是儲存在計算圖。所以在我們構建完模型所需要的圖之後,還需要打開一個會話(Session)來運行整個計算圖。在會話中,我們可以將所有計算分配到可用的 CPU 和 GPU 資源中。舉個簡單的例子,運行計算圖並獲取 c 的值:

sess = tf.Session()
print(sess.run(c))
sess.close()
__________________________________________
5

這些代碼創建了一個 Session() 對象(分配到 sess),然後(第二行)調用它的運行方法來運行足夠的計算圖以評估 c。計算完畢後需要關閉會話來幫助系統回收資源,不然就會出現資源洩漏的問題。

TensorFlow 張量

import tensorflow as tf

TensorFlow 中最基本的單位是常量(Constant)、變量(Variable)和佔位符(Placeholder)。常量定義後值和維度不可變,變量定義後值可變而維度不可變。在神經網絡中,變量一般可作為儲存權重和其他信息的矩陣,而常量可作為儲存超參數或其他結構信息的變量。

1. 常量

創建一個節點取常數值,它接收以下的變量:

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

我們來創建兩個常量並將它們加起來。常量張量可以通過定義一個值來簡單地定義:

# create graph
a = tf.constant(2)
b = tf.constant(3)
c = a + b
# launch the graph in a session
with tf.Session() as sess:
   print(sess.run(c))
____________________________________________________
5    

現在我們來看看創建的計算圖和生成的數據類型:

2. 變量

變量是狀態性的節點,輸出的是它們當前的值,意味著它們可以在一個計算圖的多次執行中保留它們的值。它們有一系列的有用特徵,例如:

它們可以在訓練期間或訓練後保存到硬碟上。這允許來自不同公司和團隊的人們保存、恢復和發送他們的模型參數給別人。

默認情況下,梯度更新(在所有神經網絡中應用)將應用到計算圖中的所有變量。實際上,變量是你希望調整以最小化損失函數的東西。

為了創建變量,你可以按如下方式使用 tf.Variable:

# Create a variable.
w = tf.Variable(<initial-value>, name=<optional-name>)

以下語句聲明一個 2 行 3 列的變量矩陣,該變量的值服從標準差為 1 的正態分布,並隨機生成。

w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))

TensorFlow 還有 tf.truncated_normal() 函數,即截斷正態分布隨機數,它只保留 [mean-2*stddev,mean+2*stddev] 範圍內的隨機數。

調用 tf.Variable 來創建一個變量是一種老方法。TensorFlow 推薦使用封裝器 tf.get_variable,它能接收命名、形狀等參數:

tf.get_variable(name,
               shape=None,
               dtype=None,
               initializer=None,
               regularizer=None,
               trainable=True,
               collections=None,
               caching_device=None,
               partitioner=None,
               validate_shape=True,
               use_resource=None,
               custom_getter=None,
               constraint=None)

變量在使用前需要初始化。為此,我們必須調用「變量初始值設定項操作」,並在 session 上運行該操作。

a = tf.get_variable(name="var_1", initializer=tf.constant(2))
b = tf.get_variable(name="var_2", initializer=tf.constant(3))
c = tf.add(a, b, name="Add1")

# launch the graph in a session
with tf.Session() as sess:
   # now let's evaluate their value
   print(sess.run(a))
   print(sess.run(b))
   print(sess.run(c))

3. 佔位符

我們已經創建了各種形式的常量和變量,但 TensorFlow 同樣還支持佔位符。佔位符並沒有初始值,它只會分配必要的內存。在會話中,佔位符可以使用 feed_dict 饋送數據。

feed_dict 是一個字典,在字典中需要給出每一個用到的佔位符的取值。在訓練神經網絡時需要每次提供一個批量的訓練樣本,如果每次迭代選取的數據要通過常量表示,那麼 TensorFlow 的計算圖會非常大。因為每增加一個常量,TensorFlow 都會在計算圖中增加一個節點。所以說擁有幾百萬次迭代的神經網絡會擁有極其龐大的計算圖,而佔位符卻可以解決這一點,它只會擁有佔位符這一個節點。

a = tf.constant([5, 5, 5], tf.float32, name='A')
b = tf.placeholder(tf.float32, shape=[3], name='B')
c = tf.add(a, b, name="Add")

with tf.Session() as sess:
   # create a dictionary:
   d = {b: [1, 2, 3]}
   # feed it to the placeholder
   print(sess.run(c, feed_dict=d))
___________________________________________________
[6. 7. 8.]

它生成的計算圖與變量如下所示:

現在,我們已經能創建一個簡單的神經網絡。如下利用隨機生成的數據創建了一個三層全連接網絡:

import tensorflow as tf
from numpy.random import RandomState

batch_size=10
w1=tf.Variable(tf.random_normal([2,3],stddev=1,seed=1))
w2=tf.Variable(tf.random_normal([3,1],stddev=1,seed=1))

# None 可以根據batch 大小確定維度,在shape的一個維度上使用None
x=tf.placeholder(tf.float32,shape=(None,2))
y=tf.placeholder(tf.float32,shape=(None,1))

#激活函數使用ReLU
a=tf.nn.relu(tf.matmul(x,w1))
yhat=tf.nn.relu(tf.matmul(a,w2))

#定義交叉熵為損失函數,訓練過程使用Adam算法最小化交叉熵
cross_entropy=-tf.reduce_mean(y*tf.log(tf.clip_by_value(yhat,1e-10,1.0)))
train_step=tf.train.AdamOptimizer(0.001).minimize(cross_entropy)

rdm=RandomState(1)
data_size=516

#生成兩個特徵,共data_size個樣本
X=rdm.rand(data_size,2)
#定義規則給出樣本標籤,所有x1+x2<1的樣本認為是正樣本,其他為負樣本。Y,1為正樣本
Y = [[int(x1+x2 < 1)] for (x1, x2) in X]

with tf.Session() as sess:
   sess.run(tf.global_variables_initializer())
   print(sess.run(w1))
   print(sess.run(w2))
   steps=11000
   for i in range(steps):

       #選定每一個批量讀取的首尾位置,確保在1個epoch內採樣訓練
       start = i * batch_size % data_size
       end = min(start + batch_size,data_size)
       sess.run(train_step,feed_dict={x:X[start:end],y:Y[start:end]})
       if i % 1000 == 0:
           training_loss= sess.run(cross_entropy,feed_dict={x:X,y:Y})
           print("在迭代 %d 次後,訓練損失為 %g"%(i,training_loss))

上面的代碼定義了一個簡單的三層全連接網絡(輸入層、隱藏層和輸出層分別為 2、3 和 2 個神經元),隱藏層和輸出層的激活函數使用的是 ReLU 函數。該模型訓練的樣本總數為 512,每次迭代讀取的批量為 10。這個簡單的全連接網絡以交叉熵為損失函數,並使用 Adam 優化算法進行權重更新。

其中需要注意的幾個函數如 tf.nn.relu() 代表調用 ReLU 激活函數,tf.matmul() 為矩陣乘法等。tf.clip_by_value(yhat,1e-10,1.0) 這一語句代表的是截斷 yhat 的值,因為這一語句是嵌套在 tf.log() 函數內的,所以我們需要確保 yhat 的取值不會導致對數無窮大。

TensorBoard 基礎

TensorBoard 是一個可視化軟體,在所有的 TensorFlow 標準安裝中都包含了 TensorBoard。按谷歌的話說:「使用 TensorFlow 執行的計算,例如訓練一個大規模深度神經網絡,可能複雜且令人困惑。為了更加容易理解、調試和優化 TensorFlow 程序,我們內置了一套可視化工具,即 TensorBoard。」

TensorFlow 程序既能解決非常簡單也能解決非常複雜的問題,它們都有兩種基本組件——運算和張量。如前所述,你創建了一個由一系列運算構成的模型,饋送數據到模型上,張量將在運算之間流動,直到得到了輸出張量,即你的結果。

完全配置好後,TensorBoard 窗口將呈現與下圖類似的畫面:

TensorBoard 的創建是為了幫助你了解模型中張量的流動,以便調試和優化模型。它通常用於兩項任務:

1. 圖形可視化

2. 編寫摘要(或可視化學習)

在本教程中,我們將介紹 TensorBoard 的上述兩項主要用法。儘早學習使用 TensorBoard,可以讓使用 TensorFlow 的工作更有趣也更有成效。

1. 計算圖可視化

強大的 TensorFlow 計算圖會變得極其複雜。可視化圖形有助於理解並對其進行調試。這是一個在 TensorFlow 網站工作的可視化示例。

為了激活 TensorFlow 程序 TensorBoard,需要向其中添加幾行代碼。這將把 TensorFlow 運算導出到一個名為「event file」(或 event log file)的文件中。TensorBoard 能夠讀取此文件並深入了解模型圖及其性能。

現在我們來編寫一個簡單的 TensorFlow 程序,並用 TensorBoard 可視化其計算圖。先創建兩個常量並將其添加到一起。常數張量可以簡單地通過定義它們的值來定義:

import tensorflow as tf

# create graph
a = tf.constant(2)
b = tf.constant(3)
c = tf.add(a, b)
# launch the graph in a session
with tf.Session() as sess:
   print(sess.run(c))
_____________________________________________
5

為了用 TensorBoard 可視化程序,我們需要編寫程序的日誌文件。為了編寫事件文件,我們首先需要為那些日誌編寫一個 writer,使用以下代碼:

writer = tf.summary.FileWriter([logdir], [graph])

其中 [logdir] 是你想要保存那些日誌文件的文件夾。你可以選擇 [logdir] 作為某些有意義的東西,例如『./graphs』。第二個參數 [graph] 是我們正在編寫的程序的計算圖。有兩種獲取計算圖的方法:

1. 使用 tf.get_default_graph() 調用計算圖,返回程序的默認計算圖

2. 將計算圖設置為 sess.graph,返回會話的計算圖(注意這裡需要我們已經創建了會話)

我們將在以下的例子中展示兩種方法。然而,第二種方法更加常用。不管用哪種方法,確保僅當你定義了計算圖之後才創建一個 writer。否則,TensorBoard 中可視化的計算圖將是不完整的。讓我們添加 writer 到第一個例子中並可視化計算圖。

import tensorflow as tf

# create graph
a = tf.constant(2)
b = tf.constant(3)
c = tf.add(a, b)

# creating the writer out of the session
# writer = tf.summary.FileWriter('./graphs', tf.get_default_graph())

# launch the graph in a session
with tf.Session() as sess:
   # or creating the writer inside the session
   writer = tf.summary.FileWriter('./graphs', sess.graph)
   print(sess.run(c))
   # don't forget to close the writer at the end
   writer.close()

接下來轉到 Terminal,確保當前工作目錄與運行 Python 代碼的位置相同。例如,此處我們可以使用以下代碼切換到目錄

$ cd ~/Desktop/tensorboard

接下來運行:

$ tensorboard --logdir="./graphs" —port 6006

這將為你生成一個連結。ctrl+左鍵單擊該連結(或將其複製到瀏覽器中,或只需打開瀏覽器並轉到 http://localhost:6006/)。接下來將顯示 TensorBoard 頁面,如下所示:

參數存儲與加載

在基礎部分中,最後還介紹了模型參數的保存與恢復。一般 TensorFlow 模型持久化可使用 tf.train.Saver() 完成,它會將 TensorFlow 模型保存為 .ckpt 格式的文件。一般該文件目錄下會有三個文件,第一個 model.ckpt.meta 保存了 TensorFlow 計算圖的結構,第二個 model.ckpt 文件保存了 TensorFlow 中每一個變量的取值,而最後一個 cheekpoint 文件保存了同目錄下所有的模型文件列表。

為了保存和恢復模型變量,我們需要在構建計算圖後調用 tf.train.Saver(),例如:

# create the graph
X = tf.placeholder(..)
Y = tf.placeholder(..)
w = tf.get_variale(..)
b = tf.get_variale(..)
...
loss = tf.losses.mean_squared_error(..)
optimizer = tf.train.AdamOptimizer(..).minimize(loss)
...

saver = tf.tfain.Saver()

在訓練模式中,我們需要打開會話初始化變量和運行計算圖,並在訓練結束時調用 saver.save() 保存變量:

# TRAIN
with tf.Session() as sess:
   sess.run(tf.globale_variables_initializer())
   # train our model
   for step in range(steps):
       sess.run(optimizer)
       ...
   saved_path = saver.save(sess, './my-model', global_step=step)

在測試模式中,我們需要使用 saver.restore() 恢復參數:

# TEST
with tf.Session() as sess:
   saver.restore(sess, './my-model')
   ...

當然,模型持久化還有非常多的內容,例如由 MetaGraphDef Protocol Buffer 定義的計算圖節點元數據。讀者可繼續閱讀完整的教程或其它書籍以了解詳細信息。

輕輕一掃  歡迎關注~

相關焦點

  • Tensorflow 全網最全學習資料匯總之Tensorflow 的入門與安裝【2】
    《TensorFlow學習筆記1:入門》連結:http://www.jeyzhang.com/tensorflow-learning-notes.html本文與上一篇的行文思路基本一致,首先概括了TensorFlow的特性,然後介紹了graph、session、variable 等基本概念的含義,以具體代碼的形式針對每個概念給出了進一步的解釋
  • 從框架優缺點說起,這是一份TensorFlow入門極簡教程
    本文介紹了學習 TensorFlow 的系列教程,旨在通過簡單的理論與實踐幫助初學者一步步掌握 TensorFlow 的編程技巧。這一系列教程分為 6 部分,從為什麼選擇 TensorFlow 到卷積神經網絡的實現,介紹了初學者所需要的技能。
  • TensorFlow極速入門
    一、前言目前,深度學習已經廣泛應用於各個領域,比如圖像識別,圖形定位與檢測,語音識別,機器翻譯等等,對於這個神奇的領域,很多童鞋想要一探究竟,這裡拋磚引玉的簡單介紹下最火的深度學習開源框架 tensorflow。
  • tensorflow極速入門
    一、前言目前,深度學習已經廣泛應用於各個領域,比如圖像識別,圖形定位與檢測,語音識別,機器翻譯等等,對於這個神奇的領域,很多童鞋想要一探究竟,這裡拋磚引玉的簡單介紹下最火的深度學習開源框架 tensorflow。本教程不是 cookbook,所以不會將所有的東西都事無巨細的講到,所有的示例都將使用 python。那麼本篇教程會講到什麼?
  • tensorflow安裝教程
    tensorflow是谷歌開源的人工智慧庫,有最完善的生態支持。是進行人工智慧領域開發和科研的必備工具。本文在windows10下,藉助anacondaAnaconda安裝和使用,AkShare入門,安裝tensorflow2.0。
  • 淺顯易懂的分布式TensorFlow入門教程
    本文是一篇淺顯易懂的分布式TensorFlow入門教程,可以讓你對分布式TensorFlow的原理和使用有一定的了解。1.https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/python/training/monitored_session.py作者 | Tutorials by Malo Marrec 編譯 | 專知整理 | HujunHow
  • Anaconda軟體安裝TensorFlow教程
    Anaconda軟體的安裝,請閱讀文章《Anaconda軟體安裝和簡易使用教程》第一步:創建r-tensorflow環境打開Anaconda Prompt,執行命令conda create --name r-tensorflow python=3.6該命令用來創建r-tensorflow虛擬環境
  • TensorFlow 1.9 新增 tf.keras 官方入門教程(Keras與TF的深度集成)
    好消息是Keras的許多核心功能已經融入了原生的TensorFlow(tf.keras),TensorFlow 1.9新增tf.keras官方入門文檔,介紹了tf.keras的使用。這幾天打開TensorFlow的官方教程頁(https://www.tensorflow.org/tutorials/),會發現教程頁中給出的DEMO變成了基於tf.keras的教程。
  • TensorFlow圖像分類教程
    訓練和分類本教程將訓練一個用於識別不同類型花朵的圖像分類器。深度學習需要大量的訓練數據,因此,我們需要大量已分類的花朵圖像。在很多TensorFlow教程中最先且唯一依賴的就是Docker(應該表明這是個合理的開始)。我也更喜歡這種安裝TensorFlow的方法,因為不需要安裝一系列的依賴項,這可以保持主機(筆記本或桌面)比較乾淨。
  • TensorFlow 中文資源全集,學習路徑推薦
    安裝教程,安裝之後跑起來。入門教程,簡單的模型學習和運行。實戰項目,根據自己的需求進行開發。/GitHub:https://github.com/tensorflow安裝教程中文安裝教程Mac安裝:http://www.cnblogs.com/tensorflownews/p/7298646.htmlubuntu 16.04 安裝 tensorflow-gpu:http://www.tensorflownews.com/2017/09/02/tensorflow-gpu-install-ubuntu
  • TensorFlow 實現流行的機器學習算法的教程匯集
    這是使用 TensorFlow 實現流行的機器學習算法的教程匯集。本匯集的目標是讓讀者可以輕鬆通過案例深入 TensorFlow。這些案例適合那些想要清晰簡明的 TensorFlow 實現案例的初學者。本教程還包含了筆記和帶有註解的代碼。
  • 【官方教程】TensorFlow在圖像識別中的應用
    這篇教程將會教你如何使用Inception-v3。你將學會如何用Python或者C++把圖像分為1000個類別。我們也會討論如何從模型中提取高層次的特徵,在今後其它視覺任務中可能會用到。Python API的使用方法第一次運行classify_image.py腳本時,它會從tensorflow.org官網上下載訓練好的模型。你需要在磁碟上預留約200M的空間。
  • 英文教程太難啃?這裡有一份TensorFlow2.0中文教程
    今年 3 月份,谷歌在 Tensorflow Developer Summit 2019 大會上發布 TensorFlow 2.0 Alpha 版。作為當前最為流行的深度學習框架,2.0 Alpha 版的正式發布引人關注。近兩個月,網上已經出現了大量 TensorFlow 2.0 英文教程。在此文章中,機器之心為大家推薦一個持續更新的中文教程,以便大家學習。
  • 【TensorFlow超級指南】你能想到的TF教程和資源都在這裡了
    本文涵蓋與TensorFlow相關的教程、書籍、工具、求職等的大量信息。盡數資源,應有盡有。Jacob Buckman—《TensorFlow:令人困惑的部分(1)》:https://jacobbuckman.com/post/tensorflow-the-confusing-parts-1/
  • Tensorflow官方語音識別入門教程 | 附Google新語音指令數據集
    語音識別教程Google還配合這個數據集,推出了一份TensorFlow教程,教你訓練一個簡單的語音識別網絡,能識別10個詞,就像是語音識別領域的MNIST(手寫數字識別數據集)。雖然這份教程和數據集都比真實場景簡化了太多,但能幫用戶建立起對語音識別技術的基本理解,很適合初學者使用。
  • 可能是史上最全的Tensorflow學習資源匯總
    一 、Tensorflow教程資源:1)適合初學者的Tensorflow教程和代碼示例:https://github.com/aymericdamien/TensorFlow-Examples該教程不光提供了一些經典的數據集,更是從實現最簡單的「Hello World」開始,到機器學習的經典算法,再到神經網絡的常用模型
  • 《30天吃掉那隻 TensorFlow2.0 》全新TF2.0教程收穫1000 Star
    pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -U tensorflowimport tensorflow as tf#註:本書全部代碼在tensorflow 2.1版本測試通過tf.print
  • TensorFlow Eager圖文教程(附9張圖解和Jupyter)
    本文推薦一個Github上的關於TensorFlow Eager的較為完整的圖文教程(附Jupyter Notebook)。教程連結教程被託管在Github中,作者為Madalina Buzau,連結:https://github.com/madalinabuzau/tensorflow-eager-tutorials01.
  • Tensorflow教程-雙向的LSTM文本分類
    原始碼:https://github.com/PrivateThink/tensorflow_tutorial/blob/master/15.py在Tensorflow今天的教程就是利用雙向的LSTM進行文本分類,單向的LSTM的文本分類可以參考Tensorflow教程-循環神經網絡文本分類。
  • TF - GAN入門:TensorFlow 2.0 的輕量級 GAN 庫
    具影響力的論文:https://github.com/tensorflow/gan#who-uses-tf-gan今天,各個推出 TF-GAN 的新版本。此版本擁有諸多升級和新功能:Cloud TPU 支持:您現在可以使用 TF-GAN 在 Google 的 Cloud TPU 上訓練 GAN。