為機器學習模型注入持久性
大?。?/span>0.6 MB 人氣: 2017-10-10 需要積分:1
標簽:機器學習模型(2552)
簡介研究機器學習用例:
數據科學家建立了一個ML模型,并交給了一個工程團隊在生產環境部署。數據工程師將使用Python的模型訓練工作流和Java模型服務工作流整合。數據科學家專門設立崗位來訓練后期需要被保存和評估的ML模型。
在所有的這些例子中,如果有了模型的持久性,那么保存和加載模型的問題將變得更容易解決。在即將到來的2.0版本中,通過基于DataFrame的API,Spark機器學習庫MLlib將實現幾乎完整的ML持久性支持。本文將提前透露有關代碼示例,以及MLlib API持久性的一些細節。
ML持久性的關鍵特性包括:
Spark支持所有語言的API:Scala、Java、Python和R基于DataFram的API幾乎支持所有的ML算法支持單一模型和完整的Pipelines,不管是訓練或者未訓練的使用可互換的格式來實現分布式存儲
感謝所有為MLlib帶來巨大發展的社區貢獻者們!在JIRAs中可以看到為Scala,Java, Python和R做出貢獻的完整人員名單。
了解API
在Apache Spark 2.0里,對于MLlib來說基于DataFrame的API在關于Spark的ML中占據了首要位置。該API模仿被人們所熟知的Spark Data Source API,提供保存和加載模型的功能。
下面將采用流行的MNIST數據集進行手寫體數字識別,并在幾種語言上演示保存和加載模型的功能(LeCun等著,1998;可從LIBSVM數據頁面獲取)。這個數據集包含了手寫數字0-9,以及地面實況標簽。這里有些例子:
我們的最終目的是為了拍攝新的手寫數字圖像并進行數字識別。在下面的筆記中就完整地演示了數據載入,以及模型訓練、保存和加載的代碼。
保存和加載單一模型
首先將展示如何保存和加載單一模型以促進語言共享,例子中首先會通過Python來訓練一個Random Forest Classifier并保存下來,然后再利用Scala加載相同的模型。
training = sqlContext.read.。. # data: features, labelrf = RandomForestClassifier(numTrees=20)model = rf.fit(training)
為了簡化,這里將保存模型稱為save方法,把加載模型稱為load方法:
model.save(“myModelPath”) sameModel = RandomForestClassificationModel.load(“myModelPath”)
我們還可以將同樣的模型(已保存在Python的)加載到一個Scala或者Java應用程序中:
// Loadthe model inScala val sameModel = RandomForestClassificationModel.load(“myModelPath”)
這個方法既可以用于小型的本地模型例如K-Means模型(為了集群),也可以用于大型的分布式模型例如ALS模型(為了推薦)。因為加載的模型具有相同的參數設置和數據,所以即使加載的是一個完全不同的Spark部署,它也會給出相同的預測。
保存和加載完整Pipelines
到目前為止只演示了單一ML模型的保存和加載,但在實際過程中,ML的工作流其實包含著許多階段,從特征的提取和轉換到模型的訓練和調優都在其中。MLlib還提供了Pipelines來幫助用戶更好地構建這些工作流。
同時,MLlib還允許用戶保存和加載整個Pipelines。下面通過一個Pipeline案例看一下它是采用了哪些步驟實現的:
特征提取:使用Binarizer將圖像轉換成黑白色模型訓練:使用Random Forest Classifier拍攝圖像和預測數字0–9調優:使用交叉驗證(Cross-Validation)來優化森林中樹的深度
下面是建立Pipeline的一個片段:
// Construct the Pipeline: Binarizer + Random Forest val pipeline = new Pipeline().setStages(Array(binarizer, rf)) // Wrap the Pipeline inCrossValidator to do model tuning. val cv = new CrossValidator().setEstimator(pipeline) 。..
在管道訓練之前,我們會演示將整個工作流保存下來的過程(訓練前)。而且這個工作流可以在另一個數據集上,或者是在另一個Spark集群上等地方加載運行。
cv.save(“myCVPath”) val sameCV = CrossValidator.load(“myCVPath”)
最后,我們就可以進行Pipeline訓練,再將其保存和加載。這不僅可以節省特征提取的步驟,還可以省去使用Cross-Validation調整Random Forest模型以及從模型調優中提取數據的過程。
val cvModel = cv.fit(training) cvModel.save(“myCVModelPath”) val sameCVModel = CrossValidatorModel.load(“myCVModelPath”)
了解細節
Python調優
很遺憾,Python調優將缺席Spark 2.0版本。就目前情況來看,Python還不支持保存和加載用于優化hyperparameters模型的CrossValidator和TrainValidationSplit;這個問題也正是Spark 2.1版本需要解決的。但是,它仍然有可能被用來保存Python中的CrossValidator和TrainValidationSplit結果。例如,使用Cross-Validation來調整Random Forest并將調整過程中發現的最好模型保存起來。
# Define the workflowrf = RandomForestClassifier() cv = CrossValidator(estimator=rf, 。..) # Fit the model, running Cross-ValidationcvModel = cv.fit(trainingData) # Extract the results, i.e., the best Random Forest modelbestModel = cvModel.bestModel # Save the RandomForest modelbestModel.save(“rfModelPath”)
可交換的存儲格式
在內部,我們可以把模型的元數據和參數保存為JSON,把數據保存為Parquet。這些存儲格式是可交換的,還可以使用其他庫讀取。Parquet不僅可以存儲小的模型(例如Naive Bayes for classification),還可以存儲大型的分布式模型(例如ALS for recommendation)。任何被Dataset/DataFrame支持的URI 都可以保存和加載存儲路徑,包括S3路徑、本地存儲等等。
語言的跨平臺兼容性
利用Scala、Java和Python可以很容易地保存和加載模型,但是R卻有兩個局限性。一方面,R并不是支持所有的MLlib模型,其他語言所訓練的模型也不是都可以被加載到R。另一方面,目前的R模型格式需要存儲一些配合R使用的數據,這樣給其他語言加載R所訓練和存儲的模型增加了困難。相信更好的跨語言支持R會在不久的將來被補足。
結論
隨著2.0版本的即將發布,DataFrame-based MLlib API將幾乎完全覆蓋持久化的模型和Pipelines。對于團隊間共享模型、多語言ML工作流創建以及將模型用于生產這些,持久性發揮著至關重要的作用。這個特性也將會推動MLlib API(DataFrame-based)最終轉變為Apache Spark機器學習的重要API。
接下來呢?
未來的話,更高優先級的項目將會包括完整的持久性覆蓋、Python模型優化算法以及R和其他語言API之間的兼容性改進。
?
非常好我支持^.^
(0) 0%
不好我反對
(0) 0%