淘新聞

Keras 之父講解 Keras:幾行代碼就能在分散式環境訓練模型 | Google I/O 2017

雷鋒網按:在上周的谷歌開發者大會 I/O 2017 的講座中,Keras 之父 Francois Chollet 被請出來向全世界的機器學習開發者進行一場對 Keras 的綜合介紹以及實戰示例。說起來,這個子小小的男人不但是暢銷書 《Deep learning with Python》的作者,更在 Kaggle 的資料科學家中世界排名第 17 位(最高),堪稱是青年 AI 工程師中的翹楚。也因此,在開發出 Keras 之後被穀歌挖走為 TensorFlow 背書。

作為號稱是 TensorFlow 最好用、對新手最友好的 API,一起來看看它的神通在哪裡。

Francois Chollet:

對許多使用場景而言,canned estimator 是相當不錯的選擇。但如果你要做的事並沒有現成的 canned estimator,怎麼辦?如果需要寫自己的定制模型呢?這時,就到了 Keras API 派上用場的時候。

什麼是 Keras API?

簡而言之,它就是一個用於創建 TensorFlow 模型的高級 API,你可以與它一起使用 estimator class 以及 experiment class。

眾所周知,TensorFlow 的特點是非常低級的程式設計介面,你大多數時間花在矩陣、向量乘法上。這使它成為一件非常強力的深度學習工具。但對於創建十分複雜先進的模型,這種操作方式說不上“理想”。

在穀歌,我們相信,未來深度學習將存在于每一個普通 IT 開發者的工具箱中,不再局限于機器學習專家。原因很簡單:每個開發者都需要做出更智慧的應用。

為了讓這成為現實,我們需要降低深度學習的使用門檻,搞出每一個人都能用的工具,而不應該只有專家才能用深度學習解決問題。

我有一個問題想讓大家思考:

如果設計一個沒有任何束縛限制的深度學習介面,它應該是什麼樣的?

深度學習的核心理念很容易理解,它的實現也不應該複雜。對於模型核心部件,與其從頭實現所有功能,應該讓開發者利用現存部件,快速搭建資料處理流水線;就像樂高積木那樣。這正是我們設計 Keras 的理念——成為“深度學習的樂高”。

Keras 能做什麼?

下面,我來講講 Keras 都能做什麼。

首先,我不建議把 Keras 看做是 codebase、框架或庫,它只是個高級 API。它有不同的實現,最主要的當然是 TensorFlow,但還有基於其它平臺的——目前有 Theano、MXnet 和 Java;對更多框架的支持正在路上。

有一個特點,是 Keras 區別於其他所有深度學習操作介面的地方,讓它鶴立雞群——那就是用戶體驗。

說白了,Keras 的精髓就是它對用戶體驗的執著,讓開發者用著更舒服、簡化工作流。尤其在於提供易於使用的元件、符合直覺的推理、更好的報錯方面。因而,Keras 降低了操作難度,降低使用者的認知負擔。

當然,讓深度學習變得更簡單,同時意味著更多的人能上手。Keras 的終極目標,是讓盡可能更多人接觸、使用深度學習。

直到現在,Keras API 的 TensorFlow 實現,是以外部開源資源庫的形式存在的。但現在,我們把 Keras API 直接整合入 TensorFlow 專案中,這樣能與你的已有工作流無縫結合。至此,Keras 成為了 TensorFlow 內部的一個新模組:tf.keras,它包含完整的 Keras API。

“對於 TensorFlow 用戶,這意味著你獲得了一整套易於使用的深度學習元件,並能與你的工作流無縫整合。

對於 Keras 用戶,這意味著一系列高級 TensorFlow 訓練功能,比如分散式訓練、分散式超參數優化。”

下面,我們一起來看看你的工作流會是什麼樣子。我會向大家展示一個簡單但挺先進的例子。該例子中,我用 Keras API 定義模型,用 TensorFlow estimator 和 experiments 在分散式環境訓練模型。

