TensorFlow 2.0中的tf.keras和Keras有何區別?爲什麼以後一定要用tf.keras?

 2019-12-09 17:00:29.0

通過本教程,你可以瞭解 Keras 和 tf.keras 之間的區別,以及 TensorFlow 2.0 的新特性。本教程的靈感來自於上週二我在 PyImageSearch 閱讀器上收到的一封郵件。

一位名叫 Jeremiah 的讀者問道:

你好,Adrian,我看到 TensorFlow 2.0 在幾天前發佈了。

而且 TensorFlow 開發人員似乎正在推廣 Keras,或者應該叫 tf.keras,希望將它作爲 TensorFlow 2.0 中的推薦高級 API。

但是我覺得 Keras 包應該是自己獨立的呀?

我在訓練自己的網絡時,會糾結於該使用哪個「Keras」。

其次,有必要升級到 TensorFlow 2.0 嗎?

我在深度學習博客中看到了一些有關 TensorFlow 2.0 的教程,但是對於剛剛提到的那些困惑,我不知道該從何處着手去解決。你能給我一些啓示嗎?

其實,TensorFlow 2.0 發佈之後,許多像 Jeremiah 這樣的深度學習從業人員都在撓頭:

  • 作爲 Keras 用戶,TensorFlow 2.0 對我來說意味着什麼?

  • 我應該使用 keras 軟件包來訓練自己的神經網絡,還是在 TensorFlow 2.0 中使用 tf.keras 子模塊?

  • 作爲一個 Keras 用戶,TensorFlow 2.0 有哪些值得關注的特性?

從 TensorFlow 1.x 到 TensorFlow 2.0 的過渡或多或少都會有點困難,至少在開始階段是這樣。但是如果你對它有足夠多的瞭解,你的過渡期將會極其輕鬆。

在本教程剩餘的內容裏,我將討論 Keras 與 tf.keras 的相似之處,以及 TensorFlow 2.0 中值得注意的功能。

Keras vs tf.keras:在 TensorFlow 2.0 中它們的區別是什麼?

在本教程的第一部分,我們會討論 Keras 和 TensorFlow 之間錯綜複雜的歷史,包括它們是如何相互促進、共同成長、彼此滋養,從而達到今天這麼受歡迎的程度。

然後,我將說明爲什麼你應該在以後所有的深度學習項目和實驗中都使用 tf.keras。

再後面,我會講述「計算後端」的概念以及 TensorFlow 的流行度如何使其成爲 Keras 最流行的後端,從而爲 Keras 集成到 TensorFlow 的 tf.keras 子模塊中鋪平了道路。

最後,我會介紹一些 Keras 用戶應該關心的、流行的 TensorFlow 2.0 特性,包括:

  • Sessions 和 eager execution

  • 自動求導

  • 模型和層的子類化

  • 更好的多 GPU /分佈式訓練支持

TensorFlow 2.0 包含了一個完整的生態系統,包括 TensorFlow Lite(用於移動和嵌入式設備)和用於開發生產機器學習流水線的 TensorFlow Extended(用於部署生產模型)。

Keras 與 TensorFlow 錯綜複雜的關係

圖 1:Keras 與 TensorFlow 有一段極其複雜的歷史,讀完這章,你就可以瞭解到由 Cliff 筆記記錄的它們的愛情故事。你還會知道,在 TensorFlow 2.0 中,你應該使用 tf.keras,而不是單獨的 keras 包。

Keras 和 TensorFlow 之間複雜糾纏的關係就像一對高中情侶的愛情故事,他們約會、分手,但最終找到了一個共處的方式。這個故事很長,有很多細節,有時甚至會有一些矛盾。與其回憶完整的愛情故事,不如來回顧一下 Cliffs 的筆記:

  • Keras 最初是由 Google AI 開發人員/研究人員 Francois Chollet 創建並開發的。

  • Francois 於 2015 年 3 月 27 日將 Keras 的第一個版本 commit 並 release 到他的 GitHub。

  • 一開始,Francois 開發 Keras 是爲了方便他自己的研究和實驗。

  • 但是,隨着深度學習的普及,許多開發人員、程序員和機器學習從業人員都因其易於使用的 API 而涌向 Keras。

當時沒有太多的深度學習庫可用——那時候比較流行的庫是 Torch、Theano 和 Caffe。這些庫的問題是,用這些庫就像在實驗的時候用匯編或者 C++編程一樣——乏味、耗時、效率低下。另一方面,Keras 非常容易使用,這可以讓研究人員和開發人員的實驗迭代更快。

