用 Apache Spark 和 TensorFlow 進行深度學(xué)習(xí)
神經(jīng)網(wǎng)絡(luò)在過去幾年中取得了驚人的進步,現(xiàn)在已成為圖像識別和自動翻譯領(lǐng)域***進的技術(shù)。TensorFlow是 Google 為數(shù)字計算和神經(jīng)網(wǎng)絡(luò)發(fā)布的新框架。在這篇博文中,我們將演示如何使用 TensorFlow 和 Spark 一起來訓(xùn)練和應(yīng)用深度學(xué)習(xí)模型。
你可能會想:當(dāng)大多數(shù)高性能深度學(xué)習(xí)實現(xiàn)只是單節(jié)點時,Apache Spark 在這里使用什么?為了回答這個問題,我們將通過兩個用例來解釋如何使用 Spark 和 TensorFlow 的集群機器來改進深度學(xué)習(xí)流程:
超參數(shù)調(diào)整:使用 Spark 找到神經(jīng)網(wǎng)絡(luò)訓(xùn)練的***超參數(shù),使得訓(xùn)練時間減少 10 倍并且錯誤率降低 34 %。
大規(guī)模部署模型:使用 Spark,在大量數(shù)據(jù)上應(yīng)用訓(xùn)練后神經(jīng)網(wǎng)絡(luò)模型。
超參數(shù)調(diào)優(yōu)
深度學(xué)習(xí)機器學(xué)習(xí)(ML)技術(shù)的一個例子是人工神經(jīng)網(wǎng)絡(luò)。它們采取復(fù)雜的輸入,例如圖像或音頻記錄,然后對這些信號應(yīng)用復(fù)雜的數(shù)學(xué)變換。該變換的輸出是數(shù)值向量,其更容易被其他 ML 算法運算。人工神經(jīng)網(wǎng)絡(luò)通過模仿人腦視覺皮質(zhì)中的神經(jīng)元(以簡化形式)執(zhí)行這種轉(zhuǎn)化。
正如人類學(xué)習(xí)解釋他們所看到的那樣,人工神經(jīng)網(wǎng)絡(luò)需要被訓(xùn)練來識別「有趣」的特定模式。例如,這些可以是簡單的圖案,例如,邊緣,圓形,但是它們可能要復(fù)雜。在這里,我們將使用由 NIST 組合的經(jīng)典數(shù)據(jù)集,并訓(xùn)練神經(jīng)網(wǎng)絡(luò)來識別這些數(shù)字:
TensorFlow 庫自動化訓(xùn)練各種形狀和大小的神經(jīng)網(wǎng)絡(luò)算法的創(chuàng)建。然而,構(gòu)建神經(jīng)網(wǎng)絡(luò)的實際過程比僅在數(shù)據(jù)集上運行一些函數(shù)更復(fù)雜。通常會有許多非常重要的影響模型訓(xùn)練效果的超參數(shù)(外行人術(shù)語中的配置參數(shù))設(shè)置。選擇正確的參數(shù)會導(dǎo)致高性能,而不良參數(shù)會導(dǎo)致訓(xùn)練時間長,性能不佳。在實踐中,機器學(xué)習(xí)從業(yè)者用不同的超參數(shù)多次重復(fù)運行相同的模型,以便找到***超參數(shù)集。這是一種稱為超參數(shù)優(yōu)化的經(jīng)典技術(shù)。
建立神經(jīng)網(wǎng)絡(luò)時,有很多要慎重選擇的超參數(shù)。例如:
- 每層神經(jīng)元數(shù)量:太少的神經(jīng)元會降低網(wǎng)絡(luò)的表達力,但太多會大大增加運行時間并返回帶有噪聲的估計。
- 學(xué)習(xí)率:如果太高,神經(jīng)網(wǎng)絡(luò)只會關(guān)注最近幾個樣本,忽視以前積累的所有經(jīng)驗。如果太低,達到好狀態(tài)需要太長時間。
有趣的是,即使 TensorFlow 本身沒有分布,超參數(shù)調(diào)整過程也是「尷尬并行」,可以使用 Spark 進行分布。在這種情況下,我們可以使用 Spark 來 broadcast 諸如數(shù)據(jù)和模型描述之類的常見元素,然后在整個機器群集之間以容錯方式調(diào)度各個重復(fù)計算。
使用Spark如何提高準(zhǔn)確性?超級參數(shù)的默認(rèn)設(shè)置精度為 99.2%。通過超參數(shù)調(diào)優(yōu),在測試集上***的結(jié)果是具有 99.47% 的精度,這減少 34% 的測試誤差。分配添加到集群的節(jié)點數(shù)呈線性關(guān)系的計算:使用 13 節(jié)點集群,我們能夠并行訓(xùn)練 13 個模型,這相當(dāng)于在一臺機器上一次訓(xùn)練一個模型的 7 倍速度。以下是關(guān)于機器集群數(shù)量的計算時間(以秒為單位)的圖表:
更重要的是,我們深入了解訓(xùn)練過程的各種訓(xùn)練超參數(shù)的敏感性。例如,對于不同數(shù)量的神經(jīng)元,我們繪制關(guān)于學(xué)習(xí)率的最終測試性能:
這顯示了神經(jīng)網(wǎng)絡(luò)的典型權(quán)衡曲線:
- 學(xué)習(xí)率至關(guān)重要:如果太低,神經(jīng)網(wǎng)絡(luò)不會學(xué)到任何東西(高測試錯誤率);如果太高,在某些配置中,訓(xùn)練過程可能隨機振蕩甚至發(fā)散。
- 神經(jīng)元的數(shù)量對于獲得良好的性能并不重要,并且具有許多神經(jīng)元的網(wǎng)絡(luò)對于學(xué)習(xí)率更加敏感。這是奧卡姆的剃刀原理:對于大多數(shù)目標(biāo)來說,更簡單的模型往往都是「夠好」的。如果你在缺少 1% 的測試錯誤率后有足夠的時間和資源,你可以投入大量資源進行訓(xùn)練,并找到產(chǎn)生影響的適當(dāng)?shù)某瑓?shù)。
通過使用稀疏的參數(shù)樣本,我們可以對最有希望的參數(shù)集進行歸零。
我該怎么用?
由于 TensorFlow 可以使用每個機器的所有核心,因此我們一次只能在每個機器運行一個任務(wù),并將它們批處理以限制競爭。TensorFlow 庫可以作為常規(guī) Python 庫安裝在 Spark 集群上,遵循 TensorFlow 網(wǎng)站上的說明。以下筆記本顯示如何安裝 TensorFlow,讓用戶重新運行此博客的實驗:
使用TensorFlow分布式處理圖像
使用TensorFlow測試圖像的分布處理
規(guī)模部署模型
TensorFlow 模型可以直接嵌入到管道中,以對數(shù)據(jù)集執(zhí)行復(fù)雜的識別任務(wù)。例如,我們展示了如何從已經(jīng)訓(xùn)練的股票神經(jīng)網(wǎng)絡(luò)模型中標(biāo)注一組圖像。
該模型首先使用 Spark 的內(nèi)置 broadcasting 機制分配給集群的機器:
然后將該模型加載到每個節(jié)點上并應(yīng)用于圖像。這是每個節(jié)點上運行代碼的草圖:
通過將圖像批量化在一起,可以使此代碼更有效率。
這是一個圖像的例子:
這里是根據(jù)神經(jīng)網(wǎng)絡(luò)對這個圖像的解釋,這是非常準(zhǔn)確的:
期待
針對手寫數(shù)字識別和圖像標(biāo)識,我們已經(jīng)展示了如何結(jié)合 Spark 和 TensorFlow 訓(xùn)練和部署神經(jīng)網(wǎng)絡(luò)。即使我們使用的神經(jīng)網(wǎng)絡(luò)框架本身只適用于單節(jié)點,我們可以使用 Spark 來分配超參數(shù)調(diào)整過程和模型部署。這不僅減少了訓(xùn)練時間,而且提高了準(zhǔn)確度,使我們更好地了解了各種超參數(shù)的敏感性。
雖然此支持僅適用于 Python,但我們期待在 TensorFlow 和 Spark 框架的其余部分之間進行更深入的集成。