示例: 視頻內容問答

這是一個視頻問答問題。我們有一組 10 秒短視頻組成的資料集,視頻內容是人從事各種活動。一個深度學習模型將會觀察這些視頻的每一幀畫面,進行理解,然後你可以用簡短的自然語言問它視頻內容。

本例子中,一個男人把紙板箱放進車的行李箱裡。任務是回答這個人在做什麼。模型會處理該視頻和問題,試圖在可能的答案中挑選出正確的那一個。這次,它的回答是“裝貨”。這個答案很有意思:如果僅僅看一幀畫面,是得不出該結論的——這個人也有可能在卸貨。所以,我們不僅要求模型能理解視頻畫面的內容,還要能理解每一幀畫面的先後順序。

放到三四年前,Keras 和 TensorFlow 誕生之前,這會是一個無比棘手的難題,全世界只有個位數的研究機構能處理。即便是一隻由世界級專家學者、工程師組成的團隊,也需要半年左右的時間來一點一點解決。而現在,所有具備基礎 Python 程式設計技能的人都能借助工具處理該問題。我們這也是在使深度學習民主化。

下圖便是我們的神經網路方案。它的結構可分為三個部分:

首先,一個分支會導入視頻輸入,把它轉化為對視頻內容編碼的向量。另一個分支導入問題,也把它轉化為向量。現在,你可以把視頻向量和問題向量連結起來,在它們之上添加一個分類器。該分類器的任務,是從一堆潛在回答中,選出正確的那一個。

第一步,是把視頻輸入向量轉化為張量。一個視頻只是一組連續的畫面幀,每一幀都是一個圖像。對於影像處理,你要做的全部的事,就是運行一個 CNN。

每個 CNN,會從每幀畫面提取一個向量表示。最後所得到的,是對每幀畫面進行編碼的向量序列。當遇到一個序列,你會做什麼?當然是用序列處理模組—— LSTM 把它跑一遍。LSTM 會把序列簡化為一個單一向量,該向量編碼了視頻的所有資訊,包括每一幀畫面、以及它們的順序。

下一步,使用類似的過程來處理問句。它是一個由詞語組成的序列,需要用內嵌模組把每個詞語映射為一個詞向量。你就獲得了一個詞向量序列,再用另一個 LSTM 層來簡化。

當視頻、問題的向量表示都有了以後,就可以把它們連接起來,在上面添加一個用於選擇正確答案的分類器。

這就是深度學習的魔力:把複雜的輸入,比如視頻、圖像、語言、聲音變成向量,變成幾何空間中的不同的點——把了資訊變成了幾何空間中的點,這就是深度學習的本質。

而當完成之後,你就可以用線性代數來處理幾何空間,捕捉到到有趣的映射模式。在上面的例子中,該模型就是在學習一個視頻、問題空間到答案空間的映射。而執行的方式,是把不同的資訊處理模組組合起來。這是一個十分自然的操作:物件是圖像,就用影像處理模組 CNN;物件是序列,就用序列處理模組 LSTM;如果需要從一組候選中選擇一個,就用分類器。

因而,創建深度學習模型,在概念上和拼樂高積木是很相似的,前者的實現也應該這麼簡單。這張圖,就是對我們的模型在 Keras 上的直觀結構。

我們用一個按時間分佈的層,把 CNN 應用於由輸入視頻和張量組成的時間軸上的每一幀畫面。然後把輸入導入 LSTM 層,前者被簡化為單一張量。InceptionV3 CNN 會內置預訓練的權重,這一點很重要,因為以目前的視頻輸入,靠我們自己是無法學習到有趣的視覺特徵的。我們需要利用現有的、在大型資料集上學習到的視覺特徵。這個例子裡是 ImageNet。在深度學習裡,這是一個常見的舉措,而 Keras 使它變得更方便。問題的編碼更加簡單。把詞語序列導入內嵌層(embedding layer),生成向量序列,再用 LSTM 層簡化為單一向量。

