- 從機器學習到無人駕駛
- 宋哲賢
- 3813字
- 2020-11-23 15:03:24
2.5 TensorFlow核心API
TensorFlow中的API主要是圍繞利用TensorFlow框架進行機器學習這一核心目標構建的,包括模型構建、學習過程控制、數據輸入輸出、數據預處理等功能,本節的主要目的是進一步展示以Keras為主的TensorFlow高階API的主要功能和能力,另一方面也會介紹TensorFlow低階API中的張量等核心概念。講解低階API主要基于兩點考慮:一方面高階API將一些參數和過程封裝于框架本身,利用標準或者平均最優進行了固定,這樣做雖然能夠滿足基本的業務需要,但是在實際業務場景中有可能多有掣肘;另一方面,前面介紹過Keras是自1.4版本才正式內置于TensorFlow中的,很多早期資料并沒有使用Keras API,而是使用了TensorFlow的低階API,因此掌握低階API也是非常重要的。同時,本書會在后續例子中使用低階API,甚至使用NumPy API完成一些例子,以使讀者能夠全面掌握Python機器學習開發技術。
2.5.1 TensorFlow低級API
1. 張量
張量(Tensor)是TensorFlow中的核心數據表示方案,任何模型的構建起點都會構建模型的輸入輸出張量。一個張量由一組形成陣列(任意維數)的原始值組成。張量的階是它的維數,而它的形式是一個整數元組,指定了陣列每個維度的長度。比如[[[1., 2., 3.]], [[7., 8., 9.]]]是一個3階張量,張量的形式可以用[2, 1, 3]數組來表示。
2. 圖和會話
利用TensorFlow低階API進行機器學習實踐可以分為兩部分:第一部分是機器學習模型的設計,這一部分使用的技術就是圖(Graph),又稱計算圖;第二部分是運行設計模型,得到模型的最優解,這一部分使用的技術是會話(Session)。打個比方,比如我們要確定一條直線,第一步是寫出直線方程:Y=kX+b,第二步是利用(X,Y)數據集求出k、b的值。TensorFlow框架中的這種設計保持了和機器學習數學過程的一致性,使開發者更加容易理解并實踐。
仔細分析計算圖,我們可以認為計算圖是排列成一個圖的一系列TensorFlow指令。計算圖中含有兩種類型的對象:一種是操作(Operator),表示圖的節點,描述了消耗和生成張量的計算;第二種是張量(Tensor),表示圖的邊緣節點,代表將流經圖的值。簡單來說,操作是過程中的節點,張量是輸入輸出節點。
要評估張量,需要實例化一個tf.Session對象(非正式名稱為會話)。會話會封裝TensorFlow運行時的狀態,并運行TensorFlow操作。如果說tf.Graph像一個.py文件,那么tf.Session就像一個Python可執行對象。
3. 層
構建模型的時候要決定算法的運行方法,在TensorFlow模型構建的過程中,你會有一種直觀感受,這個過程非常像我們小時候堆疊積木,堆疊的原材料在TensorFlow中稱為層(Layer),不同層的串聯結構是當前機器學習中最常用的,同時也是最有效的架構方式,我們將在高階API中使用適當的方式來描述這個過程,也就是在Hello TensorFlow示例中使用的Sequential。層將變量和作用于它們的操作打包在一起,例如,密集連接層會對每個輸出對應的所有輸入執行加權和,并應用激活函數(可選)。連接權重和偏差由層對象管理。在一個完整的機器學習層模型的設計使用全流程中,一般會包含層創建、層初始化和層執行3個核心階段。
(1)創建層
下面的代碼會創建一個Dense層,該層會接收一批輸入矢量,并為每個矢量生成一個輸出值。要將層應用于輸入值,請將該層當作函數來調用,例如:
x = tf.placeholder(tf.float32, shape=[None, 3]) linear_model = tf.layers.Dense(units=1) y = linear_model(x)
層會檢查輸入數據,以確定其內部變量的大小。因此,我們必須在這里設置x占位符的形式,以便層構建正確大小的權重矩陣。
我們現在已經定義了輸出值y的計算,在運行計算之前,還需要處理一個細節,即初始化層。
(2)初始化層
層包含的變量必須先初始化,然后才能使用。盡管可以單獨初始化各個變量,但也可以輕松地初始化一個TensorFlow圖中的所有變量:
init = tf.global_variables_initializer() sess.run(init)
調用tf.global_variables_initializer僅會創建并返回TensorFlow操作的句柄。當我們使用tf.Session.run運行該操作時,該操作將初始化所有全局變量。需要特別注意的一點是,global_variables_initializer僅會初始化創建初始化程序時圖中就存在的變量。因此,應該在構建圖表的最后一步添加初始化程序。
(3)執行層
我們現在已經完成了層的初始化,可以像處理任何其他張量一樣評估linear_model的輸出張量。例如下面的代碼:
print(sess.run(y, {x: [[1, 2, 3],[4, 5, 6]]}))
會生成一個兩個元素的輸出向量:
[[-3.41378999] [-9.14999008]]
4. 可視化學習過程
雖然機器學習的TensorFlow的Python代碼看上去相當不錯,但是我們依然有讓過程和數據更加直觀的沖動,因為大腦對于形象理解本身就是過分溺愛的,更別說有了可視化過程,我們可以在很短的時間內把自己的想法解釋清楚。當然,谷歌也是深諳此道,因此很早版本的TensorFlow就內置了一個學習過程可視化的框架TensorBoard。
首先將計算圖保存為TensorBoard摘要文件,具體操作如下:
writer = tf.summary.FileWriter('.') writer.add_graph(tf.get_default_graph())
這將在當前目錄中生成一個events文件,名稱格式如下:
events.out.tfevents.{timestamp}.{hostname}
現在,在新的終端中使用以下Shell命令啟動TensorBoard:
tensorboard --logdir .
接下來,在瀏覽器中打開TensorBoard的圖頁面,應該會看到與圖2.18類似的圖。

