TensorFlow和Keras入門必讀教程
導(dǎo)讀:本文對TensorFlow的框架和基本示例進(jìn)行簡要介紹。

01 TensorFlow
TensorFlow最初由Google開發(fā),旨在讓研究人員和開發(fā)人員進(jìn)行機(jī)器學(xué)習(xí)研究。它最初被定義為描述機(jī)器學(xué)習(xí)算法的接口,以及執(zhí)行該算法的實現(xiàn)。
TensorFlow的主要預(yù)期目標(biāo)是簡化機(jī)器學(xué)習(xí)解決方案在各種平臺上的部署,如計算機(jī)CPU、計算機(jī)GPU、移動設(shè)備以及最近的瀏覽器中的部署。最重要的是,TensorFlow提供了許多有用的功能來創(chuàng)建機(jī)器學(xué)習(xí)模型并大規(guī)模運(yùn)行它們。TensorFlow 2于2019年發(fā)布,它專注于易用性,并能保持良好的性能。
這個庫于2015年11月開源。從那時起,它已被世界各地的用戶改進(jìn)和使用。它被認(rèn)為是開展研究的首選平臺之一。就GitHub活躍度而言,它也是最活躍的深度學(xué)習(xí)框架之一。
TensorFlow既可供初學(xué)者使用,也可供專家使用。TensorFlow API具有不同級別的復(fù)雜度,從而使初學(xué)者可以從簡單的API開始,同時也可以讓專家創(chuàng)建非常復(fù)雜的模型。我們來探索一下這些不同級別的模型。
1. TensorFlow主要架構(gòu)
TensorFlow架構(gòu)(見圖2-1)具有多個抽象層級。我們首先介紹底層,然后逐漸通往最上層。

▲圖2-1 TensorFlow架構(gòu)圖
大多數(shù)深度學(xué)習(xí)計算都是用C++編碼的。為了在GPU上進(jìn)行運(yùn)算,TensorFlow使用了由NVIDIA開發(fā)的庫CUDA。這就是如果想要利用GPU功能就需要安裝CUDA,以及不能使用其他硬件制造商GPU的原因。
然后,Python底層API(low-level API)封裝了C++源代碼。當(dāng)調(diào)用TensorFlow的Python方法時,通常會在后臺調(diào)用C++代碼。這個封裝層使用戶可以更快地工作,因為Python被認(rèn)為更易于使用并且不需要編譯。該P(yáng)ython封裝器可以創(chuàng)建非?;镜倪\(yùn)算,例如矩陣乘法和加法。
最上層是高級API(high-level API),由Keras和評估器API(estimator API)兩個組件組成。Keras是TensorFlow的一個用戶友好型、模塊化且可擴(kuò)展的封裝器,評估器API包含多個預(yù)制組件,可讓你輕松地構(gòu)建機(jī)器學(xué)習(xí)模型。你可以將它們視為構(gòu)建塊或模板。
tip:在深度學(xué)習(xí)中,模型通常是指經(jīng)過數(shù)據(jù)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)。模型由架構(gòu)、矩陣權(quán)重和參數(shù)組成。
2. Keras介紹
Keras于2015年首次發(fā)布,它被設(shè)計為一種接口,可用于使用神經(jīng)網(wǎng)絡(luò)進(jìn)行快速實驗。因此,它依賴TensorFlow或Theano(另一個深度學(xué)習(xí)框架,現(xiàn)已棄用)來運(yùn)行深度學(xué)習(xí)操作。Keras以其用戶友好性著稱,是初學(xué)者的首選庫。
自2017年以來,TensorFlow完全集成了Keras,這意味著無須安裝TensorFlow以外的任何庫就可使用它。我們將依賴tf.keras而不是Keras的獨(dú)立版本。這兩個版本之間有一些細(xì)微的差異,例如與TensorFlow的其他模塊的兼容性以及模型的保存方式。因此,讀者必須確保使用正確的版本,具體方法如下:
在代碼中,導(dǎo)入tf.keras而不是keras。
瀏覽TensorFlow網(wǎng)站上的tf.keras文檔,而不是keras.io文檔。
在使用外部Keras庫時,請確保它們與tf.keras兼容。
某些保存的模型在Keras版本之間可能不兼容。
這兩個版本在可預(yù)見的未來將繼續(xù)共存,而tf.keras與TensorFlow集成將越來越密切。為了說明Keras的強(qiáng)大功能和簡單性,我們將使用該庫實現(xiàn)一個簡單的神經(jīng)網(wǎng)絡(luò)。
02 基于Keras的簡單計算機(jī)視覺模型
在深入探討TensorFlow的核心概念之前,我們先從一個計算機(jī)視覺的經(jīng)典示例開始,它使用數(shù)據(jù)集MNIST進(jìn)行數(shù)字識別。
1. 準(zhǔn)備數(shù)據(jù)
首先,導(dǎo)入數(shù)據(jù)。它由用于訓(xùn)練集的60 000幅圖像和用于測試集的10 000幅圖像組成:
import tensorflow as tf
num_classes = 10
img_rows, img_cols = 28, 28
num_channels = 1
input_shape = (img_rows, img_cols, num_channels)
(x_train, y_train),(x_test, y_test) = tf.keras.datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
tip:常見的做法是使用別名tf來導(dǎo)入TensorFlow,從而加快讀取和鍵入速度。通常用x表示輸入數(shù)據(jù),用y表示標(biāo)簽。
tf.keras.datasets模塊提供快速訪問,以下載和實例化一些經(jīng)典數(shù)據(jù)集。使用load_data導(dǎo)入數(shù)據(jù)后,請注意,我們將數(shù)組除以255.0,得到的數(shù)字范圍為[0, 1]而不是[0, 255]。將數(shù)據(jù)歸一化在[0, 1]范圍或[-1, 1]范圍是一種常見的做法。
2. 構(gòu)建模型
現(xiàn)在,我們可以繼續(xù)構(gòu)建實際模型。我們將使用一個非常簡單的架構(gòu),該架構(gòu)由兩個全連接層(也稱為稠密層)組成。在詳細(xì)介紹架構(gòu)之前,我們來看一下代碼。可以看到,Keras代碼非常簡潔:
model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dense(num_classes, activation='softmax'))
由于模型是層的線性堆棧,因此我們首先調(diào)用Sequential函數(shù)。然后,依次添加每一層。模型由兩個全連接層組成。我們逐層構(gòu)建:
展平層(Flatten):它將接受表示圖像像素的二維矩陣,并將其轉(zhuǎn)換為一維數(shù)組。我們需要在添加全連接層之前執(zhí)行此操作。28×28的圖像被轉(zhuǎn)換為大小為784的向量。
大小為128的稠密層(Dense):它使用大小為128×784的權(quán)重矩陣和大小為128的偏置矩陣,將784個像素值轉(zhuǎn)換為128個激活值。這意味著有100 480個參數(shù)。
大小為10的稠密層(Dense):它將把128個激活值轉(zhuǎn)變?yōu)樽罱K預(yù)測。注意,因為概率總和為1,所以我們將使用softmax激活函數(shù)。
tip:softmax函數(shù)獲取某層的輸出,并返回總和為1的概率。它是分類模型最后一層的選擇的激活函數(shù)。
請注意,使用model.summary()可以獲得有關(guān)模型、輸出及其權(quán)重的描述。下面是輸出:

