iMind Developers Blog

iMind開発者ブログ

MLFlowを使ってみる3 - models

概要

MLFlowの機能をざっと試す第三弾。tracking、projectsと扱ってきたので今回は最後のmodelsについて。

modelsは生成したモデルをsave、load、predictなどの機能を持ち、コマンドラインで指定モデルを使ってpredictが実行できたりもする。

本稿では扱わないが、クラウド用途ではAWS SageMakerやAzure MLと連携することもできる。

バージョン情報

  • mlflow==1.0.0

用意されているwrapper(Model Flavor)

ラッパーという言葉を聞くとクラッシュバンディクーが頭に浮かぶことがあるが、おそらくパラッパラッパーと混線しているのだと思われる。

mlflowでは下記のwrapperが既に用意されている。

  • h2o
  • keras
  • mleap
  • pytorch
  • sklearn
  • spark(mllib)
  • tensorflow

sklearnでlog_model

mlflow.sklearnを用いて何ができるか確認する。

mlflow.sklearnには下記メソッドが用意されている。

  • load_model
  • log_model
  • save_model

save_modelはローカルに保存する処理で、log_modelはsave_modelを利用して保存したモデルをmlflowのartifactとして登録する。

help(mlflow.sklearn) で出てくるモデルを参考に簡単に動作を確認する。

import mlflow.sklearn
import sklearn.datasets
import sklearn.tree

with mlflow.start_run():
    # irisiでモデル生成
    iris = sklearn.datasets.load_iris()
    tree = sklearn.tree.DecisionTreeClassifier()
    model = tree.fit(iris.data, iris.target)

    # metricsらしきものをなんとなく入れておく
    accuracy = sum(model.predict(iris.data) == iris.target) / len(iris.target) 
    mlflow.log_metrics({'accuracy': accuracy})

    # dicision_treeという名前でlog_model
    mlflow.sklearn.log_model(model, 'dicision_tree')

uiで見るとこんな感じの結果になる。

f:id:imind:20190531173147p:plain

日付のリンクをクリックすると詳細に飛ぶ。下記のようにモデルに関する各種情報が残されている。

f:id:imind:20190531173157p:plain

CLIでpredict

log_modelしたモデルを使ってCLIでpredictして結果を取得する。

predictに入力するデータとしてirisをcsvにして保存しておく。

import numpy as np
import sklearn.datasets

iris = sklearn.datasets.load_iris()
np.savetxt('iris.csv', iris.data, delimiter=',')

出力したcsvファイルからpredictを実行。

$ mlflow models predict \
        --model-uri {Full Path} \
        --content-type csv \
        --input-path iris.csv \
        --output-path predict.csv

引数の--model-uri は上のweb uiの画像にも出ているFull Pathの項の値を取ってくる。

例えば$HOME/workで実行していた場合は下記のような結果になるはず。

file:///home/user/work/mlruns/0/${run_uuid}/artifacts/dicision_tree

--output-path predict.csv と指定しているので、predict.csvというファイルパスに結果が出力されているはず。

$ cat predict.csv 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

Pythonのコードからpredict

モデルのload。下記でscikit-learnのモデルが取得できる。引数のFull Pathはコマンドラインで指定したものと同じ。

# modelのload
import mlflow
import mlflow.sklearn
model = mlflow.sklearn.load_model('{Full Path}')

# irisの用意
import sklearn.datasets
iris = sklearn.datasets.load_iris()

# 10件だけ予測してみる
model.predict(iris.data[0:10])
    #=> array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

APIを用いたpredict

Web APIでpredictを実行することもできる。

models serveでそれ用のAPIを立ち上げる。{Full Path}のところはいつもの。

mlflow models serve \
  --model-uri {Full Path} \
  --host localhost \
  --port 5001

特徴はjsonで渡すのでpandasを使ってirisの5行分のレコードをjsonにしてみる。

import pandas as pd
print( pd.DataFrame(iris.data[0:5]).to_json() )

出力された結果を引数にcurlを叩け叩け叩け。

$ curl -X POST \
    -H "Content-Type:application/json; format=pandas-records" \
    --data '{"0":{"0":5.1,"1":4.9,"2":4.7,"3":4.6,"4":5.0},"1":{"0":3.5,"1":3.0,"2":3.2,"3":3.1,"4":3.6},"2":{"0":1.4,"1":1.4,"2":1.3,"3":1.5,"4":1.4},"3":{"0":0.2,"1":0.2,"2":0.2,"3":0.2,"4":0.2}}' \
    http://localhost:5001/invocations

実行結果

[0, 0, 0, 0, 0]

こうしたAPIはcustom flavorを作れば自作のモデルで実装することも可能らしい。

改定履歴

Author: Masato Watanabe, Date: 2019-06-15, 記事投稿