圖2.18 TensorBoard張量相加的計算圖
此外,我們還能夠通過TensorBoard將記錄的運算中間數據可視化,通過圖表的形式更加容易地對數據趨勢做出準確判斷。具體事例會在下面的綜合實例中進行展示。
5. 低級API綜合實例
import tensorflow as tf a = tf.constant(3.1, name='a') x = tf.placeholder(tf.float32, name='x') w = tf.Variable(2.0, name='w') result = tf.add(a, w*x) tf.summary.scalar('result', result) sess = tf.Session() merged = tf.summary.merge_all() init = tf.global_variables_initializer() graph = sess.graph writer = tf.summary.FileWriter('./log', graph) sess.run(init) for i in range(100): summary_, result_ = sess.run([merged, result], feed_dict={x:float(i)}) writer.add_summary(summary_, i) sess.close()
這個例子中首先構建了一個ax+b的表達式,然后通過TensorFlow會話進行了計算,實例中通過TensorFlow的summary模塊進行可視化跟蹤。程序運行完成后,會在當前目錄建立一個名稱為log的文件夾,在該文件夾下會存儲本次運算的日志文件,日志文件名稱包含運行時間戳和運行機器名稱。通過tensorboard –logdir命令在命令行中啟動TensorBoard,啟動完成之后打開瀏覽器(最好是Chrome,其他瀏覽器特別是IE瀏覽器會有很多顯示問題),在地址欄輸入http://localhost:6006就能夠看到代碼中存儲的計算圖結構和result張量變化的情況,具體如圖2.19和圖2.20所示。

圖2.19 利用TensorBoard展示的計算圖模型