爲了訓練你自己的自定義神經網絡,Keras 需要一個後端。後端是一個計算引擎——它可以構建網絡的圖和拓撲結構,運行優化器,並執行具體的數字運算。要理解後端的概念,可以試想你需要從頭開始構建一個網站。你可以使用 PHP 編程語言和 SQL 數據庫。這個 SQL 數據庫就是是後端。你可以使用 MySQL,PostgreSQL 或者 SQL Server 作爲你的數據庫;但是,用於與數據庫交互的 PHP 代碼是不會變的(當然,前提是使用某種可以封裝數據庫層的 MVC 範例)。從本質上講,PHP 並不關心正在使用哪個數據庫,只要它符合 PHP 的規則即可。

 Keras 也是如此。你可以把後臺看作是你的數據庫,Keras 是你用來訪問數據庫的編程語言。你可以把後端替換成任何你喜歡的後端,只要它遵守某些規則,你的代碼就不需要更改。因此,你可以把 Keras 看作是一組用來簡化深度學習操作的封裝(abstraction)。(注:雖然 Keras 總是啓用快速原型,但它對研究人員來說不夠靈活。這種情況在 TensorFlow 2.0 中有所改變,本文後面將對此進行詳細介紹)

一開始,在 v1.1.0 之前,Keras 的默認後端都是 Theano。與此同時,Google 發佈了 TensorFlow,這是一個用於機器學習和神經網絡訓練的符號數學庫。Keras 開始支持 TensorFlow 作爲後端。漸漸地,TensorFlow 成爲最受歡迎的後端,這也就使得 TensorFlow 從 Keras v1.1.0 發行版開始成爲 Keras 的默認後端。

一般來說,一旦 TensorFlow 成爲了 Keras 的默認後端,TensorFlow 和 Keras 的使用量會一起增長——沒有 TensorFlow 的情況下就無法使用 Keras,所以如果你在系統上安裝了 Keras,那麼你也得安裝 TensorFlow。

 同樣的,TensorFlow 用戶也越來越被高級 Keras API 的簡單易用所吸引。tf.keras 是在 TensorFlow v1.10.0 中引入的,這是將 keras 直接集成到 TensorFlow 包中的第一步。

tf.keras 軟件包與你通過 pip 安裝的 keras 軟件包(即 pip install keras)是分開的,過去是這樣,現在也是。爲了確保兼容性,原始的 keras 包沒有被包含在 tensorflow 中,因此它們的開發都很有序。

然而,這種情況正在改變——當谷歌在 2019 年 6 月發佈 TensorFlow 2.0 時,他們宣佈 Keras 現在是 TensorFlow 的官方高級 API,用於快速簡單的模型設計和訓練。隨着 Keras 2.3.0 的發佈,Francois 聲明:

  • 這是 Keras 首個與 tf.keras 同步的版本;

  • 這也是 Keras 支持多個後端(即 Theano,CNTK 等)的最終版本。

  • 最重要的是,所有深度學習從業人員都應將其代碼轉換成 TensorFlow 2.0 和 tf.keras 軟件包。

  • 原始的 keras 軟件包仍會接收 bug 並修復,但請向前看,你應該開始使用 tf.keras 了。

如你所見,Keras 與 TensorFlow 之間的有着悠久又錯綜複雜的歷史。

但是,對於 Keras 用戶來說,讀完這一部分需要了解到,你應該在未來的項目中開始使用 TensorFlow 2.0 和 tf.keras 了。

在未來的項目中開始使用 tf.keras

圖 2:TensorFlow 2.0 中,Keras 和 tf.keras 有什麼區別呢

2019 年 9 月 17 日,Keras v2.3.0 正式發佈,在這個版本中 Francois Chollet(Keras 的創建者和首席維護者)聲明:

Keras v2.3.0 是 Keras 第一個與 tf.keras 同步的版本,也將是最後一個支持除 TensorFlow 以外的後端(即 Theano,CNTK 等)的主要版本。最重要的是,深度學習從業人員應該開始使用 TensorFlow 2.0 和 tf.keras 軟件包了。

對於大多數項目來說,你只需要改變一下你的 import 部分:

在 import 部分加上 tensorflow 作爲前綴:

如果你使用的是自定義的訓練 loop 或 Sessions,則必須要改動一下代碼才能使用新的 GradientTape 功能,但是總的來說,這個改動相當容易。

爲了幫助你(自動地)將代碼從 keras 更新爲 tf.keras,Google 發佈了一個名爲 tf_upgrade_v2 的腳本。顧名思義,這個腳本可以分析你的代碼並報告需要改動的行,該腳本甚至可以替你完成升級過程。

TensorFlow 2.0 中更多自動更新代碼的信息,請參考此鏈接:https://www.tensorflow.org/guide/upgrade。

Keras 的計算後端

圖 3:Keras 支持哪些計算後端?直接在 TensorFlow 中使用 Keras 對 Keras 來說意味着什麼?

