如何在Hadoop 2.0上實現深度學習?

梧桐發表於2015-03-09

位於波士頓的資料科學團隊正在利用前沿的工具和演算法,通過對使用者資料的分析來優化業務行為。 資料科學很大程度上依賴機器演算法,它能幫助我們發現資料的特徵。要想洞察網際網路般規模的資料還是很有挑戰的,因此能夠大規模的執行演算法成為了我們的關鍵需求。隨著資料的爆炸性增長,以及隨之而來的上千節點叢集,我們需要將演算法的執行適配到分散式環境。在通用的分散式計算環境中執行機器學習演算法,這本身有它自己的挑戰。

下面我們就將一起探討如何將深度學習(最前沿的機器學習框架)部署到Hadoop的叢集中。還將提供如何對演算法進行修改以便適應分散式環境。同時還將展示在標準資料集下的執行結果。

深度信念網

深度信念網(DBN)是一種圖模型,可以通過對受限玻爾茲曼機(RBM)以貪婪和無監督的方式進行疊加和訓練獲得。採用對被觀察的x向量和第I隱層的接點進行建模的方式,我們可以訓練DBN來提取訓練資料的深度層級表示, 這裡每個隱層的分佈基於它緊鄰的上一層的條件。

可以從下圖中觀察輸入層和隱層的關係。從總體上看,第一層被訓練成RBM,它為x的原始輸入建模。一個輸入是指代表一組未分類資料的稀疏二進位制向量,比如一個數字的二進位制影象。接下來的層採用變換後的資料(sample or mean activations)進行訓練,這些資料來自於上一層。層的數量可以基於經驗來選取以便獲得最好的模型效果,而且DBN也支援任意數量的層。

下面的程式碼段展示了進入RBM的訓練。對於RBM的輸入資料,這裡有多次預定義的迭代(epochs). 輸入資料被分成小的批次,並計算出每一層的權重(weight),啟用值(activations)和增量(deltas)。

每一層的訓練都完成後,深度網路的引數都採用受監督的訓練標準進行了調優。舉例來說,受監督的標準(criterion), 可以分解為一個分類問題,然後可以用深度網路來解決分類問題。也可以使用更復雜的受監督標準,通過它我們可以獲得諸如場景解析的有趣結果,比如可以解釋圖片上出現了那些物件。

Infrastructure

深度學習獲得的廣泛關注,不僅因為它能提供優於其他學習演算法的結果,還因為它能執行在一個分散式環境從而能處理大規模的資料。深度網路主要從兩個級別來並行化 – 層級和資料級。對於層級的並行化實現,大多數採用GPU陣列來平行計算層啟用值並對它們進行頻繁的同步。然而這種方式對於叢集環境不合適,因為當資料分散在多個通過網路連線節點時,會產生較高的網路開銷。資料並行化是指通過將資料拆分來進行並行訓練,分散式環境更適合採用這種方式。Paypal的大部分資料存放在hadoop叢集裡,因此我們的首要需求是能夠在叢集裡執行演算法。對叢集的針對性維護和支援也是我們要考慮的因素。鑑於深度學習天生就繼承了迭代性,MapReduce模式可能不太適合執行這些演算法。然而Hadoop 2.0 和 基於Yarn的資源管理出現後,我們就可以寫出迭代式應用,因為我們可以很好的控制應用佔用的資源。我們使用了IterativeReduce, 它是一個在Hadoop YARN裡寫迭代式演算法的一個簡單抽象,然後我們就能把它部署到某個執行Hadoop 2.4.1的Paypal叢集裡。

方法論

我們實現了Hinton的核心深度學習演算法。這是因為考慮到我們需要把演算法分佈到多個機器中去。對於多臺機器的演算法分佈過程,我們採用了Grazia推薦的手冊。下面是對我們實現的一個大概總結:

  1. 主節點初始化RBM權重。
  2. 主節點把權重和分配推送到工作節點
  3. 工作節點對一個資料段進行RBM訓練,也就是執行完整個分片,將更新後的權重返回給主節點
  4. 主節點針對某個資料段把所有工作接點的權重進行平均。
  5. 對於預先定於的分段重複3-5步(我們採用的是50)
  6. 等到第6步完成後,一個層就訓練完了。對後面的RBM層重複以上步驟。
  7. 等到所有層的訓練完成後,深度網路就已經採用Error Back-propagation進行了調優。

