Azure Machine LearningワークスペースをCLIv2で操作する 入門編1-機械学習モデル作成

概要

2022年11月現在、CLIv2、SDKv2がAzure Machine Learningで提供されている最新のフレームワークです。

learn.microsoft.com

本記事はAzure Machine LearningワークスペースをCLIv2を使って操作するチュートリアルです。
使い方を習得すれば自動化パイプラインを自身で構築できるようになります。

本内容はシリーズとなっておりますので、関連記事も併せてご覧ください。

やりたいこと

Azure Machine Learningワークスペースをコマンドから操作して、モデルの登録や学習などを実施することができるようになる、というのが目指すところになります。

コマンドによる操作を覚えることで、例えば以下のような実装が可能になります。

  • モデルの訓練を自動化する
  • 推論APIのデプロイを自動化する
  • MLOpsの完全自動化

Microsoft社の提示しているML用の成熟度モデルのうち、レベル2~4を実現することができます。
learn.microsoft.com

これらの内容をいくつかの記事に分割して順番に書いていきます。 今回は自動化の前段階、CLIv2を使って手動で学習操作を実施するまでの手順を示します。

準備

コマンドによる操作はazコマンドで行うので、Azure CLIのインストールが必要になります。
Azure Machine Learningワークスペースマネージドのコンピューティングインスタンスから操作を行う場合は、すでにインストールされているため作業不要です。

learn.microsoft.com

今回実施した環境のバージョンは以下の通りです。

  "azure-cli": "2.39.0",
  "azure-cli-core": "2.39.0",
  "azure-cli-telemetry": "1.0.6",

Azure Machine Learningワークスペースはデプロイ済みとして解説を進めていきます。

また本記事ではローカル環境からではなく、再現性の高いコンピューティングインスタンス環境を使用してワークスペースを操作します。

今回はCSV形式のタイタニック号のデータを学習させてみます。

www.kaggle.com

Azure CLI 拡張機能(CLIv2)によるAzure Machine Learningの基本操作と学習の実行

ログイン

azコマンドで対象のアカウントにログインします。
ワークスペースの存在するサブスクリプションを設定します。

az login
az account set -s $subscription_id

以下のコマンドでmlコマンドの入力を省略できます。

!az configure --defaults group=$resource_group workspace=$aml_workspace

拡張機能のセットアップ

Azure CLIにAML拡張機能のCLIv2をインストールします。
2個目のコマンドでextensionsの一覧に「ml:2.4.1」が表示されていれば成功です。 3個目のコマンドでワークスペースの一覧が表示できます。

az extension add --name ml --version 2.4.1
az version
az ml workspace list

コンピューティングの作成

計算用のリソースを作成するコマンドです。
この例ではコンピューティングクラスターを作成します。
min-instancesを0に設定することで、使用していない間のコストを抑えることができます。(1以上の値にすると常時待機状態になるため、プログラムの動き出しが早くなるかわりに費用が発生します)

az ml compute create --name cpu-cluster \
  --type amlcompute \
  --min-instances 0 \
  --max-instances 1 \
  --size Standard_D2_v2 \
  --idle-time-before-scale-down 1800

費用とマネージドVMのサイズについては以下を参照ください。

azure.microsoft.com

コマンドのリファレンスです。

learn.microsoft.com

データセットの登録

タイタニック号のデータをデータセットとして登録します。
ダウンロードしてきたcsvファイルをカレントディレクトリに配置しておきます。

まずはワークスペースに送信するために必要な情報をyamlで定義します。 データセットの登録に必要な情報を記述します。

csv_register.yml

$schema: https://azuremlschemas.azureedge.net/latest/data.schema.json
name: titanic_train_dataset
description: this is training datasets.
type: uri_file
path: train.csv

コマンドで上記の定義ファイルを送信します。

az ml data create --file csv_register.yml

データセットの項目を確認すると、指定したcsvファイルが登録されています。

学習

学習環境の整備

学習にあたって、学習に使うPython環境を作成する必要があります。 OSやバージョン指定、パッケージのインストールを行います。

まずenvironmentを記述します。

environments/training-env.yml

channels:
  - defaults
  - anaconda
  - conda-forge
dependencies:
  - python=3.8.5
  - pip
  - pip:
      - azureml-defaults
      - azureml-mlflow==1.41.0
      - scikit-learn==1.0.2
      - pandas==1.1.5
      - joblib==1.0.0