正如我在本文前面提到的,Keras 依賴於計算後端這一概念。在構建模型圖、數值計算等過程裏,計算後端承擔了所有的「重活」。

而 Keras 作爲一個基於這個計算引擎之上的封裝,幫助深度學習的開發人員與實踐者更簡單地實現並訓練他們的模型。

一開始,Keras 將 Theano 作爲它首選的計算後端——然後它又支持了其他的一些後端,包括 CNTK 和 mxnet 等等。

然而,目前最流行的後端是 TensorFlow,而且它也最終成爲了 Keras 的默認計算後端

隨着越來越多的 TensorFlow 用戶開始使用 Keras 的簡易高級 API,越來越多的 TensorFlow 開發人員開始考慮將 Keras 項目納入 TensorFlow 中作爲一個單獨模塊,並將其命名爲 tf.keras。TensorFlow v1.10 是 TensorFlow 第一個在 tf.keras 中包含一個 keras 分支的版本。

現在 TensorFlow 2.0 已發佈,keras 和 tf.keras 已經處於同步狀態,這意味着儘管 keras 和 tf.keras 仍是獨立的兩個項目,但是開發人員應該開始使用 tf.keras,因爲 keras 軟件包僅支持錯誤修復。

正如 Keras 的創建者和維護者 Francois Chollet 所說:

這也是 Keras 支持多個後端的最後一個主要版本。長期來看,我們建議用戶考慮開始將 TensorFlow 2.0 中的 Keras 代碼切換爲 tf.keras。

它實現了與 Keras 2.3.0 相同的 API(因此這個改變應該像更改 Keras 導入語句一樣容易),但是對 TensorFlow 用戶來說,它具有許多優勢,例如對 eager execution、distribution、TPU 訓練的支持,以及通常來說對底層的 TensorFlow 與頂層概念(如「層」和「模型」)之間更好的集成度。

它也會得到更好的維護。

如果你同時是 Keras 和 TensorFlow 用戶,那就該開始考慮將代碼切換到 TensorFlow 2.0 和 tf.keras 了。

TensorFlow 2.0 中的 Sessions 與 Eager Execution

圖 4:Eager excution 是一種更具 Python 風格的動態計算圖處理方式。TensorFlow 2.0 開始支持 eager execution(與 Pytorch 一樣)。你可以在 TensorFlow 2.0 與 tf.keras 中使用 eager execution 與 sessions。

在 tf.keras 使用 Keras API 的 TensorFlow 1.10+用戶應該對在訓練模型時創建一個 Session 很熟悉:

創建一個 Session 對象,並要求提前構建整個模型圖確實有點麻煩,所以 TensorFlow 2.0 引入了 eager execution 的概念,這樣一來代碼被簡化爲:

eager execution 的好處是不需要提前構建整個模型圖了。

相反,運算會被立刻執行(即 eager execution),這也使得模型的構建以及調試變得更容易。

有關 eager execution 的更多細節,以及在 TensorFlow 2.0 中的使用方法,見此鏈接:

https://medium.com/coding-blocks/eager-execution-in-tensorflow-a-more-pythonic-way-of-building-models-e461810618c8

如果你知道 eager execution 與 sessions 的對比,以及它對模型訓練速度的影響,見此鏈接:

https://github.com/sayakpaul/tf - 2.0 - hacks/tree/master/speed%20comparison%20between%20tf%201.x%20and%20tf%202.0。

TensorFlow 2.0 中的自動求導與 GradientTape

