當前位置:
首頁 > 最新 > 一文看懂JeffDean等提出的ENAS到底好在哪?

一文看懂JeffDean等提出的ENAS到底好在哪?

作者|第四範式先知平台架構師 陳迪豪

編輯|Natalie

本文經作者授權發佈於 AI 前線,未經許可不得轉載!

AI 前線導讀:ENAS 全稱為 Efficient Neural Architecture Search,出自谷歌 Jeff Dean 等人在 2018 年發表的論文《Efficient Neural Architecture Search via Parameter Sharing》,可以在一天內自動訓練得到一個比人類設計效果更好的模型。那麼這個看上去很神奇的 ENAS 到底有何奇妙之處?它與最近風頭正盛的 AutoML 有何關係?

本文將循序漸進地介紹業界主流的自動生成神經網路模型的 NAS 演算法,以及目前最為落地的 ENAS 演算法,帶你一探 ENAS 究竟。

更多乾貨內容請關注微信公眾號「AI 前線」,(ID:ai-front)

簡介

隨著機器學習演算法的突破,AutoML 逐漸被業界所熟知並開始落地應用。Google 近期頻頻發布 AutoML 相關的論文,並且在 Google Cloud 平台推出了 AutoML Vision 服務,此服務允許用戶上傳少量標記過的圖片數據即可重新訓練一個專屬的圖像分類模型。在我微博中大概介紹了這項「AutoML」技術,實際上可以通過 Fine-tune 等方式實現,因此拋出本文第一個觀點,AutoML 的定義沒有強制標準,只要能自動訓練出好的模型就是有價值的 AutoML