代碼演示

下面是視頻編碼機器人的完整代碼,加起來只有幾行,非常簡潔。你從確認視頻輸入開始,高亮部分就是你的視頻輸入:

這是一個由合理幀陣列成的序列。“None”就是幀數,它沒有被定義,你可以不同的 batch 進行修改。每一幀畫面的解析度是 150*150。下一步,僅用一行我們就定義了整個 InceptionV3 模型。它裝滿了從 ImageNet 得到的預訓練權重。所有這些已經內置於 Keras 中,你不需要做任何多餘操作,僅此一行代碼足矣。代碼並不包含頂層,因為並不相關,但在頂部加入了 pooling,使得我們能從每一幀抓取一個向量。

下一步,CNN 被設置為不可訓練,意味它的參數表示並不會在訓練中更新。這一步很重要,因為該 CNN 已經有了非常不錯的表示,沒必要更改。再強調一遍,這是深度學習的常用操作,把封住不再改動的預訓練模型添加入流水線。在 Keras 中,這項操作變得十分簡便。有了不再變動的 CNN 之後,我們用一個時間分配層(time distributed layer),把它在視頻輸入的時間軸上均衡分配。這樣做的結果,是得到所有幀的張量,再導入 LSTM 層得到單一向量。

如上圖,問題處理就更加簡單。最終的問題輸入,被處理為整數序列。為什麼是整數呢?每一個整數,都會用某些詞彙映射到一個向量。隨後把整數序列導入嵌入層,這會把每個整數映射到一個向量上。這些訓練過的嵌入是模型的一部分。再把向量序列導入 LSTM,簡化為單一向量。

這裡有一個有意思的地方。通常使用 LSTM 的時候,有許多東西需要考慮、許多套路需要參考。但在這裡,除了設置輸入單位的數量,我們並沒有做任何其他操作配置 LSTM 層——所有“最佳套路”,都已經成為 Keras 的默認設置。這是 Keras 的一大特點,已知的最佳方案被用於默認設置。對於開發者,這意味著模型直接就能用,不需要對所有參數都進行調參。

在完成對視頻、問題的編碼之後,你只需要用 concate up 把它們轉化為單一向量,然後在頂端加入兩個密集層,它們會從備選詞彙中選出一個作為答案。

下一步,使用輸入和輸出初始化 Keras 模型,本質上它是一個神經網路各層的圖(a graph of layers)的容器。然後要確定訓練設置,比如優化器、Adam 優化器和損失函數。到現在一切都很簡單,我們已經定義了模型和訓練設置。下面是在分散式環境訓練模型,或許在 Cloud ML 上。

只用幾行代碼,你就可以用 TensorFlow Estimator 和 Experiment 類訓練模型。所有需要你做的事,僅僅是寫 experiment 函數,用內置的 get_estimator 方法在其中定義模型,並用模型來初始化 Estimator。有了 estimator 之後,再用它創建 Experiment,在其中你確認輸入資料。

僅僅用幾行非常直觀、具有高度可讀性的 Python 代碼就可以實現,我們就定義了一個相當先進的模型、在分散式環境訓練它,來解決視頻問答難題。而這在幾年前是完全難以想像的。

到這裡,你應該已經看到,像 Keras 這樣的 API 是如何推動 AI 民主化。這借助兩個東西實現:

其中一個,當然是 Keras API。為在 TensorFlow 中定義模型提供了易於使用、功能強大的工具。而且,每一層都有非常優秀的預設設置,讓模型可以直接運行。

另外一個,則是全新的高級 TensorFlow 訓練 API:Estimator 和 Experiment。

把它們結合到一起,使得開發者們能夠以相當小的時間、經歷代價處理任何深度學習難題。

雷鋒網注:感興趣的童鞋可翻牆到

Youtube

觀看完整視頻,雷鋒網編譯。