MLflow: A Machine Learning Lifecycle Platform-入門教學

Chunjhong
Taiwan AI Academy
Published in
13 min readJan 30, 2020
source: https://twitter.com/MLflow

MLflow能讓使用者紀錄機器學習模型訓練過程中的各種數據,模型訓練完後也能夠用它來打包模型,方便後續提供給其他人重現實驗結果,總的來說它是一套能讓你在分析及後續部屬上更為便利的工具。

首先,就讓我們先到cmd輸入以下指令來安裝MLflow,我個人是在Windows上安裝,並沒有出現什麼問題。

pip install mlflow

安裝完後就讓我們先從一個簡單的例子開始,請先創建一個py檔並輸入以下程式碼。

import os
from mlflow import log_metric, log_param, log_artifact
if __name__ == "__main__":
# Log a parameter (key-value pair)
log_param("param1", 2.5)
log_param("param2", 4)
# Log a metric; metrics can be updated throughout the run
log_metric("foo", 1)
log_metric("foo", 2)
log_metric("foo", 5)
# Log an artifact (output file)
with open("output1.txt", "w") as f:
f.write("first file!")
with open("output2.txt", "w") as f:
f.write("second file!")
log_artifact("output1.txt")
log_artifact("output2.txt")

因為等一下執行程式後會在程式碼所在目錄額外生成一些資料,我建議新增一個資料夾來放這份程式碼。再來只要像一般執行py檔一樣執行上面這段程式碼,你可以看到資料夾裡多了下面這些檔案。

我的程式碼放在test.py裡,執行後會多出mlruns這個資料夾,裡面會有我要求MLflow記錄下來的參數或是指標的數值,output1和output2則是上面程式碼裡輸出的兩個文字檔,這兩個文字檔我也有讓MLflow記錄下來。只要是我們有讓MLflow記錄下來的資料,後續都可以用它提供的ui很方便的觀察這些數據,那就讓我們在cmd輸入以下指令來試試看吧。

mlflow ui

輸入指令後會出現如下的訊息,紅色框框的部分只是提醒說有一些功能未來可能會更新,目前不會影響我們的程式執行。綠色框框則是跟你講MLflow把ui功能啟動在哪個位置,框框內顯示的路徑名稱會因為電腦名稱而有所不同,不過一樣都能用localhost:5000去使用這項服務,注意不要把cmd關掉。

再來我們開啟瀏覽器並在網址的部分輸入localhost:5000,就能進到MLflow提供的ui介面了。

可以看到我們在上面程式碼裡請MLflow紀錄的數據都會顯示在這裡,log_param就是用來記錄一些模型的超參數,而log_metric則可以用來記錄訓練過程中不斷變化的loss或accuracy,不過這個頁面的 Metrics只會顯示最後紀錄的值,要看更詳細的資訊我們需要點一下我用紅色框起來的Date那邊。

點進來後可以看到最下面有我們在程式碼裡用log_artifact紀錄的文字檔,其實不只是文字檔,也可以用來記錄圖片或其他格式的檔案,最重要的是能夠紀錄訓練好的模型,這個部分後續會再給一些實際例子。我們先看Metrics的部分,點一下我用紅色框起來的地方。

這邊就可以看到我們紀錄的foo這個數值的變化過程了,那有了上述這些基本的了解之後,我們來個實際應用的案例。

# The data set used in this example is from http://archive.ics.uci.edu/ml/datasets/Wine+Quality
# P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis.
# Modeling wine preferences by data mining from physicochemical properties. In Decision Support Systems, Elsevier, 47(4):547-553, 2009.
import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import ElasticNet
import mlflow
import mlflow.sklearn
def eval_metrics(actual, pred):
rmse = np.sqrt(mean_squared_error(actual, pred))
mae = mean_absolute_error(actual, pred)
r2 = r2_score(actual, pred)
return rmse, mae, r2

alphas = [0.5, 0.7, 0.9]
l1_ratios = [0.3, 0.5, 0.9]
np.random.seed(40)
# Read the wine-quality csv file from the URL
csv_url ='http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'
try:
data = pd.read_csv(csv_url, sep=';')
except Exception as e:
print("Unable to download training & test CSV, check your internet connection. Error: %s", e)
# Split the data into training and test sets. (0.75, 0.25) split.
train, test = train_test_split(data)
# The predicted column is "quality" which is a scalar from [3, 9]
train_x = train.drop(["quality"], axis=1)
test_x = test.drop(["quality"], axis=1)
train_y = train[["quality"]]
test_y = test[["quality"]]
for alpha in alphas:
for l1_ratio in l1_ratios:
with mlflow.start_run():
lr = ElasticNet(alpha=alpha, l1_ratio=l1_ratio, random_state=42)
lr.fit(train_x, train_y)
predicted_qualities = lr.predict(test_x)
(rmse, mae, r2) = eval_metrics(test_y, predicted_qualities)
mlflow.log_param("alpha", alpha)
mlflow.log_param("l1_ratio", l1_ratio)
mlflow.log_metric("rmse", rmse)
mlflow.log_metric("r2", r2)
mlflow.log_metric("mae", mae)
mlflow.sklearn.log_model(lr, "model")