圖 5:TensorFlow 2.0 是如何更好地處理自定義層和損失函數的?答案就是自動求導和 GradientTape。(圖源:https://twitter.com/fchollet/status/1158907168721997824)

如果你是個需要自定義網絡層和損失函數的研究人員,那麼你可能不喜歡 TensorFlow 1.x(理應如此)。

至少可以說,TensorFlow 1.x 的自定義實現是很笨拙的——要改進的地方還有很多。

隨着 TensorFlow 2.0 的發佈,情況開始發生變化——現在實現你自己的自定義損失函數要容易得多。其中一種使其變得簡單的方法是使用自動求導和 GradientTape。要利用 GradientTape,我們需要做的就是創建我們的模型架構:

定義我們的損失函數以及優化器:

創建負責執行單個批更新的函數:

然後就可以訓練模型了:

GradientTape 魔法爲我們在後臺進行導數的計算,使處理自定義損失和層變得容易得多。

說到自定義層和模型的實現,請務必閱讀下一節。

TensorFlow 2.0 中的模型和層子類化

TensorFlow 2.0 和 tf.keras 爲我們提供了三種獨立的方法來實現我們自己的自定義模型:

  1. 序列化

  2. 函數化

  3. 子類化

序列化和函數化的示例都已經在 Keras 中存在很長時間了,但是許多深度學習從業者依然不瞭解子類化功能。

下週我將針對這三種方法撰寫專門的教程,但目前來說,先讓我們看一下如何使用 TensorFlow 2.0、tf.keras 與模型子類化功能實現一個基於 LeNet 架構的簡單 CNN。

注意 LeNet 類是如何成爲 Model 的子類的。LeNet 的構造函數(即 init)定義了模型內部的每個單獨層。然後,call 方法實現了前向傳遞,這使得你能夠根據需要自定義前向傳遞的過程。

使用模型子類化的好處是你的模型:

  • 變得更加靈活。

  • 使你能夠實現並使用自定義損失函數。

而且,由於你的網絡架構繼承了 Model 類,因此你仍然可以調用.fit()、. compile()和.evaluate()之類的方法,從而保證了大家熟悉的簡易 Keras API 的使用。

如果你想了解有關 LeNet 的更多信息,可以參考:

https://www.pyimagesearch.com/2016/08/01/lenet-convolutional-neural-network-in-python/ 

TensorFlow 2.0 開始支持更優的多 GPU 與分佈式訓練

圖 6:TensorFlow 2.0 在多 GPU 訓練上是否更好了呢?是的,你只需要一個 MirroredStrategy。(圖源:https://jhui.github.io/2017/03/07 tensorflow - gpu/)

TensorFlow 2.0 和 tf.keras 利用 MirroredStrategy 來提供更好的多 GPU 和分佈式訓練。

如 TensorFlow 2.0 文檔中所說,「MirroredStrategy 支持在一臺機器的多個 GPU 上進行同步、分佈式訓練」。

如果要使用多臺機器(每臺機器可能有多個 GPU),則應使用 MultiWorkerMirroredStrategy。或者,如果你使用 Google 的雲進行訓練,可以試試 TPUStrategy。

不過現在,假設你正在使用一臺具有多個 GPU 的機器,並且想在訓練時同時使用所有 GPU,你可以先創建你的 MirroredStrategy:

然後你需要聲明你的模型架構,並在 strategy 的 scope 內進行編譯:

然後你就可以在那裏調用.fit 來訓練模型了。

基於你有多個 GPU,TensorFlow 會爲你考慮如何使用多 GPU 進行訓練的。

TF2.0 是一個生態系統,它包含了 TF 2.0、TF LITE、TFX、量化和部署

圖 7:TensorFlow 2.0 生態系統中有什麼新特性嗎?我應該用 Keras 還是 tf.keras?

TensorFlow 2.0 不僅僅是一個計算引擎和用於訓練神經網絡的深度學習庫,它還有很多其他功能。

我們可以使用 TensorFlow Lite (TF Lite) 來訓練、優化和量化那些專門爲資源受限的設備(如智能手機和 Raspberry Pi, Google Coral 等其他嵌入式設備)設計的模型。

或者,如果你需要將模型部署到生產環境中,可以使用 TensorFlow Extended (TFX),這是一個用於模型部署的端到端平臺。一旦你的研究和實驗完成,你就可以利用 TFX 爲生產準備模型,並使用谷歌的生態系統擴展你的模型。

有了 TensorFlow 2.0,我們在研究、實驗、模型準備、量化和生產部署之間架起了高效的橋樑。

我真的對 TensorFlow 2.0 的發佈及其對深度學習圈的影響感到非常興奮。

總結

學習完本教程,你應該學到了關於 Keras、tf.keras 和 TensorFlow 2.0 的知識。

第一個要點是,使用 keras 軟件包的深度學習從業人員應該開始在 TensorFlow 2.0 中使用 tf.keras。

你不僅體驗到了 TensorFlow 2.0 帶來的加速和優化,而且還知道了 keras 包的最新版本(v2.3.0)將成爲支持多個後端和特性的最後一個版本。未來,keras 軟件包將只進行 bug 修復。

以後的項目中,你應該認真考慮使用 tf.keras 和 TensorFlow 2.0。

第二個收穫應該是 TensorFlow 2.0 不僅是 GPU 加速的深度學習庫。

你不僅能夠使用 TensorFlow 2.0 和 tf.keras 來訓練自己的模型,還可以:

  • 使用 TensorFlow Lite (TF Lite) 將這些模型部署到移動/嵌入式環境中;

  • 使用 TensorFlow Extended (TF Extended) 將模型部署到生產環境中。

就我自己來說,我已經開始將原始的 keras 代碼更新成 tf.keras 的版本了。我建議你也這麼做。

原文鏈接:https://www.pyimagesearch.com/2019/10/21/keras-vs-tf-keras-whats-the-difference-in-tensorflow-2-0/

文章來源:機器之心