下圖展示了單個資料段在執行深度學習時的過程。我們注意到可以採用這套概念來實現一個本質上具有迭代性的機器學習主機

下面的程式碼段展示了單機訓練DBN的步驟。資料集首先被分批,然後初始化多個RBM層,接著進行訓練。RBM訓練完成後,採用error back propagation進行調優。

我們使用IterativeReduce的實現與YARN進行了大量適配。並且對實現進行了很多修改以便適用於深度學習。IterativeReduce實現是為Cloudera Hadoop 寫的, 我們將它改造成適用於通用的Apache Hadoop 平臺。 我們還重寫了標準程式模型。特別要提到的是,客戶端程式和ResourceManager之間通訊採用了YarnClient API。還採用了AMRMClient和AMNMClient在ApplicationMaster和ResourceManager以及NodeManager之間通訊。

首先我們使用YarnClient API將程式提交給YARN resource manager

提交之後,YARN resource manager 執行 application master,它將根據需要負責分配和釋放工作節點容器。 application master採用AMRMClient與resource manager進行通訊。

application master 採用 NMClient API在容器中執行來自application master的命令。

application master執行工作節點容器後,它會立即設定埠用來和工作節點通訊。對於我們的深度學習來說,我們給原本的IterativeReduce介面新增了一些方法,用來實現引數初始化,逐層訓練和微調訊號。IterativeReduce採用Apache Avro IPC進行主節點-工作節點通訊。

下面的程式碼段展示了主節點-工作節點在分散式訓練中的一系列步驟。主節點把初始引數傳送給工作節點,然後工作節點基於自己的資料對RBM進行訓練。訓練完成後,它將結果傳送給主節點,主節點會將結果進行合併。整個迭代完成後,主節點開始back propagation(反向傳播演算法)微調階段,標誌著主節點流程結束。

結果

我們採用MNIST手寫數字識別來評估深度學習的效能。 資料集包含介於0-9之間的手寫數字,它們都已經包含一個標籤。訓練資料包含 60,000張圖片,測試資料包含10,000張圖片。

為了對結果進行評估, DBN事先進行了訓練,然後用60000張訓練圖片進行微調。進過上述步驟後,用10000張測試圖片來進行評估。 在訓練和測試過程中,圖片沒進行任何預處理。 通過分類錯誤的圖片和圖片總數就能獲得錯誤率。

通過採用每層RBM還有500-500-2000 隱藏units的RBM以及10個節點的分散式設定,我們能達到最優的1.66%的錯誤率。把這個錯誤率和演算法的原作者報告的1.2%錯誤率進行對比,以及其他一些類似的結果對比,我們注意到原本的實現是基於單機的,而我們的實現是基於分散式環境的。引數平均化(parameter-averaging)步驟稍微降低了效能,然而多臺機器的分散式計算帶來的優勢遠遠超過其瑕疵。下表總結了基於10個節點時每層含有的隱藏單位數與錯誤率之間的變化關係。

下一步想法

我們已經成功部署了一個分散式的深度學習系統。我相信這有助於我們解決機器學習的一些問題。更進一步,可以利用iterative reduce abstraction來將任何適合的機器學習演算法進行分佈計算。能夠利用通用的Hadoop叢集平臺將極大的利於在大資料上執行可擴充套件的機器學習演算法。我們注意到目前的框架還有很多值得改進的地方,主要集中在降低網路延遲和更高階的資源管理。另外像我們希望優化DBN框架以便減少節點內通訊。Hadoop Yarn框架帶有更精細的叢集資源控制,它能為我們提供這種靈活性。

相關文章