微软面向初学者的机器学习课程:3.1-构建使用ML模型的Web应用程序
寫在前面:最近在參與microsoft/ML-For-Beginners的翻譯活動(dòng),歡迎有興趣的朋友加入(https://github.com/microsoft/ML-For-Beginners/issues/71)
構(gòu)建使用ML模型的Web應(yīng)用程序
在本課中,你將在一個(gè)數(shù)據(jù)集上訓(xùn)練一個(gè)ML模型,這個(gè)數(shù)據(jù)集來(lái)自世界各地:過(guò)去一個(gè)世紀(jì)的UFO目擊事件,來(lái)源于NUFORC的數(shù)據(jù)庫(kù)。
你將學(xué)會(huì):
如何“pickle”一個(gè)訓(xùn)練有素的模型
如何在Flask應(yīng)用程序中使用該模型
我們將繼續(xù)使用notebook來(lái)清理數(shù)據(jù)和訓(xùn)練我們的模型,但你可以進(jìn)一步探索在web應(yīng)用程序中使用模型。
為此,你需要使用Flask構(gòu)建一個(gè)web應(yīng)用程序。
課前測(cè)
構(gòu)建應(yīng)用程序
有多種方法可以構(gòu)建Web應(yīng)用程序以使用機(jī)器學(xué)習(xí)模型。你的web架構(gòu)可能會(huì)影響你的模型訓(xùn)練方式。想象一下,你在一家企業(yè)工作,其中數(shù)據(jù)科學(xué)小組已經(jīng)訓(xùn)練了他們希望你在應(yīng)用程序中使用的模型。
注意事項(xiàng)
你需要問(wèn)很多問(wèn)題:
**它是web應(yīng)用程序還是移動(dòng)應(yīng)用程序?**如果你正在構(gòu)建移動(dòng)應(yīng)用程序或需要在物聯(lián)網(wǎng)環(huán)境中使用模型,你可以使用TensorFlow Lite并在Android或iOS應(yīng)用程序中使用該模型。
**模型放在哪里?**在云端還是本地?
離線支持。該應(yīng)用程序是否必須離線工作?
**使用什么技術(shù)來(lái)訓(xùn)練模型?**所選的技術(shù)可能會(huì)影響你需要使用的工具。
使用Tensor flow。例如,如果你正在使用TensorFlow訓(xùn)練模型,則該生態(tài)系統(tǒng)提供了使用TensorFlow.js轉(zhuǎn)換TensorFlow模型以便在Web應(yīng)用程序中使用的能力。
使用 PyTorch。如果你使用PyTorch等庫(kù)構(gòu)建模型,則可以選擇將其導(dǎo)出到ONNX(開(kāi)放神經(jīng)網(wǎng)絡(luò)交換)格式,用于可以使用 Onnx Runtime的JavaScript Web 應(yīng)用程序。此選項(xiàng)將在Scikit-learn-trained模型的未來(lái)課程中進(jìn)行探討。
使用Lobe.ai或Azure自定義視覺(jué)。如果你使用ML SaaS(軟件即服務(wù))系統(tǒng),例如Lobe.ai或[Azure Custom Vision](https://azure.microsoft.com/services/ cognitive-services/custom-vision-service/?WT.mc_id=academic-15963-cxa)來(lái)訓(xùn)練模型,這種類型的軟件提供了為許多平臺(tái)導(dǎo)出模型的方法,包括構(gòu)建一個(gè)定制API,供在線應(yīng)用程序在云中查詢。
你還有機(jī)會(huì)構(gòu)建一個(gè)完整的Flask Web應(yīng)用程序,該應(yīng)用程序能夠在 Web瀏覽器中訓(xùn)練模型本身。這也可以在JavaScript上下文中使用 TensorFlow.js來(lái)完成。
出于我們的目的,既然我們一直在使用基于Python的notebook,那么就讓我們探討一下將經(jīng)過(guò)訓(xùn)練的模型從notebook導(dǎo)出為Python構(gòu)建的web應(yīng)用程序可讀的格式所需要采取的步驟。
工具
對(duì)于此任務(wù),你需要兩個(gè)工具:Flask和Pickle,它們都在Python上運(yùn)行。
? 什么是 Flask?Flask被其創(chuàng)建者定義為“微框架”,它提供了使用Python和模板引擎構(gòu)建網(wǎng)頁(yè)的Web框架的基本功能。看看本學(xué)習(xí)單元練習(xí)使用Flask構(gòu)建應(yīng)用程序。
? 什么是Pickle?Pickle????是一 Python模塊,用于序列化和反序列化 Python對(duì)象結(jié)構(gòu)。當(dāng)你“pickle”一個(gè)模型時(shí),你將其結(jié)構(gòu)序列化或展平以在 Web上使用。小心:pickle本質(zhì)上不是安全的,所以如果提示“un-pickle”文件,請(qǐng)小心。生產(chǎn)的文件具有后綴.pkl。
練習(xí) - 清理你的數(shù)據(jù)
在本課中,你將使用由 NUFORC(國(guó)家 UFO 報(bào)告中心)收集的80,000次UFO目擊數(shù)據(jù)。這些數(shù)據(jù)對(duì)UFO目擊事件有一些有趣的描述,例如:
詳細(xì)描述。"一名男子從夜間照射在草地上的光束中出現(xiàn),他朝德克薩斯儀器公司的停車場(chǎng)跑去"。
簡(jiǎn)短描述。“燈光追著我們”。
ufos.csv電子表格包括有關(guān)目擊事件發(fā)生的city、state和country、對(duì)象的shape及其latitude和longitude的列。
在包含在本課中的空白notebook中:
像在之前的課程中一樣導(dǎo)入pandas、matplotlib和numpy,然后導(dǎo)入ufos電子表格。你可以查看一個(gè)示例數(shù)據(jù)集:
import?pandas?as?pd import?numpy?as?npufos?=?pd.read_csv('../data/ufos.csv') ufos.head()將ufos數(shù)據(jù)轉(zhuǎn)換為帶有新標(biāo)題的小dataframe。檢查country字段中的唯一值。
ufos?=?pd.DataFrame({'Seconds':?ufos['duration?(seconds)'],?'Country':?ufos['country'],'Latitude':?ufos['latitude'],'Longitude':?ufos['longitude']})ufos.Country.unique()現(xiàn)在,你可以通過(guò)刪除任何空值并僅導(dǎo)入1-60秒之間的目擊數(shù)據(jù)來(lái)減少我們需要處理的數(shù)據(jù)量:
ufos.dropna(inplace=True)ufos?=?ufos[(ufos['Seconds']?>=?1)?&?(ufos['Seconds']?<=?60)]ufos.info()導(dǎo)入Scikit-learn的LabelEncoder庫(kù),將國(guó)家的文本值轉(zhuǎn)換為數(shù)字:
? LabelEncoder按字母順序編碼數(shù)據(jù)
from?sklearn.preprocessing?import?LabelEncoderufos['Country']?=?LabelEncoder().fit_transform(ufos['Country'])ufos.head()你的數(shù)據(jù)應(yīng)如下所示:
Seconds Country Latitude Longitude 2 20.0 3 53.200000 -2.916667 3 20.0 4 28.978333 -96.645833 14 30.0 4 35.823889 -80.253611 23 60.0 4 45.582778 -122.352222 24 3.0 3 51.783333 -0.783333練習(xí) - 建立你的模型
現(xiàn)在,你可以通過(guò)將數(shù)據(jù)劃分為訓(xùn)練和測(cè)試組來(lái)準(zhǔn)備訓(xùn)練模型。
選擇要訓(xùn)練的三個(gè)特征作為X向量,y向量將是Country 你希望能夠輸入Seconds、Latitude和Longitude并獲得要返回的國(guó)家/地區(qū)ID。
from?sklearn.model_selection?import?train_test_splitSelected_features?=?['Seconds','Latitude','Longitude']X?=?ufos[Selected_features] y?=?ufos['Country']X_train,?X_test,?y_train,?y_test?=?train_test_split(X,?y,?test_size=0.2,?random_state=0)使用邏輯回歸訓(xùn)練模型:
from?sklearn.metrics?import?accuracy_score,?classification_report? from?sklearn.linear_model?import?LogisticRegression model?=?LogisticRegression() model.fit(X_train,?y_train) predictions?=?model.predict(X_test)print(classification_report(y_test,?predictions)) print('Predicted?labels:?',?predictions) print('Accuracy:?',?accuracy_score(y_test,?predictions))準(zhǔn)確率還不錯(cuò)**(大約 95%)**,不出所料,因?yàn)镃ountry和Latitude/Longitude相關(guān)。
你創(chuàng)建的模型并不是非常具有革命性,因?yàn)槟銘?yīng)該能夠從其Latitude和Longitude推斷出Country,但是,嘗試從清理、導(dǎo)出的原始數(shù)據(jù)進(jìn)行訓(xùn)練,然后在web應(yīng)用程序中使用此模型是一個(gè)很好的練習(xí)。
練習(xí) - “pickle”你的模型
現(xiàn)在,是時(shí)候_pickle_你的模型了!你可以在幾行代碼中做到這一點(diǎn)。一旦它是 pickled,加載你的pickled模型并針對(duì)包含秒、緯度和經(jīng)度值的示例數(shù)據(jù)數(shù)組對(duì)其進(jìn)行測(cè)試,
import?pickle model_filename?=?'ufo-model.pkl' pickle.dump(model,?open(model_filename,'wb'))model?=?pickle.load(open('ufo-model.pkl','rb')) print(model.predict([[50,44,-12]]))該模型返回**'3'**,這是英國(guó)的國(guó)家代碼。????
練習(xí) - 構(gòu)建Flask應(yīng)用程序
現(xiàn)在你可以構(gòu)建一個(gè)Flask應(yīng)用程序來(lái)調(diào)用你的模型并返回類似的結(jié)果,但以一種更美觀的方式。
首先在你的 ufo-model.pkl 文件所在的_notebook.ipynb_文件旁邊創(chuàng)建一個(gè)名為web-app的文件夾。
在該文件夾中創(chuàng)建另外三個(gè)文件夾:static,其中有文件夾css和templates`。你現(xiàn)在應(yīng)該擁有以下文件和目錄
web-app/static/css/templates/ notebook.ipynb ufo-model.pkl? 請(qǐng)參閱解決方案文件夾以查看已完成的應(yīng)用程序
在_web-app_文件夾中創(chuàng)建的第一個(gè)文件是requirements.txt文件。與JavaScript應(yīng)用程序中的_package.json_一樣,此文件列出了應(yīng)用程序所需的依賴項(xiàng)。在requirements.txt中添加以下幾行:
scikit-learn pandas numpy flask現(xiàn)在,進(jìn)入web-app文件夾:
cd?web-app在你的終端中輸入pip install,以安裝_reuirements.txt_中列出的庫(kù):
pip?install?-r?requirements.txt現(xiàn)在,你已準(zhǔn)備好創(chuàng)建另外三個(gè)文件來(lái)完成應(yīng)用程序:
在根目錄中創(chuàng)建app.py
在_templates_目錄中創(chuàng)建index.html。
在_static/css_目錄中創(chuàng)建styles.css。
使用一些樣式構(gòu)建_styles.css_文件:
body?{width:?100%;height:?100%;font-family:?'Helvetica';background:?black;color:?#fff;text-align:?center;letter-spacing:?1.4px;font-size:?30px; }input?{min-width:?150px; }.grid?{width:?300px;border:?1px?solid?#2d2d2d;display:?grid;justify-content:?center;margin:?20px?auto; }.box?{color:?#fff;background:?#2d2d2d;padding:?12px;display:?inline-block; }接下來(lái),構(gòu)建_index.html_文件:
<!DOCTYPE?html> <html> <head><meta?charset="UTF-8"><title>?????UFO?Appearance?Prediction!?????</title><link?rel="stylesheet"?href="{{?url_for('static',?filename='css/styles.css')?}}">? </head><body><div?class="grid"><div?class="box"><p>According?to?the?number?of?seconds,?latitude?and?longitude,?which?country?is?likely?to?have?reported?seeing?a?UFO?</p><form?action="{{?url_for('predict')}}"?method="post"><input?type="number"?name="seconds"?placeholder="Seconds"?required="required"?min="0"?max="60"?/><input?type="text"?name="latitude"?placeholder="Latitude"?required="required"?/><input?type="text"?name="longitude"?placeholder="Longitude"?required="required"?/><button?type="submit"?class="btn">Predict?country?where?the?UFO?is?seen</button></form><p>{{?prediction_text?}}</p></div> </div></body> </html>看看這個(gè)文件中的模板。請(qǐng)注意應(yīng)用程序?qū)⑻峁┑淖兞恐車摹癿ustache”語(yǔ)法,例如預(yù)測(cè)文本:{{}}。還有一個(gè)表單可以將預(yù)測(cè)發(fā)布到/predict路由。
最后,你已準(zhǔn)備好構(gòu)建使用模型和顯示預(yù)測(cè)的python 文件:
在app.py中添加:
import?numpy?as?np from?flask?import?Flask,?request,?render_template import?pickleapp?=?Flask(__name__)model?=?pickle.load(open("../ufo-model.pkl",?"rb"))@app.route("/") def?home():return?render_template("index.html")@app.route("/predict",?methods=["POST"]) def?predict():int_features?=?[int(x)?for?x?in?request.form.values()]final_features?=?[np.array(int_features)]prediction?=?model.predict(final_features)output?=?prediction[0]countries?=?["Australia",?"Canada",?"Germany",?"UK",?"US"]return?render_template("index.html",?prediction_text="Likely?country:?{}".format(countries[output]))if?__name__?==?"__main__":app.run(debug=True)???? 提示:當(dāng)你在使用Flask運(yùn)行Web應(yīng)用程序時(shí)添加 debug=True時(shí)你對(duì)應(yīng)用程序所做的任何更改將立即反映,無(wú)需重新啟動(dòng)服務(wù)器。注意!不要在生產(chǎn)應(yīng)用程序中啟用此模式
如果你運(yùn)行python app.py或python3 app.py - 你的網(wǎng)絡(luò)服務(wù)器在本地啟動(dòng),你可以填寫一個(gè)簡(jiǎn)短的表格來(lái)回答你關(guān)于在哪里看到UFO的問(wèn)題!
在此之前,先看一下app.py的實(shí)現(xiàn):
首先,加載依賴項(xiàng)并啟動(dòng)應(yīng)用程序。
然后,導(dǎo)入模型。
然后,在home路由上渲染index.html。
在/predict路由上,當(dāng)表單被發(fā)布時(shí)會(huì)發(fā)生幾件事情:
收集表單變量并轉(zhuǎn)換為numpy數(shù)組。然后將它們發(fā)送到模型并返回預(yù)測(cè)。
我們希望顯示的國(guó)家/地區(qū)根據(jù)其預(yù)測(cè)的國(guó)家/地區(qū)代碼重新呈現(xiàn)為可讀文本,并將該值發(fā)送回index.html以在模板中呈現(xiàn)。
以這種方式使用模型,包括Flask和pickled模型,是相對(duì)簡(jiǎn)單的。最困難的是要理解數(shù)據(jù)是什么形狀的,這些數(shù)據(jù)必須發(fā)送到模型中才能得到預(yù)測(cè)。這完全取決于模型是如何訓(xùn)練的。有三個(gè)數(shù)據(jù)要輸入,以便得到一個(gè)預(yù)測(cè)。
在一個(gè)專業(yè)的環(huán)境中,你可以看到訓(xùn)練模型的人和在Web或移動(dòng)應(yīng)用程序中使用模型的人之間的良好溝通是多么的必要。在我們的情況下,只有一個(gè)人,你!
???? 挑戰(zhàn):
你可以在Flask應(yīng)用程序中訓(xùn)練模型,而不是在notebook上工作并將模型導(dǎo)入Flask應(yīng)用程序!嘗試在notebook中轉(zhuǎn)換Python代碼,可能是在清除數(shù)據(jù)之后,從應(yīng)用程序中的一個(gè)名為train的路徑訓(xùn)練模型。采用這種方法的利弊是什么?
課后測(cè)
復(fù)習(xí)與自學(xué)
有很多方法可以構(gòu)建一個(gè)Web應(yīng)用程序來(lái)使用ML模型。列出可以使用JavaScript或Python構(gòu)建Web應(yīng)用程序以利用機(jī)器學(xué)習(xí)的方法。考慮架構(gòu):模型應(yīng)該留在應(yīng)用程序中還是存在于云中?如果是后者,你將如何訪問(wèn)它?為應(yīng)用的ML Web解決方案繪制架構(gòu)模型。
任務(wù)
嘗試不同的模型
總結(jié)
以上是生活随笔為你收集整理的微软面向初学者的机器学习课程:3.1-构建使用ML模型的Web应用程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: C#新手该如何规划学习【学习路线指南】
- 下一篇: [006] 了解 Roslyn 编译器