設(shè)置好架構(gòu)并初始化權(quán)重后,模型現(xiàn)在就可以針對所選任務(wù)進(jìn)行訓(xùn)練了。
3. 訓(xùn)練模型
Keras讓訓(xùn)練變得非常簡單:
model.compile(optimizer='sgd',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
callbacks = [tf.keras.callbacks.TensorBoard('./keras')]
model.fit(x_train, y_train, epochs=25, verbose=1, validation_data=(x_test, y_test), callbacks=callbacks)
在剛剛創(chuàng)建的模型上調(diào)用.compile()是一個必需的步驟。必須指定幾個參數(shù):
優(yōu)化器(optimizer):運(yùn)行梯度下降的組件。
損失(loss):優(yōu)化的指標(biāo)。在本例中,選擇交叉熵,就像上一章一樣。
評估指標(biāo)(metrics):在訓(xùn)練過程進(jìn)行評估的附加評估函數(shù),以進(jìn)一步查看有關(guān)模型性能(與損失不同,它們不在優(yōu)化過程中使用)。
名為sparse_categorical_crossentropy的Keras損失執(zhí)行與categorical_crossentropy相同的交叉熵運(yùn)算,但是前者直接將真值標(biāo)簽作為輸入,而后者則要求真值標(biāo)簽先變成獨(dú)熱(one-hot)編碼。因此,使用sparse_...損失可以免于手動轉(zhuǎn)換標(biāo)簽的麻煩。
tip:將'sgd'傳遞給Keras等同于傳遞tf.keras.optimizers.SGD()。前一個選項更易于閱讀,而后一個選項則可以指定參數(shù),如自定義學(xué)習(xí)率。傳遞給Keras方法的損失、評估指標(biāo)和大多數(shù)參數(shù)也是如此。
然后,我們調(diào)用.fit()方法。它與另一個流行的機(jī)器學(xué)習(xí)庫scikit-learn中所使用的接口非常相似。我們將訓(xùn)練5輪,這意味著將對整個訓(xùn)練數(shù)據(jù)集進(jìn)行5次迭代。
請注意,我們將verbose設(shè)置為1。這將讓我們獲得一個進(jìn)度條,其中包含先前選擇的指標(biāo)、損失和預(yù)計完成時間(Estimated Time of Arrival,ETA)。ETA是對輪次結(jié)束之前剩余時間的估計。進(jìn)度條如圖2-2所示。

▲圖2-2 Keras在詳細(xì)模式下顯示的進(jìn)度條屏幕截圖
4. 模型性能
如第1章中所述,你會注意到模型是過擬合的——即訓(xùn)練準(zhǔn)確率大于測試準(zhǔn)確率。如果對模型訓(xùn)練5輪,則最終在測試集上的準(zhǔn)確率為97%。這比上一章(95%)高了約2個百分點(diǎn)。最先進(jìn)的算法可達(dá)到99.79%的準(zhǔn)確率。
我們遵循了三個主要步驟:
加載數(shù)據(jù):在本例中,數(shù)據(jù)集已經(jīng)可用。在未來的項目中,你可能需要其他的步驟來收集和清理數(shù)據(jù)。
創(chuàng)建模型:使用Keras可以讓這一步驟變得容易——按順序添加層即可定義模型的架構(gòu)。然后,選擇損失、優(yōu)化器和評估指標(biāo)進(jìn)行監(jiān)控。
訓(xùn)練模型:模型第一次運(yùn)行效果很好。在更復(fù)雜的數(shù)據(jù)集上,通常需要在訓(xùn)練過程中微調(diào)參數(shù)。
借助TensorFlow的高級API——Keras,整個過程非常簡單。在這個簡單API的背后,該庫隱藏了很多復(fù)雜操作。


干貨直達(dá)??
