深度學(xué)習(xí)發(fā)展勢頭迅猛,但近兩年涌現(xiàn)的諸多深度學(xué)習(xí)框架讓初學(xué)者無所適從。如 Google 的 TensorFlow、亞馬遜的 MXNet、Facebook 支持的 PyTorch、Theano、Caffe、CNTK、Chainer、百度的 PaddlePaddle、DSSTNE、DyNet、BigDL、Neon 等等。
在這其中,TensorFlow 作為最為著名的用于深度學(xué)習(xí)生產(chǎn)環(huán)境的框架,它有一個(gè)非常強(qiáng)大的生態(tài)體系支持,然而,相比其他框架,TensorFlow 也有其劣勢,如速度較慢、使用上手難。而基于 TensorFlow 基礎(chǔ)上構(gòu)建的 Keras 提供了簡單易用的 API 接口,非常適合初學(xué)者使用。
2017 年 1 月,隨著 Keras 的作者、谷歌 AI 研究員 Francois Chollet 的一條消息的宣布,Keras 成為第一個(gè)被添加到 TensorFlow 核心的高級(jí)別框架,Keras 從此成為 Tensorflow 的默認(rèn) API。
“那么,我應(yīng)該在項(xiàng)目中使用 Keras 還是 TensorFlow?Keras 和 TensorFlow 究竟哪個(gè)會(huì)更好?我應(yīng)該把時(shí)間花在研究 TensorFlow 還是 Keras 上?”
在與深度學(xué)習(xí)的研究人員、從業(yè)者包括工程師在內(nèi)的交談中,“Deep Learning for Computer Vision with Python ”一書作者 Adrian Rosebrock 聽到了他們的困惑。
就 Keras 和 TensorFlow 而言,Rosebrock 認(rèn)為開發(fā)者更應(yīng)該關(guān)注的是當(dāng) Keras 實(shí)際上已被完全采用并整合到 TensorFlow 后,自己可以:
使用 Keras 易于使用的界面定義模型。
如果需要 TensorFlow 的特定功能,或需要實(shí)現(xiàn) Keras 不支持但 TensorFlow 支持的自定義功能,則調(diào)入 TensorFlow。
他給出的建議是先使用 Keras ,然后下載 TensorFlow 以獲取可能需要的任何特定功能。文本中,Rosebrock展示了如何訓(xùn)練使用 Keras 的神經(jīng)網(wǎng)絡(luò)和使用直接構(gòu)建在 TensorFlow 庫中的 Keras+TensorFlow 集成(具有自定義功能)的模型。
下面開始正文:
▌對比 Keras 和 TensorFlow 沒什么意義
前些年,深度學(xué)習(xí)領(lǐng)域的研究人員、開發(fā)人員和工程師必須經(jīng)常做出一些選擇:
我應(yīng)該選擇易于使用但自定義困難的 Keras 庫?
還是應(yīng)該使用難度更大的 TensorFlow API,編寫大量代碼?(更不用說一個(gè)不那么容易使用的 API 了。)
如果你陷于“我應(yīng)該使用 Keras 還是 TensorFlow”這樣的問題,你可以退一步再看,其實(shí)這是一個(gè)錯(cuò)誤的問題,因?yàn)槟憧梢赃x擇同時(shí)使用兩個(gè)。
我會(huì)使用基于 TensorFlow 的標(biāo)準(zhǔn) keras 模塊和 tf.keras 模塊,來實(shí)現(xiàn)一個(gè)卷積神經(jīng)網(wǎng)絡(luò)(CNN)。然后,基于一個(gè)示例數(shù)據(jù)集,來訓(xùn)練這些 CNN,然后檢查所得結(jié)果,你會(huì)發(fā)現(xiàn),Keras 和 TensorFlow 是可以和諧共處的。
雖然自一年多之前,TensorFlow 就宣稱 Keras 將被并入 TensorFlow 的官方發(fā)布版本中,但令我詫異的是,仍有很多深度學(xué)習(xí)開發(fā)者沒有意識(shí)到,他們可以通過 tf.keras 子模塊來調(diào)用 Keras。更重要的是,Keras 與 TensorFlow 是無縫銜接的,使得我們將 TensorFlow 的源代碼直接寫入 Keras 模型中。
在 TensorFlow 中結(jié)合 Keras 使用,會(huì)有雙贏效果:
你可以使用 Keras 提供的簡單、原生 API 來創(chuàng)建自己的模型。
Keras 的 API 類似于 scikit-learn 的,都可稱為機(jī)器學(xué)習(xí)的優(yōu)質(zhì) API。
Keras 的 API 是模塊化的、基于 Python ,并且極其易于使用。
當(dāng)你需要實(shí)現(xiàn)一個(gè)自定義的層或更復(fù)雜的損失函數(shù)時(shí),你可以深入使用 TensorFlow,將代碼自動(dòng)地與 Keras 模型相結(jié)合。
▌Keras 通過 tf.keras 模塊構(gòu)建到 TensorFlow 中
可以看到,我們通過引入 TensorFlow (tf) 并調(diào)用 tf.keras,在 Python shell 中展示了 Keras 實(shí)際上是 TensorFlow 的一部分。
tf.keras 中的 Keras 允許我們使用標(biāo)準(zhǔn)的 Keras 包獲取下面這樣簡單的前饋神經(jīng)網(wǎng)絡(luò):
接下來基于 TensorFlow 的一部分 —— tf.keras 子模塊,來實(shí)現(xiàn)同樣的網(wǎng)絡(luò):
然而這是否意味著你必須使用 tf.keras?從而現(xiàn)在放棄使用標(biāo)準(zhǔn) Keras 包了嗎?當(dāng)然不是!
Keras 依然作為一個(gè)庫,與 TensorFlow 分開,進(jìn)行獨(dú)立操作,所以仍存在未來兩者會(huì)分開的可能性;然而,我們知道 Google 官方同時(shí)支持 Keras 和 TensorFlow,分開似乎又是極不可能發(fā)生的。
但重點(diǎn)在于:
如果你更喜歡只基于 Keras 來編程,那就這么做吧,以后可以一直如此。但如果你是 TensorFlow 用戶,你應(yīng)該開始考慮 Keras API 了,因?yàn)椋?/p>
它是基于 TensorFlow 創(chuàng)建的
它更易于使用
當(dāng)你需要用純 TensorFlow 實(shí)現(xiàn)特定性能或功能時(shí),它可以直接用于你的 Keras。
▌示例數(shù)據(jù)集
CIFAR-10 數(shù)據(jù)集有10個(gè)類,我們用該數(shù)據(jù)集來展示本文的觀點(diǎn)
為了簡單起見,我們就在 CIFAR-10 數(shù)據(jù)集上訓(xùn)練兩個(gè)單獨(dú)的卷積神經(jīng)網(wǎng)絡(luò) (CNN),方案如下:
方法 1 :以 TensorFlow 作為后端的 Keras 模型
方法 2 :使用tf.keras中 Keras 子模塊
在介紹的過程中我還會(huì)展示如何把自定義的 TensorFlow 代碼寫入你的 Keras 模型中。
CIFAR-10 數(shù)據(jù)集包括10個(gè)單獨(dú)的類,50,000 張訓(xùn)練圖片和 10,000 張測試圖片。
▌項(xiàng)目結(jié)構(gòu)
我們可以在終端使用 tree 指令來查看該項(xiàng)目的結(jié)構(gòu):
pyimagesearch模塊被包括在與網(wǎng)絡(luò)條目相關(guān)的下載中。它不能通過 pip 來安裝,但包含在 "Downloads"后的結(jié)果中。我們先回顧一下該模塊中兩個(gè)重要的 Python 文件:
minivggnetkeras.py:此文件是基于 Keras 實(shí)現(xiàn)的 MiniVGGNet 網(wǎng)絡(luò),一個(gè)基于 VGGNet 的深度學(xué)習(xí)模型。
minivggnettf.py:此文件是基于 TensorFlow + Keras (如 tf.keras)實(shí)現(xiàn)的 MiniVGGNet 網(wǎng)絡(luò)。
該項(xiàng)目的根目錄包含兩個(gè) Python 文件:
train_network_keras.py:用 Keras 實(shí)現(xiàn)的訓(xùn)練腳本;
train_network_tf.py: TensorFlow + Keras 實(shí)現(xiàn)需要的訓(xùn)練腳本,與前者基本相同;但我們?nèi)詴?huì)進(jìn)行說明,并標(biāo)出不同之處。
每個(gè)腳本都會(huì)生成各自訓(xùn)練的 accuracy 和 loss 曲線:
plot_keras.png
plot_tf.png
接下來就會(huì)向大家介紹基于 Keras 和 TensorFlow + Keras (tf.keras) 實(shí)現(xiàn)的 MiniVGGNet 網(wǎng)絡(luò)和他們的訓(xùn)練過程。
▌?dòng)?Keras 訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)
用 Keras 實(shí)現(xiàn)的一個(gè) miniVGGNet 卷積神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)
訓(xùn)練我們網(wǎng)絡(luò)的第一步是在 Keras 中構(gòu)建網(wǎng)絡(luò)的架構(gòu)。
如果你已經(jīng)熟悉 Keras 訓(xùn)練神經(jīng)網(wǎng)絡(luò)的基礎(chǔ)知識(shí),那么我們就開始吧 (如果你對此并不了解的話,請參考相關(guān)的介紹性文章)。
相關(guān)鏈接:https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/
首先,打開 minivggnetkeras.py 文件并插入以下代碼:
從導(dǎo)入一系列所需的 Keras 庫開始構(gòu)建模型。
然后,定義一個(gè)的MiniVGGNetKeras類:
我們在第 12 行定義了build方法,并定義inputShape和input參數(shù)。 我們假定以 channel last 的規(guī)則排序,所以inputShape參數(shù)中最后一個(gè)值應(yīng)該對應(yīng)的是depth值。
下面開始定義卷積神經(jīng)網(wǎng)絡(luò)的主體結(jié)構(gòu):
從上面這段代碼你可以觀察到我們在每次應(yīng)用池化 (pooling) 之前都堆疊了一系列卷積 (conv2D),ReLU 激活函數(shù)和批規(guī)范化層 (batch normalization),以降低卷積操作后的空間維度。此外,我們還使用 Dropout 技術(shù)來防止模型的過擬合現(xiàn)象。
對于圖層類型和有關(guān)術(shù)語的知識(shí),可以參考以前的 Keras 教程
https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/
如果想深入研究的話,推薦書“Deep Learning for Computer Vision with Python ”
https://www.pyimagesearch.com/deep-learning-computer-vision-python-book/
然后,將全連接層 (FC) 添加到網(wǎng)絡(luò)結(jié)構(gòu)中,代碼如下:
我們將 FC 層和 Softmax 分類器添加到網(wǎng)絡(luò)中。隨后我們定義神經(jīng)網(wǎng)絡(luò)模型并將其返回給回調(diào)函數(shù) (calling function)。
現(xiàn)在我們已經(jīng)在 Keras 中實(shí)現(xiàn)了 CNN 模型的定義。下面,我們創(chuàng)建用于訓(xùn)練該模型的程序腳本。
打開train_network_keras.py文件并插入以下代碼:
我們首先在代碼的第 2-13 行導(dǎo)入我們模型訓(xùn)練所需的包。
需要注意的是:
在第 3 行,將 Matplotlib 的后端設(shè)置為 Agg,以便我們可以能將訓(xùn)練圖保存為圖像文件。
在第 6 行,我們導(dǎo)入MiniVGGNetKeras類。
我們使用 scikit-learn 庫中的LabelBinarizer方法進(jìn)行獨(dú)熱編碼 (one-hot encoding),并使用其classification_report方法打印出分類精度統(tǒng)計(jì)結(jié)果 (分別對應(yīng)第 7 行和第 8 行)。
我們在第 10 行導(dǎo)入訓(xùn)練所需的數(shù)據(jù)庫。
如何使用自定義的數(shù)據(jù)集,可參考
https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/
https://www.pyimagesearch.com/2018/04/16/keras-and-convolutional-neural-networks-cnns/
此外,我們還在第 16-19 行解析了一個(gè)命令行參數(shù) (輸出 --plot path)。
下面我們就加載 CIFAR-10 數(shù)據(jù)集,并對標(biāo)簽進(jìn)行編碼操作,代碼如下:
在第 24 行和第 25 行中,我們分別加載并提取訓(xùn)練和測試所需的數(shù)據(jù),同時(shí)在第 26 和 27 行將數(shù)據(jù)進(jìn)行 floating point + scale 轉(zhuǎn)化。
第 30-36 行我們對標(biāo)簽進(jìn)行編碼并初始化真實(shí)的labelNames。
模型定義和數(shù)據(jù)集導(dǎo)入的工作都已經(jīng)完成。現(xiàn)在可以開始訓(xùn)練我們的模型,代碼如下:
在第 40-46 行,我們設(shè)置訓(xùn)練過程所需的一些參數(shù)和模型優(yōu)化方法。
然后在第 47-50 行,我們使用MiniVGGNetKeras.build方法初始化我們的模型并進(jìn)行編譯。
最后,在第 54 和 55 行啟動(dòng)模型的訓(xùn)練程序。
下面,我們將對網(wǎng)絡(luò)模型進(jìn)行評(píng)估并生成一個(gè)結(jié)果圖:
在這里,我們利用測試數(shù)據(jù)來評(píng)估我們的模型,并生成 classification_report。最后,我們將評(píng)估結(jié)果集成并導(dǎo)出結(jié)果圖。
需要注意的是,通常在這里我們會(huì)將模型序列化并導(dǎo)出我們的模型,以便可以在圖像或視頻處理腳本中使用它,但在這篇教程中我們不介紹這部分的內(nèi)容。
如果你想要運(yùn)行以上的腳本,請確認(rèn)下載本文的源代碼。
然后,打開一個(gè)終端并執(zhí)行以下命令就可以用 Keras 實(shí)現(xiàn)一個(gè)神經(jīng)網(wǎng)絡(luò):
在我的電腦 cpu 上運(yùn)行每個(gè)訓(xùn)練 epoch 只需要 5 多分鐘。訓(xùn)練結(jié)果圖如下:
用 Keras 實(shí)現(xiàn)的神經(jīng)網(wǎng)絡(luò)模型,以 Matplotlib 畫出訓(xùn)練過程的 accuracy/loss 曲線
正如我們從上面終端的輸出看到那樣,我們的模型取得75%的準(zhǔn)確度。雖然這不是最先進(jìn)的模型,但它能比隨機(jī)猜測 (1/10) 要好得多。
相比起小型的神經(jīng)網(wǎng)絡(luò),我們模型的結(jié)果實(shí)際上是非常好的!
此外,正如我們在輸出圖6中所示,我們模型并不會(huì)發(fā)生過擬合現(xiàn)象。
▌?dòng)?Tensorflow 和 tf.keras 訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)模型
使用 tf.keras (內(nèi)置于 TensorFlow 中的模塊) 構(gòu)建的 MiniVGGNet CNN 架構(gòu)與我們直接使用 Keras 構(gòu)建的模型是相同的。在此,出于演示的目的,我改變了其中的激活函數(shù),其他的結(jié)構(gòu)都是相同的。
上面我們已經(jīng)能夠使用 Keras 庫實(shí)現(xiàn)并訓(xùn)練了一個(gè)簡單的 CNN 模型。接下來,我們要做的是:
1.學(xué)習(xí)如何使用 TensorFlow 中的 tf.keras 模塊實(shí)現(xiàn)相同的網(wǎng)絡(luò)架構(gòu)
2.在我們的 Keras 模型中包含一個(gè) TensorFlow 激活函數(shù),而該函數(shù)未在Keras中實(shí)現(xiàn)。
下面,讓我們開始吧。
首先,打開minivggnettf.py文件,我們將實(shí)現(xiàn) TensorFlow 版的 MiniVGGNet 模型,代碼如下:
在這個(gè) .py 文件中,請注意第 2 行我們需要導(dǎo)入所需的 tensorflow 依賴庫,而 tensorflow 中自帶 tf.keras 子模塊,該子模塊包含我們可以直接調(diào)用的所有 Keras 功能。
在模型定義中,我使用 Lambda 層,如代碼中的黃色突出顯示,它可以用于插入自定義激活函數(shù) CRELU (Concatenated ReLUs),
激活函數(shù) CRELU是由 Shang 等人在論文“Understanding and Improving Convolutional Neural Network”中所提出。
CRELU 激活函數(shù)在 Keras 中沒有相應(yīng)的實(shí)現(xiàn),但是在 TensorFlow 中可以。你可以在 TensorFlow 中的 tf.keras 模塊,使用一行代碼來將 CRELU 函數(shù)添加到我們的 Keras 模型中。
還需要注意的是:CRELU 函數(shù)有兩個(gè)輸出,一個(gè) positive ReLU 和一個(gè) negative ReLU,二者連接在一起。對于正值 x,CRELU 函數(shù)的返回值是 [x,0];而對于負(fù)值 x,CRELU 函數(shù)的返回值是 [0,x]。有關(guān)該函數(shù)的詳細(xì)介紹可以參考 Shang 等人的論文。
接下來,我們將用 TensorFlow + Keras 來定義用于訓(xùn)練MiniVGGNetTF模型的程序。打開 train_network_tf.py 并插入如下代碼:
在 2-12 行,我們導(dǎo)入訓(xùn)練過程所需的依賴庫。與我們之前的 Keras 版的訓(xùn)練腳本相比,唯一的變化在于我們導(dǎo)入了 MiniVGGNetTF 類及 tensorflow as tf 而不是使用 Keras。而在第 15-18 行是我們的命令行參數(shù)解析部分。
和之前一樣,我們在第 23 行加載模型訓(xùn)練所需的數(shù)據(jù)。腳本剩余的部分和之前 Keras 版的訓(xùn)練過程是一樣的,即提取并分離訓(xùn)練和測試集數(shù)據(jù)并編碼我們的標(biāo)簽。
下面,讓我們開始訓(xùn)練我們的模型,代碼如下:
在第 39-54 行,是與 Keras 版訓(xùn)練過程不同的地方,我們用黃色突出顯示,其余部分都是相同的。
在第 58-73 行,我們用測試數(shù)據(jù)評(píng)估我們的模型并繪制最終的結(jié)果。
正如你所看到的,我們只是更換了所使用的方法 (使用 tf.keras),實(shí)現(xiàn)了幾乎一樣的訓(xùn)練流程。
然后,打開一個(gè)終端并執(zhí)行以下命令就可以使用 tensorflow + tf.keras 訓(xùn)練一個(gè)神經(jīng)網(wǎng)絡(luò)模型:
訓(xùn)練完成后,你可以得到如上類似的訓(xùn)練結(jié)果圖:
用 Tensorflow + tf.keras 實(shí)現(xiàn)的神經(jīng)網(wǎng)絡(luò)模型,以 Matplotlib 畫出訓(xùn)練過程的 accuracy/loss 曲線
可以看到,我們用 CRELU 代替原有的 RELU 激活函數(shù),獲得 76% 的準(zhǔn)確率; 然而,1% 的準(zhǔn)確性提升增加可能是由于網(wǎng)絡(luò)中權(quán)重的隨機(jī)初始化導(dǎo)致的,這還需進(jìn)行交叉驗(yàn)證實(shí)驗(yàn)來進(jìn)一步證明 CRELU 激活函數(shù)是否確實(shí)能夠提升模型的準(zhǔn)確性。當(dāng)然,原始精度并不是本節(jié)所重點(diǎn)關(guān)注的內(nèi)容。
相反,更需要我們注意的是,如何在 Keras 模型內(nèi)部,用 TensorFlow 的激活函數(shù)替換標(biāo)準(zhǔn) Keras 激活函數(shù)!
此外,你也可以使用自定義的激活函數(shù)、損失/成本函數(shù)或圖層來執(zhí)行以上相同的操作。
▌總結(jié)
在今天的文章中,關(guān)于 Keras 和 TensorFlow 我們主要討論了以下幾個(gè)問題:
我是否應(yīng)該在我的項(xiàng)目中使用 Keras 或 TensorFlow?
TensorFlow 比 Keras 要好嗎?
我是否要花時(shí)間學(xué)習(xí) TensorFlow 或者 Keras?
最終,我們發(fā)現(xiàn),試圖在 Keras 和 TensorFlow 之間作出抉擇變成一個(gè)越來越無關(guān)緊要的問題。Keras 庫已經(jīng)通過 tf.keras 模塊直接集成到 TensorFlow 中了。
本質(zhì)上來說,你可以通過易于使用的 Keras API 來編碼模型和訓(xùn)練過程,然后用純 TensorFlow 進(jìn)行自定義實(shí)現(xiàn)。
所以,如果你正準(zhǔn)備開始學(xué)習(xí)深度學(xué)習(xí),或在糾結(jié)下一個(gè)項(xiàng)目是“用 Keras 還是 TensorFlow ?”或就是在思考他們兩者間“誰更好?”這些問題,現(xiàn)在正是尋找答案和動(dòng)力的時(shí)候了,而我給你的建議非常簡單:
不多說,先開始!
在你的 Python 項(xiàng)目中輸入 import keras 或者 import tensorflow as tf (這樣你就可以訪問 tf.keras 了)然后開始后續(xù)的工作。
TensorFlow 可以直接集成到你的模型和訓(xùn)練過程中,所以不用去比較特性,功能或易用性,你都可以直接在項(xiàng)目中使用 TensorFlow 或 Keras。
▌讀者的疑問
對此,有讀者提出了尖銳的疑問:
根據(jù)上述以及我的了解,不少開發(fā)者仍糾纏在 Keras 和 TensorFlow 究竟是什么的問題,可能對此我也不甚了解,但我還是希望提出一些澄清性的問題:
一是在這二者中,將一個(gè)視為計(jì)算引擎,另一個(gè)作為一種工具包是否正確?如果這樣的話,我猜測 TensorFlow 是工具包而 Keras 是計(jì)算后端?
二是你也提到 TensorFlow 與 Caffe 的整合,但為了支持 Keras 已經(jīng)放棄了 Caffe。您能分享您為什么會(huì)這樣的原因嗎?是 Caffe不再可用,還是因?yàn)?Keras 有了更多功能?
對此,Adrian Rosebrock 回應(yīng)道:
是的,Keras 本身依賴于 TensorFlow、Theano、CNTK 等后端來執(zhí)行實(shí)際的計(jì)算。
Caffe 仍存在,只是其他功能已經(jīng)分解為 Caffe2 。TensorFlow 從未成為 Caffe 的一部分。我們?nèi)允褂?Caffe,尤其是研究人員。但從業(yè)者尤其是 Python 的從業(yè)者更喜歡編程友好的庫如 TensorFlow、Keras、PyTorch 或 mxnet。
-
數(shù)據(jù)集
+關(guān)注
關(guān)注
4文章
1208瀏覽量
24701 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5503瀏覽量
121162 -
keras
+關(guān)注
關(guān)注
2文章
20瀏覽量
6087
原文標(biāo)題:Keras還是TensorFlow?深度學(xué)習(xí)框架選型實(shí)操分享
文章出處:【微信號(hào):rgznai100,微信公眾號(hào):rgznai100】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論