雷鋒網按:在上周的谷歌開發者大會 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 民主化。這藉助兩個東西實現:
把它們結合到一起,使得開發者們能夠以相當小的時間、經歷代價處理任何深度學習難題。
雷鋒網註:感興趣的童鞋可翻牆到 Youtube 觀看完整視頻,雷鋒網(公眾號:雷鋒網)編譯。
相關文章:
李飛飛:我把今天AI所處的發展階段稱為「AI in vivo」 | Google I/O 2017
六大亮點解讀:計算機視覺技術無處不在 | Google I/O 2017
深度學習庫 Keras 2 重磅發布,與 TensorFlow 聯繫更緊密
雷鋒網版權文章,未經授權禁止轉載。詳情見轉載須知。