圖2.20 利用TensorBoard展示的result張量的變化情況
下面我們來分析一下低階API實例中的關鍵代碼。按照我們對于機器學習的理解,代碼實際上分為模型構建和模型運行兩個階段,在模型構建階段應該還可以分為運行準備和實際運行兩個階段。模型構建階段的代碼如下:
a = tf.constant(3.1, name='a') x = tf.placeholder(tf.float32, name='x') w = tf.Variable(2.0, name='w') result = tf.add(a, w*x)
在這里使用TensorFlow的常量、變量和占位符,通過add函數和乘法運算符完成了模型的最終構建。接下來是運行準備階段,這個階段的主要工作就是實例化會話對象,并且完成張量的初始化。其代碼如下:
sess = tf.Session() init = tf.global_variables_initializer()
最后,Session(會話)的run方法調用就是模型的實際運行,在這里要特別注意的是,我們是通過feed_dict這種類字典的簡單數據集調用方式完成訓練數據的輸入的:
sess.run(init) for i in range(100): summary_, result_ = sess.run([merged, result], feed_dict={x:float(i)}) sess.close()
如果仔細對照代碼,就會發現有一些代碼我們跳過了,這些代碼就是使用Summary進行可視化log數據記錄的過程,包括可視化log數據記錄的定義:
tf.summary.scalar('result', result)
可視化log數據記錄的整合初始化:
merged = tf.summary.merge_all()
計算圖的存儲:
graph = sess.graph writer = tf.summary.FileWriter('./log', graph)
可視化log數據記錄的整合初始化的存儲:
writer.add_summary(summary_, i)
2.5.2 TensorFlow高級API
Keras的核心數據結構是Model,是一種組織網絡層的方式。最簡單的模型是Sequential順序模型,它由多個網絡層線性堆疊。對于更復雜的結構,應該使用Keras函數式API,它允許構建任意的神經網絡圖。
Keras有以下三個優點:
第一,用戶友好。Keras是為人類而不是為機器設計的API。它把用戶體驗放在首要和中心位置。Keras遵循減少認知困難的最佳實踐:它提供一致且簡單的API,將常見用例所需的用戶操作數量降至最低,并且在用戶錯誤時提供清晰和可操作的反饋。
第二,模塊化能力強。模型被理解為由獨立的、完全可配置的模塊構成的序列或圖。這些模塊可以盡可能少地限制組裝在一起。特別是神經網絡層、損失函數、優化器、初始化方法、激活函數、正則化方法,它們都是可以結合起來構建新模型的模塊。
第三,易擴展性好。新的模塊是很容易添加的(作為新的類和函數),現有的模塊已經提供了充足的示例。由于能夠輕松地創建可以提高表現力的新模塊,因此Keras更加適合高級研究。
下面將展示使用tf.keras模塊的一些配置和技巧。
1. 導入tf.keras
tf.keras是TensorFlow對Keras API規范的實現。這是一個用于構建和訓練模型的高階API,包含對TensorFlow特定功能(例如Eager Execution、tf.data管道和Estimator)的頂級支持。tf.keras使TensorFlow更易于使用,并且不會犧牲靈活性和性能。
導入tf.keras以設置TensorFlow程序:
import tensorflow as tf from tensorflow.keras import layers print(tf.VERSION) print(tf.keras.__version__)
在終端打印結果:
1.11.0 2.1.6-tf
tf.keras可以運行任何與Keras兼容的代碼,但請注意:
- 最新版TensorFlow中的tf.keras版本可能與PyPI中的最新Keras版本不同。請查看tf.keras.version。
- 保存模型的權重時,tf.keras默認采用檢查點格式。請傳遞save_format='h5'以使用HDF5。
2. 構建簡單的模型
在Keras中,你可以通過組合層來構建模型。模型(通常)是由層構成的圖,最常見的模型類型是層的堆疊:tf.keras.Sequential模型。
例如,構建一個簡單的全連接網絡(多層感知器),可運行以下代碼:
model = tf.keras.Sequential() # Adds a densely-connected layer with 64 units to the model: model.add(layers.Dense(64, activation='relu')) # Add another: model.add(layers.Dense(64, activation='relu')) # Add a softmax layer with 10 output units: model.add(layers.Dense(10, activation='softmax'))
3. 配置層
我們可以使用很多tf.keras.layers,它們具有一些相同的構造函數參數。
- activation:設置層的激活函數。此參數由內置函數的名稱指定,或指定為可調用對象。默認情況下,系統不會應用任何激活函數。
- kernel_initializer和bias_initializer:創建層權重(核和偏差)的初始化方案。此參數是一個名稱或可調用對象,默認為Glorot uniform初始化器。
- kernel_regularizer和bias_regularizer:應用層權重(核和偏差)的正則化方案,例如L1或L2正則化。默認情況下,系統不會應用正則化函數。
以下代碼使用構造函數參數實例化tf.keras.layers. Dense層:
# Create a sigmoid layer: layers.Dense(64, activation='sigmoid') # Or: layers.Dense(64, activation=tf.sigmoid) # A linear layer with L1 regularization of factor 0.01 applied to the kernel matrix: layers.Dense(64, kernel_regularizer=tf.keras.regularizers.l1(0.01)) # A linear layer with L2 regularization of factor 0.01 applied to the bias vector: layers.Dense(64, bias_regularizer=tf.keras.regularizers.l2(0.01)) # A linear layer with a kernel initialized to a random orthogonal matrix: layers.Dense(64, kernel_initializer='orthogonal') # A linear layer with a bias vector initialized to 2.0s: layers.Dense(64, bias_initializer=tf.keras.initializers.constant(2.0))
4. 訓練和評估
構建好模型后,可通過調用compile方法配置該模型的學習流程,代碼如下:
model = tf.keras.Sequential([ # Adds a densely-connected layer with 64 units to the model: layers.Dense(64, activation='relu'), # Add another: layers.Dense(64, activation='relu'), # Add a softmax layer with 10 output units: layers.Dense(10, activation='softmax')]) model.compile(optimizer=tf.train.AdamOptimizer(0.001), loss='categorical_crossentropy', metrics=['accuracy'])
tf.keras.Model.compile采用了以下3個重要參數。
- optimizer:此對象會指定訓練過程。從tf.train模塊向其傳遞優化器實例,例如tf.train.AdamOptimizer、tf.train.RMSPropOptimizer或tf.train.GradientDescentOptimizer。
- loss:要在優化期間最小化的函數。常見選擇包括均方誤差(Mean Squared Error, MSE)、categorical_crossentropy和binary_crossentropy。損失函數由名稱或通過從tf.keras.losses模塊傳遞可調用對象來指定。
- metrics:用于監控訓練。它是tf.keras.metrics模塊中的字符串名稱或可調用對象。
以下代碼展示了配置模型以進行訓練的兩個示例:
# Configure a model for mean-squared error regression. model.compile(optimizer=tf.train.AdamOptimizer(0.01), loss='mse', # mean squared error metrics=['mae']) # mean absolute error # Configure a model for categorical classification. model.compile(optimizer=tf.train.RMSPropOptimizer(0.01), loss=tf.keras.losses.categorical_crossentropy, metrics=[tf.keras.metrics.categorical_accuracy])
- Machine Learning for Cybersecurity Cookbook
- Visual FoxPro 6.0數據庫與程序設計
- 輕松學Java
- Learning Apache Cassandra(Second Edition)
- 計算機網絡技術實訓
- 可編程控制器技術應用(西門子S7系列)
- DevOps:Continuous Delivery,Integration,and Deployment with DevOps
- 控制系統計算機仿真
- 樂高機器人—槍械武器庫
- Prometheus監控實戰
- 學會VBA,菜鳥也高飛!
- The Python Workshop
- 菜鳥起飛系統安裝與重裝
- Visual FoxPro程序設計
- Learn Microsoft Azure