こすたろーんエンジニアの試行錯誤部屋

作成物の備忘録を書いていきますー

【MLOps】Metaflowとscikit-learnでmnistデータの学習をやってみる

以前にMLOpsのモジュールmetaflowの環境を構築しました
technoxs-stacker.hatenablog.com technoxs-stacker.hatenablog.com

googleが定義する「MLOps レベル 1: ML パイプラインの自動化」を目指すため、
今回はmetaflowを使って機械学習の処理の自動化を試してみます
使用するデータはmnistで、モデルはGaussianNB、RandomForestClassifierです

目次

スポンサーリンク

この記事でわかること

Metaflowとscikit-learnでmnistデータの学習を行う方法

1.実行環境

Jetson Xavier NX
ubuntu18.04
docker 19.03.6
Python 3.6.9
metaflow 2.7.14

2.必要モジュールをインストール

pip install pandas
pip install scikit-learn  

3.MNISTデータを取得

以下のページにアクセスして、mnist_train.csvとmnist_test.csvを取得します
www.kaggle.com

4.ディレクトリ構成を整備

以下のようにmnist_train.csvとmnist_test.csvを設置してmnist.pyファイルを作成します
workspace
├─mnist_train.csv
├─mnist_train.csv
├─mnist.py

5.metaflowでフローの骨組みを作る

ここからmnist.pyを編集して以下のような処理を作成していきます
5.1) MNISTの学習データを読み込む
5.2) データの前処理 5.3) train / testデータの分割
5.4) model1(GaussianNB)の学習とmodel2(RandomForestClassifier)の学習して推論
5.5) 推論結果からモデルを評価
上記の骨組みをまず作成します

mnist.py

import os
from io import StringIO
import pandas as pd
from metaflow import FlowSpec, step, Parameter, IncludeFile
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score

class MnistFlow(FlowSpec):

  @step
  def start(self):
    self.next(self.prepare_data)

  @step
  def prepare_data(self):
    self.next(self.split_data)

  @step
  def split_data(self):
    self.next(self.fit_predict_model1, self.fit_predict_model2)

  @step
  def fit_predict_model1(self):
    self.next(self.join)

  @step
  def fit_predict_model2(self):
    self.next(self.join)

  @step
  def join(self, inputs):
    # merge artificate during a join
    self.merge_artifacts(inputs)
    self.next(self.evaluate)

  @step
  def evaluate(self):
    # measure accuracy
    self.next(self.end)

  @step
  def end(self):
    print('finished')


if __name__ == '__main__':
  MnistFlow()

6.各処理を記述する

6.1 MNISTの学習データを読み込む

start関数にデータ読み込み処理を記述します

  @step
  def start(self):
    # Read data from csv file
    self.mnist_df = pd.read_csv(StringIO(self.mnist_train_data))
    self.next(self.prepare_data)

6.2 データの前処理

prepare_data関数にデータ前処理を記述します

  @step
  def prepare_data(self):
    # Extract the features and thelabel from the data
    self.X_df = self.mnist_df.drop(["label"], axis=1)
    self.Y_df = self.mnist_df.label.values
    self.next(self.split_data)

6.3 train / testデータの分割

split_data関数に学習データと検証データの分割処理を記述します

  @step
  def split_data(self):
    # Split data into train and test set
    self.X_train, self.X_test, self.Y_train, self.Y_test = train_test_split(
        self.X_df, self.Y_df, test_size=0.5, random_state=42)
    self.next(self.fit_predict_model1, self.fit_predict_model2)

6.4 model1(GaussianNB)の学習とmodel2(RandomForestClassifier)の学習して推論

fit_predict_model1関数とfit_predict_model2関数にモデル学習して推論処理を記述します

  @step
  def fit_predict_model1(self):
    modelA = GaussianNB()
    # Fit the model
    modelA.fit(self.X_train, self.Y_train)
    # predict
    self.predictionA = modelA.predict(self.X_test)
    self.next(self.join)

  @step
  def fit_predict_model2(self):
    modelB = RandomForestClassifier(random_state=1)
    # fit the model
    modelB.fit(self.X_train, self.Y_train)
    # predict
    self.predictionB = modelB.predict(self.X_test)
    self.next(self.join)

6.5 推論結果からモデルを評価

join関数で分岐処理の合流処理を記述して、evaluate関数で推論結果の評価処理を記述します

  @step
  def join(self, inputs):
    # merge artificate during a join
    self.merge_artifacts(inputs)
    self.next(self.evaluate)

  @step
  def evaluate(self):
    # measure accuracy
    print('accuracy score for gaussianNB {}'.format(
        accuracy_score(self.predictionA, self.Y_test)))
    print('accuracy score for RandomForestClassifier {}'.format(
        accuracy_score(self.predictionB, self.Y_test)))
    self.next(self.end)

スポンサーリンク

7.コマンド実行

以下コマンドで処理を実行します

python3 mnist.py run

実行すると以下のように学習から評価まで自動で実行されます

Including file mnist_train.csv of size 104MB
2023-03-05 14:38:15.704 Workflow starting (run-id 1678027093037546):
2023-03-05 14:38:15.731 [1678027093037546/start/1 (pid 120)] Task is starting.
2023-03-05 14:38:47.003 [1678027093037546/start/1 (pid 120)] Task finished successfully.
2023-03-05 14:38:47.075 [1678027093037546/prepare_data/2 (pid 136)] Task is starting.
2023-03-05 14:39:13.454 [1678027093037546/prepare_data/2 (pid 136)] Task finished successfully.
2023-03-05 14:39:13.496 [1678027093037546/split_data/3 (pid 152)] Task is starting.
2023-03-05 14:39:36.280 [1678027093037546/split_data/3 (pid 152)] Task finished successfully.
2023-03-05 14:39:36.314 [1678027093037546/fit_predict_model1/4 (pid 168)] Task is starting.
2023-03-05 14:39:36.347 [1678027093037546/fit_predict_model2/5 (pid 169)] Task is starting.
2023-03-05 14:39:53.368 [1678027093037546/fit_predict_model1/4 (pid 168)] Task finished successfully.
2023-03-05 14:40:26.838 [1678027093037546/fit_predict_model2/5 (pid 169)] Task finished successfully.
2023-03-05 14:40:26.870 [1678027093037546/join/6 (pid 200)] Task is starting.
2023-03-05 14:40:32.795 [1678027093037546/join/6 (pid 200)] Task finished successfully.
2023-03-05 14:40:32.824 [1678027093037546/evaluate/7 (pid 216)] Task is starting.
2023-03-05 14:40:36.462 [1678027093037546/evaluate/7 (pid 216)] accuracy score for gaussianNB 0.5673666666666667
2023-03-05 14:40:36.475 [1678027093037546/evaluate/7 (pid 216)] accuracy score for RandomForestClassifier 0.9627
2023-03-05 14:40:37.028 [1678027093037546/evaluate/7 (pid 216)] Task finished successfully.
2023-03-05 14:40:37.060 [1678027093037546/end/8 (pid 232)] Task is starting.
2023-03-05 14:40:40.722 [1678027093037546/end/8 (pid 232)] finished
2023-03-05 14:40:41.278 [1678027093037546/end/8 (pid 232)] Task finished successfully.
2023-03-05 14:40:41.285 Done!

deeplearning関連記事

technoxs-stacker.hatenablog.com technoxs-stacker.hatenablog.com technoxs-stacker.hatenablog.com

参考

cloud.google.com medium.com