ENAS 全稱 Efficient Neural Architecture Search,出自 Google 在 2018 年發布的論文《Efficient Neural Architecture Search via Parameter Sharing》(論文鏈接:https://arxiv.org/pdf/1802.03268.pdf ),通過共享模型參數的形式高效實現神經網路模型結構的探索,也就是說可以在一天內自動訓練得到一個比人類設計效果更好的模型。ENAS 使用了強化學習、動態構建計算圖等技術,從宏觀角度看是一種搜索演算法,產出是一個精心挑選的 NN 模型,因此這是一種很符合期望的 AutoML,除此之外要實現完整的「自動 (Auto) 機器學習 (ML)」還需要有自動特徵抽取、自動超參調優等技術支持,但暫時不在本文的討論範圍。

對於 ENAS 的介紹,大家可能已經看過媒體界吹捧的《谷歌大腦發布神經架構搜索新方法:提速 1000 倍》、《Jeff Dean 等人提出 ENAS:通過參數共享實現高效的神經架構搜索》等文章。這裡拋出本文第二個觀點,看媒體翻譯的技術文章沒有用,想學習技術可以看論文原文或者本文。在介紹 ENAS 演算法實現細節之前,希望可以循序漸進地介紹一些前置的基礎知識理解。

NAS 的原理

NAS 也就是 Neural Architecture Search,目標是從一堆神經網路組件中,搜索到一個好的神經網路模型。我們知道神經網路模型是一種可任意堆砌的模型結構,基礎的組件包括 FC(全連接層)、Convolution(卷積層)、Polling(池化層)、Activation(激活函數)等,後一個組件可以以前一個組件作為輸入,不同的組件連接方式和超參配置方式在不同應用場景有不同的效果,例如下面就是在圖像分類場景非常有效的 Inception 模型結構。

圖內結構比較複雜不理解也沒關係,我們只需要知道這個神經網路結構是由圖像領域專家花費大量精力設計出來的,並且經過了巨量的實驗和測試才能(在不能解釋深度學習原理的情況下)確定這個網路結構。

那麼計算機是否可以自己去學習和生成這個複雜的網路結構呢?目前是不行的,包括各種 NAS 演算法的變形還有 ENAS 演算法暫時也無法生成這樣的網路結構,這裡拋出本文第三個觀點,絕大部分機器學習都不是人工智慧,計算機不會無緣無故獲得既定目標以外的能力。因此,計算機並不是自己學會編程或者建模,我們還沒有設計出自動建模的數據集和演算法,所謂的「AI 設計神經網路模型」,其實只是在給定的搜索空間中查找效果最優的模型結構。

例如我們假設模型必須是一個三層的全連接神經網路(一個輸入層、一個隱層、一個輸出層),隱層可以有不同的激活函數和節點個數,假設激活函數必須是 relu 或 sigmoid 中的一種,而隱節點數必須是 10、20、30 中的一個,那麼我們稱這個網路結構的搜索空間就是 * 。在搜索空間中可以組合出 6 種可能的模型結構,在可枚舉的搜索空間內我們可以分別實現這 6 種可能的模型結構,最終目標是產出效果最優的模型,那麼我們可以分別訓練這 6 個模型並以 AUC、正確率等指標來評價模型,然後返回或者叫生成一個最優的神經網路模型結構。

因此,NAS 演算法是一種給定模型結構搜索空間的搜索演算法,當然這個搜索空間不可能只有幾個參數組合,在 ENAS 的示例搜索空間大概就有 1.6*10^29 種可選結構,而搜索演算法也不可能通過枚舉模型結構分別訓練來解決,而需要一種更有效的啟發式的搜索演算法,這種演算法就是後面會提到的貝葉斯優化、增強學習、進化演算法等。

使用超參自動調優

前面提到 NAS 是一種搜索演算法,是從超大規模的搜索空間找到一個模型效果很好的模型結構,這類問題我們也可以看作一個優化問題,也就是從搜索空間中找到另一個模型效果更優的模型結構。而神經網路模型的結構和效果並不是線性關係的,也沒有一個函數可以描述這種關係,如果存在這樣的函數我們就可以通過求導、SGD 等方法用數學的方式找到最優解了,因此這可以看作一類黑盒優化(Black-box optimization)問題,或者是多臂老虎機(Multi-armed bandit)問題,對於黑盒優化問題的解法可以參考專欄另一篇文章《貝葉斯優化: 一種更好的超參數調優方式》(https://zhuanlan.zhihu.com/p/29779000) 。

回到 NAS 的場景,我們需要定義一個搜索空間來讓演算法選擇更優的網路結構,而這個搜索空間無外乎就是網路層個數、網路層的類型、網路層的激活函數類型、網路層是否加 Dropout、網路層是否加 Batch normalization,還有就是諸如卷積層的 filter size、strip、padding 和池化層的 polling type、kernel size 等等,這些我們都可以認為是神經網路的超參數。

如果你使用過我開源的 tensorflow_tempalate_application 應該就理解,為什麼是 template application?因為我們可以通過傳入的參數 --model=來選擇更好的模型結構,也可以通過參數 --optimizer=來選擇更好的優化演算法等等,這裡不再細說,感興趣可以在 Github 上了解下:

https://github.com/tobegit3hub/tensorflow_template_application

實際上,NAS 可以是一個普通的超參調優問題,也可以是一個針對模型結構場景的調優問題。例如 Google 開源的 NASnet 模型和 ENAS 演算法就是在通用的超參調優上更進一步,當然並不是說後者的方法更優更先進,而是有些問題是超參不好描述的,例如用超參來表達每一層的輸入是前面的哪一層,這裡不妨推薦一篇文章介紹基於 Policy gradient 的 NAS 經典實現:

https://lab.wallarm.com/the-first-step-by-step-guide-for-implementing-neural-architecture-search-with-reinforcement-99ade71b3d28

對於可以用超參輕易描述並且實現的模型結構,實現 NAS 並沒有那麼難,我們不需要自己去實現類似 Policy gradient 的啟發式調優演算法(後面會詳細介紹到),可以使用一些已有的超參調優庫,只要自己實現機器學習模型的訓練過程和返回最終的指標結果即可。

因此我嘗試在 Google Vizier 的開源實現 Advisor 上使用 NAS 的功能,發現不到一百行代碼就可以實現完整的自動生成網路結構功能,而且不需要服務端做任何修改,我們用幾十行 Keras 代碼或者是 TensorFlow 等任意的框架都可以使用,只需要提前描述好超參的搜索空間即可,示例代碼我也提交到 Github 上了。

Github 鏈接:

https://github.com/tobegit3hub/advisor/tree/master/examples/keras

NAS 的優化演算法

前面提到 NAS 演算法是一種搜索演算法,除了需要定義好搜索空間外,還需要有一種啟發式的可以收斂的調優演算法實現。因為一般生成網路模型的搜索空間都很大,如果搜索空間不大就可以暴力枚舉了,而且生成一個模型要評估好壞就需要訓練,這個成本也是非常大了。

這時我們想到的調優演算法就是貝葉斯優化(Bayesian optimization)、粒子群優化(Particle swarm optimization)、Policy gradient、DQN 等等,這些演算法都可以用於 NAS 內部的模型的優化。是的,NAS 內部也有一個模型,一般在論文或者代碼中稱為 controller 模型,又它來控制想要生成的神經網路模型的結構,而生成的神經網路模型會根據客戶的使用場景(例如圖像分類)來返回模型效果對應的指標,這個一般稱為 child 模型。

前面介紹了基於 Advisor 來實現的 NAS,其實就是使用了 Advisor 內置的調優模型作為 NAS 的 controller 模型,默認就是貝葉斯優化,而且只需要修改一個參數就可以通過統一的介面來使用後端已經支持的 Random search、Grid search 等調優演算法。

前面推薦的博客使用的是增強學習中的 Policy gradient 演算法,包括後面提到的 ENAS 論文也是使用這個演算法,而在 Google 的其他論文中有介紹使用 Evolution algorithm 和 DQN 的,AlphaZero 在超參調優中使用的是貝葉斯優化,而 Deepmind 最新的調參論文介紹了類似 PSO 的群體優化演算法。

大家需要理解這些演算法從本質上沒有區別,都是黑盒優化演算法,因為假設不知道優化的目標和優化的參數是否有函數關係並且不能從中獲取梯度等信息,只能從歷史的模型訓練結果中根據超參組合還有最後模型效果來選擇超參的變化值。而這些演算法的區別在於運行效率和演算法複雜度上,因此也會應用到不同的領域上

我們經常看到下圍棋、打遊戲的人喜歡用 DQN、A3C 演算法來優化模型,是因為下棋和打遊戲都是可以通過軟體模擬操作並且可以快速收到 reward 的,例如一分鐘收集到幾十萬的 state 和 reward 完全足夠訓練一個高度複雜的 AlphaZero 模型(基於 ResNet)。而 AlphaZero 的超參調優卻使用基於高斯過程的貝葉斯優化,是因為調整超參需要重新訓練模型代價很大,大概幾小時才能得到一個 state 和 reward,這不足以訓練一個比 ResNet 弱很多的神經網路模型,但可以通過在數學上假設所有超參之間符合聯合高斯分布然後通過高斯過程求 state、reward 關聯關係的均值和方差,然後基於 exploration/exploitation 原則選擇下一個更優的探索點,這也就是貝葉斯優化的實現原理了。這其實也解釋了為什麼 Google 以前基於 DQN、進化演算法的 NAS 模型需要幾百塊 GPU 並發訓練多個月,因為評估一個模型結構是好是壞真的很耗時,這也是為什麼 ENAS 解決評估模型這個問題後這麼 Efficient,後面會有詳細的介紹。

下面有一個更直觀的圖介紹為什麼貝葉斯優化在數學上會比瞎猜(Random search 演算法)更好。首先紅色的點表示已經探索過超參數,這裡只有一個超參數 X 需要調整,Y 軸表示選擇這個超參數 X 後模型的效果,可以認為 Y 就是模型正確率也就是越大越好,藍線真實的超參 X 與正確率 Y 的對應關係,因為我們不可能遍歷所有 X 因此藍線我們是未知的,而我們的目標是已知幾個紅點去找到藍線中的最高點。其中上圖有一條虛線和淺藍色區域,那就是貝葉斯優化中高斯過程返回的均值和方差,這個均值和方差是在 X 取值範圍內都有的,分別代表了這個 X 點期望的正確率是多少和這個 X 點可能浮動的空間。

如果仔細觀察可以發現,紅點必然會在虛線上,因為這個點是已經探索過的,也就是用這個 X 去訓練模型已經得到了正確率,因此這個點也必然在藍線上。而淺藍色區域代表了這一塊可能浮動的空間,因此淺藍色區域里虛線越大表示這塊越值得 exploration,可能發現新的高點也不一定,而虛線越高表示對這塊期望的 Y 值也越大,也是越值得 exploitation。為了權衡 exploration 和 exploitation 因此有了下面的 Utility function,這也是一種演算法。我們可以簡單認為它就是用均值加上λ倍的方差得到的曲線,然後取最高值作為下一個探索點,因為這個探索點代表了這個 X 位置期望的 Y 值還有想要探索更多未知的可能性,如果覺得比較難理解建議先參考《貝葉斯優化:一種更好的超參數調優方式》(https://zhuanlan.zhihu.com/p/29779000 )。

ENAS 的實現

前面一直介紹的是 NAS,為了讓大家了解 NAS 只是一種搜索演算法。NAS 沒有學會建模也不能替代演算法科學家設計出 Inception 這樣複雜的神經網路結構,但它可以用啟發式的演算法來進行大量計算,只要人類給出網路結構的搜索空間,它就可以比人更快更准地找到效果好的模型結構。

ENAS 也是一種 NAS 實現,因此也是需要人類先給出基本的網路結構搜索空間,這也是目前 ENAS 的一種限制(論文中並沒有提哦)。ENAS 需要人類給出生成的網路模型的節點數,我們也可以理解為層數,也就是說人類讓 ENAS 設計一個複雜的神經網路結構,但如果人類說只有 10 層那 ENAS 是不可能產出一個超過 10 層網路結構,更加不可能憑空產生一個 ResNet 或者 Inception。當然我們是可以設計這個節點數為 10000 或者 1000000,這樣生成的網路結構也會複雜很多。那為什麼要有這個限制呢?這個原因就在於 ENAS 中的 E(Efficient)。

大家大概了解過 ENAS 為什麼比其他 NAS 高效,因為做了權值共享 (Parameter sharing),這裡的權值共享是什麼意思呢?是大家理解的模型權重共享了嗎,但 ENAS 會產生和嘗試各種不同的模型結構,模型都不一樣的權重還能共享嗎?實際上這裡我把 Parameter sharing 翻譯成權值共享就代表則這個 Parameter 就是模型權重的意思,而不同模型結構怎樣共享參數,就是 ENAS 的關鍵。ENAS 定義了節點(Node)的概念,這個節點和神經網路中的層(Layer)類似,但因為 Layer 肯定是附著在前一個 Layer 的後面,而 Node 是可以任意替換前置輸入的。

下面有一個較為直觀的圖,對於普通的神經網路,我們一般每一層都會接前一層的輸入作為輸出,當然我們也可以定義一些分支不一定是一條線的組合關係,而 ENAS 的每一個 Node 都會一個 pre-node index 屬性,在這個圖裡 Node1 指向了 Node0,Node2 也指向了 Node0,Node3 指向了 Node1。

事實上,ENAS 要學習和挑選的就是 Node 之間的連線關係,通過不同的連線就會產生大量的神經網路模型結構,從中選擇最優的連線相當於「設計」了新的神經網路模型。如果大家理解了可能覺得這種生成神經網路的結構有點 low,因為生成的網路結構樣式比較相似,而且節點數必須是固定的,甚至很難在其中創造出 1x1 polling 這樣的新型結構。是的,這些吐槽都是對的,目前 ENAS 可以做的就是幫你把連線改一下然後生成一個新的模型,但這個就是 ENAS 共享權重的基礎,而且可以以極低的代碼量幫你調整模型結構生成一個更好的模型,接下來就是本文最核心的 ENAS 的 E(Efficient)的實現原理介紹了。

我們知道,TensorFlow 表示了 Tensor 數據的流向,而流向的藍圖就是用戶用 Python 代碼定義的計算圖(Graph),如果我們要實現上圖中所有 Layer 連成一條直線的模型,我們就需要在代碼中指定多個 Layer,然後以此把輸入和輸出連接起來,這樣就可以訓練一個模型的權重了。當我們把上圖中所有 Layer 連成一條直線的模型改成右邊交叉連線的模型,顯然兩者是不同的 Graph,而前一個導出模型權重的 checkpoint 是無法導入到後一個模型中的。但直觀上看這幾個節點位置本沒有變,如果輸入和輸出的 Tensor 的 shape 不變,這些節點的權重個數是一樣的,也就是說左邊 Node0、Node1、Node2、Node3 的權重是可以完全複製到右邊對應的節點的。

這也就是 ENAS 實現權重共享的原理,首先會定義數量固定的 Node,然後通過一組參數去控制每個節點連接的前置節點索引,這組參數就是我們最終要挑選出來的,因為有了它就可以表示一個固定神經網路結構,只要用前面提到的優化演算法如貝葉斯優化、DQN 來調優選擇最好的這組參數就可以了。

那評估模型也是先生成多組參數,然後用新的網路結構來訓練模型得到 AUC 等指標嗎?答案是否定的,如果是這樣那就和普通的 NAS 演算法沒什麼區別了。因為訓練模型後評估就是非常不 Efficient 的操作,這裡評估模型是指各組模型用相同的一組權重,各自在未被訓練的驗證集中做一次 Inference,最終選擇 AUC 或者正確率最好的模型結構,其實也就是選擇節點的連線方式或者是表示連線方式的一組參數。

稍微總結一下,因為 ENAS 生成的所有模型節點數是一樣的,而且節點的輸入和輸出都是一樣的,因此所有模型的所有節點的所有權重都是可以載入來使用的,因此我們只需要訓練一次模型得到權重後,讓各個模型都去驗證集做一個預估,只要效果好的說明發現了更好的模型了。實際上這個過程會進行很多次,而這組共享的權重也會在一段時間後更新,例如我找到一個更好的模型結構了,就可以用這個介面來訓練更新權重,然後看有沒有其他模型結構在使用這組權重後能在驗證機有更好的表現。

回到前面 TensorFlow 實現 ENAS 的問題,我們知道 TensorFlow 要求開發者先定義 Graph,然後再載入權重來運行,但定義 Graph 的過程與模型訓練過程是分開的,而 ENAS 要求我們在模型訓練過程中不斷調整 Graph 的結構來嘗試更好的 Graph 模型結構。這在聲明式(Declarative)編程介面的 TensorFlow 上其實不好實現,而命令式(Imperative)編程介面的 PyTorch 上反而更好實現。當然這裡可以為 TensorFlow 正名,因為 ENAS 的作者就提供了基於 TensorFlow 的 ENAS 源碼實現,開源地址 https://github.com/melodyguan/enas 。我們也深入看了下代碼,作者用了大量 tf.case()、tf.while() 這樣的介面,其實是在 TensorFlow 的 Graph 中根據參數來生成最終訓練的 child 模型的 Graph,因此沒有用 Python 代碼定義所有 child 模型的 Graph 的集合,也不需要每次都重新構建 Graph 來影響模型訓練的性能。

除了 Node 之間的連線外,ENAS 論文裡面可以訓練的超參數還包括上圖中的激活函數,也是通過 controller 模型輸出的一組參數來決定每個 Node 使用的激活函數,而這些激活函數不需要重新訓練,只需要直接載入共享權重然後做一次 Inference 來參與模型評估即可。

很多人可能覺得目前共享的權重比較簡單,只能實現矩陣乘法和加法,也就是全連接層的作用,但在圖像方面會用到更多的卷積網路,也會有 filter size、polling kernel size 等參數需要選擇。實際上 ENAS 已經考慮這點了,這些 Node 擁有的權重以及使用權重的方法被稱為 Cell,目前已經提供乘法和卷積這兩種 Cell,並且在 PTB 和 Cifar10 數據集上做過驗證,當然未來還可以加入 RNN 等 Cell,甚至多種 Cell 一起混用,當然這個在實現上例如前置節點的連線上需要有更複雜的判斷和實現。

對於 ENAS 的 controller 模型的參數調優,論文中使用的是增強學習中的 Policy gradient,當然正如前面所提到的,使用貝葉斯優化、DQN、進化演算法也是沒問題的。不過目前 ENAS 的 controller 模型和共享權重的實現放在了一起,因此要拓展新的 controller 提優演算法比較困難,未來我們希望把更多的調優演算法集成到 Advisor 中(目前已經支持 Bayesian optimization、Random search、Grid search,正在計劃支持 Policy gradient、DQN、Evolution algorithm、Particle swarm optimization 等),讓 ENAS 和其他 NAS 演算法也可以更簡單地使用已經實現的這些調優演算法。

總體而言,ENAS 給我們自動超參調優、自動生成神經網路結構提供了全新的思路。通過權值共享的方式讓所有生成的模型都不需要重新訓練了,只需要做一次 Inference 就可以獲得大量的 state 和 reward,為後面的調優演算法提供了大量真實的訓練樣本和優化數據。這是一種成本非常低的調優嘗試,雖然不一定能找到更優的模型結構,但在這麼大的搜索空間中可以快速驗證新的模型結構和調優生成模型結構的演算法,至少在已經驗證過的 PTB 和 CIFAR-10 數據集上有了巨大的突破。

當然也不能忽略 ENAS 本身存在的缺陷(這也是未來優化 ENAS 考慮的方向)。首先是為了共享權重必須要求 Node 數量一致會限制生成模型的多樣性;其次目前只考慮記錄前一個 Node 的 index,後面可以考慮連接多個 Node 製造更大的搜索空間和更複雜的模型結構;第三是目前會使用某一個模型訓練的權重來讓所有模型復用進行評估,對其他模型不一定公平也可能導致找不到比當前訓練的模型效果更好的了;最後是目前基於 Inference 的評估可以調優的參數必須能體現到 Inference 過程中,例如 Learning rate、dropout 這些超參就無法調優和選擇了。

總結

最後總結下,本文介紹了業界主流的自動生成神經網路模型的 NAS 演算法以及目前最為落地的 ENAS 演算法介紹。在整理本文的時候,發現 NAS 其實原理很簡單,在一定空間內搜索這個大家都很好理解,但要解決這個問題在優化上使用了貝葉斯優化、增強學習等黑盒優化演算法、在樣本生成上使用了權值共享、多模型 Inference 的方式、在編碼實現用了編寫一個 Graph 來動態生成 Graph 的高級技巧,所以要讀好一篇 Paper 需要有一對懂得欣賞的眼睛和無死角深挖的決心

本文致謝 Hieu Pham、Melody Y Guan、Barret Zoph、Quoc V Le、Jeff Dean。

作者介紹

陳迪豪,第四範式先知平台架構師,曾在小米科技和 UnitedStack 擔任基礎架構研發工程師。活躍於 OpenStack、Kubernetes、TensorFlow 等開源社區,實現了 Cloud Machine Learning 雲深度學習平台,Github 賬號 https://github.com/tobegit3hub。

今日薦文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 AI前線 的精彩文章:

TensorFlow、Keras、CNTK……到底哪種深度學習框架更好用?
如何成為一名厲害的數據科學家?

TAG:AI前線 |