winequality_red.csv是一個葡萄酒的公開資料集,欄位有酒的酸度、ph值、酒的品質等資訊,上面這段程式的目的就是要用這份資料集訓練能夠預測酒的品質的模型。我們這邊挑了ElasticNet作為我們要訓練的模型,並測試了很多組超參數的組合,再紀錄每一組超參數下的評分。藉由MLflow做的紀錄我們可以很方便地確認我們每一次的實驗結果。請執行上面這段程式碼後再啟動mlflow ui。

可以看到每次的超參數和評分都很清楚地記下來了,而且它有提供一些搜尋或是排序的功能,像是我在紅色框框那邊輸入metrics.rmse>0.8再按右邊的Search,這樣就只會有符合我們設定條件的那幾次實驗會顯示出來。再來說明一下上面程式碼出現的log_model的部分,先點綠色框起來的Date那邊。

log_model這個指令會幫我們把訓練好的model保存起來,在Artifacts這邊可以看到model的資料夾,我們如果想要把model讀取出來再做predict使用就需要這個資料夾的路徑,也就是我用紅色框起來的部分。可以用下面這段程式碼來試試看,注意你的model路徑會跟我的不一樣,還有我把這份程式碼放在跟mlruns同一層目錄,所以不用打完整路徑。

import mlflow.sklearn
from sklearn.model_selection import train_test_split
import pandas as pd
sk_model = mlflow.sklearn.load_model("mlruns/0/0f98bc27332545ef9d075675cad1131b/artifacts/model")
csv_url ='http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv'
try:
data = pd.read_csv(csv_url, sep=';')
except Exception as e:
print("Unable to download training & test CSV, check your internet connection. Error: %s", e)
# Split the data into training and test sets. (0.75, 0.25) split.
train, test = train_test_split(data)
# The predicted column is "quality" which is a scalar from [3, 9]
test_x = test.drop(["quality"], axis=1)
predictions = sk_model.predict(test_x)
print(predictions)

用load_model就能讀取保存起來的模型,需要注意的是,不同套件下模型的保存和讀取的方式會有點不太一樣,比方sklearn的模型保存是用sklearn.log_model,而tensorflow的模型保存是用tensorflow.log_model,可以去這個地方確認一下 https://mlflow.org/docs/latest/models.html#built-in-model-flavors。最後,我來講一下專案打包的部分。

先準備一個資料夾,資料夾裡面放你的程式碼或你會用到的資料集等等,再來我們需要編輯MLproject和conda.yaml這兩個檔案。

name: tutorialconda_env: conda.yamlentry_points:
main:
command: "python test.py"

MLproject裡面需要寫專案名稱、有寫環境需求的檔案路徑及執行這個專案的時候要做哪些事,名稱這邊就簡單給個tutorial,有寫環境需求的檔案就是上面提到的conda.yaml,entry_points這邊可以下很多command,我這邊只有讓他去執行test.py,你可以根據需求再加其他command上去,像是先去哪個網址爬資料集下來等等。

name: tutorial
channels:
- defaults
dependencies:
- numpy=1.14.3
- pandas=0.22.0
- scikit-learn=0.19.1
- pip:
- mlflow

再來是conda.yaml的部分,這裡需要先提一下,MLflow會根據這個檔案在你的anaconda上開新的虛擬環境並下載裡面提到的套件,所以你必須要先安裝好anaconda。檔案內容的部分,專案名稱就一樣給tutorial,channels一般給defaults就行了,除非你要載特定owner的套件,如下圖,如果你要載的tensorflow是紅色框起來那個,你就要把channels改成conda-forge,最後dependencies就把你要的套件跟需求版本打上去就行了,需要注意的是有的套件conda install找不到,比方mlflow,這種情況就需要特別指定用pip下載。

https://anaconda.org/

這兩個檔案都編輯好之後,我們只要把這個資料夾給其他有安裝MLflow的使用者,對方就能用一行指令就安裝好環境,並照你設定的command很輕易地重現你的實驗,那就讓我們來試試看吧,請輸入下面這行指令。

mlflow run mlflow_project

要注意你們的資料夾名稱可能跟我的不一樣。執行之後他就會開始創新的虛擬環境及安裝相關的套件等等,安裝部分都還沒什麼問題,但是在啟動虛擬環境的地方會報錯,這也許是windows才會報的錯,我會持續關注這個issue( https://github.com/mlflow/mlflow/issues/2296),等官方修復完我會再做更新。

--

--