次に環境をAzure Machine Learning上に登録するために必要な情報をyamlで定義します。

env_register.yml

$schema: https://azuremlschemas.azureedge.net/latest/environment.schema.json
name: sample-training-env
image: mcr.microsoft.com/azureml/openmpi3.1.2-ubuntu18.04
version: 1
conda_file: ./environments/training-env.yml
description: env description

最後にコマンドを送信します。

az ml environment create --file env_register.yml

作成した環境はワークスペースの「環境」タブから確認できます。

学習の実施

学習用のスクリプトを用意する必要があります。
今回はサンプルとして、決定木でタイタニック号のデータを学習させるものを用意しました。

scripts/train.py

# coding: utf-8
import argparse, os
import pandas as pd
import numpy as np
from sklearn.tree import DecisionTreeClassifier
import mlflow
import mlflow.sklearn

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("--input_data", type=str, help="input data")
    parser.add_argument("--output_dir", type=str, help="output dir", default="./outputs")
    args = parser.parse_args()
    return args

# define functions
def main(args):
        
    lines = [
        f"Training data path: {args.input_data}",
        f"output dir path: {args.output_dir}"
    ]
    for line in lines:
        print(line)

    # データ読み込み      
    train_data = pd.read_csv(args.input_data, delimiter=',')

    # データの変換
    ## fill nan
    train_data["Age"] = train_data["Age"].fillna(train_data["Age"].median())
    ## string->int
    train_data["Sex"][train_data["Sex"] == "male"] = 0
    train_data["Sex"][train_data["Sex"] == "female"] = 1

    # 「train」の目的変数と説明変数の値を絞りこみ
    X = train_data[["Pclass", "Sex", "Age", "Fare"]].values
    y = train_data["Survived"].values

    with mlflow.start_run():
        run_id = mlflow.active_run().info.run_id
        mlflow.autolog(log_models=False, exclusive=True)
        print('run_id = ', run_id)
        # 学習
        model = DecisionTreeClassifier(max_depth=3)
        result = model.fit(X, y)
        score = model.score(X, y)
        mlflow.log_metric('score', score)

        # モデルの登録
        os.makedirs(os.path.join(args.output_dir, 'models'), exist_ok=True)
        mlflow.sklearn.save_model(model, os.path.join(args.output_dir, 'models'))
        mlflow.log_artifacts(args.output_dir)

# run script
if __name__ == "__main__":
    args = parse_args()
    main(args)

Azure Machine Learningに対してメトリックやモデルの登録を行う際は、機能統合されているmlflowを使うのが便利です。
この辺りの詳細情報については以下をご参照ください。
learn.microsoft.com

次に学習タスクに必要な情報をyamlファイルで定義します。

train_on_remote.yml

$schema: https://azuremlschemas.azureedge.net/latest/commandJob.schema.json
experiment_name: train-cliv2-sample-exp
description: train sample cliv2
type: command
code: ./scripts
command: >-
  python train.py 
  --input_data ${{inputs.training_data}}
  --output_dir ${{outputs.outputs}}
environment: azureml:sample-training-env@latest
inputs:
  training_data:
    type: uri_file
    path: azureml:titanic_train_dataset@latest
  mlflow_exp_name: train-cliv2-sample-exp
outputs:
  outputs:
compute: azureml:cpu-cluster

以下のコマンドで学習タスクが送信されます。

az ml job create --file train_on_remote.yml

コンピューティングクラスターのmin-instancesを0にした場合は、インスタンスの作成から開始するため少し時間がかかります。
学習結果は次のように閲覧できます。

作成したモデルは「出力とログ」の項目を開き、modelsフォルダの中に格納されます。

おわりに

今回はAzure Machine LearningをCLIv2を使って操作する方法について紹介しました。 yamlファイルとコマンドによってワークスペースの操作を実現しましたが、これらをパイプラインに組み込むことで自動化を実現することができます。
推論インスタンスのデプロイや、自動化については次回以降で触れようと思います。

本記事の続きはこちらをご覧ください。

blog.jbs.co.jp

執筆担当者プロフィール
西野 佑基

西野 佑基(日本ビジネスシステムズ株式会社)

機械学習系ソリューション開発、業務Webアプリ開発、開発環境自動化などを担当。

担当記事一覧