AI Platform Training での scikit-learn によるトレーニング

AI Platform Training トレーニング サービスでは、クラウド内のコンピューティング リソースを管理してモデルをトレーニングします。このページでは、AI Platform Training を使用して scikit-learn モデルをトレーニングするプロセスについて説明します。

このチュートリアルでは、国勢調査所得データセットに基づいて所得水準を予測する簡単なモデルをトレーニングします。トレーニング アプリケーションをローカルに作成し、Cloud Storage にアップロードして、トレーニング ジョブを送信します。AI Platform Training トレーニング サービスの出力は Cloud Storage バケットに書き込まれ、Logging にログが作成されます。

このコンテンツは、GitHub にも Jupyter ノートブックとして公開されています。

AI Platform Training でモデルをトレーニングする方法

AI Platform Training では、次の 3 つのステップでモデルをトレーニングできます。

  • Python モデルファイルを作成する
    • Cloud Storage からデータをダウンロードして AI Platform Training で使用するためのコードを追加する
    • AI Platform Training でモデルのトレーニングが完了した後にモデルを Cloud Storage にエクスポートして保存するためのコードを追加する
  • トレーニング アプリケーション パッケージを準備する
  • トレーニング ジョブを送信する

始める前に

次の操作を行って GCP アカウントを設定し、AI Platform Training API を有効にします。さらに、Cloud SDK をインストールして有効にします。

GCP プロジェクトを設定する

  1. Google アカウントにログインします。

    Google アカウントをまだお持ちでない場合は、新しいアカウントを登録します。

  2. Cloud Console のプロジェクト セレクタページで、Cloud プロジェクトを選択または作成します。

    プロジェクト セレクタのページに移動

  3. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  4. AI Platform Training & Prediction and Compute Engine API を有効にします。

    API を有効にする

  5. Cloud SDK をインストールして初期化します。

環境の設定

以下のいずれかのオプションを選択して、macOS のローカル環境または Cloud Shell のリモート環境を設定します。

macOS の場合、以下の [MACOS] タブで環境を設定することをおすすめします。[CLOUD SHELL] タブに表示される Cloud Shell は、macOS、Linux、Windows で使用できます。Cloud Shell は、AI Platform Training の機能を試すような場合には便利ですが、継続的な開発作業には適していません。

macOS

  1. Python のインストールを確認する
    Python がインストールされていることを確認します。されていない場合はインストールします。

    python -V
  2. pip のインストールを確認する
    pip は、Python のパッケージ マネージャーであり、Python の現在のバージョンに含まれています。pip --version コマンドを実行して、pip がすでにインストールされているかどうかを確認します。インストールされていない場合は、pip のインストール方法をご覧ください。

    次のコマンドを使用すると、pip をアップグレードできます。

    pip install -U pip

    詳細については、pip のドキュメントをご覧ください。

  3. virtualenv をインストールする
    virtualenv は隔離された Python 環境を作成するツールです。次のコマンドを実行して、virtualenv がすでにインストールされているかどうかを確認します。virtualenv --version。インストールされていない場合は、virtualenv をインストールします。

    pip install --user --upgrade virtualenv

    このガイド用に隔離された開発環境を作成するために、virtualenv で新しい仮想環境を作成します。たとえば、次のコマンドは、cmle-env という名前の環境をアクティブにします。

    virtualenv cmle-env
    source cmle-env/bin/activate
  4. このチュートリアルでは、仮想環境内で残りのコマンドを実行します。

    virtualenv の使用方法の詳細をご覧ください。virtualenv を終了するには、deactivate を実行します。

Cloud Shell

  1. Google Cloud Console を開きます。

    Google Cloud Console

  2. コンソール ウィンドウの上部にある [Google Cloud Shell をアクティブにする] ボタンをクリックします。

    Google Cloud Shell をアクティブにする

    コンソールの下部の新しいフレーム内で Cloud Shell セッションが開き、コマンドライン プロンプトが表示されます。シェル セッションが初期化されるまで、数秒かかる場合があります。

    Cloud Shell セッション

    Cloud Shell セッションが使用できる状態になります。

  3. 選択したプロジェクトを使用するように gcloud コマンドライン ツールを構成します。

    gcloud config set project [selected-project-id]

    ここで、[selected-project-id] はプロジェクト ID ですID を囲んでいる角かっこは不要です。

フレームワークをインストールする

macOS

仮想環境内で次のコマンドを実行して、AI Platform Training ランタイム バージョン 2.1 で使用する scikit-learn および pandas をインストールします。

(cmle-env)$ pip install scikit-learn==0.22 pandas==0.25.3

上記のコマンドでバージョン番号を指定して、仮想環境内の依存関係とランタイム バージョン内の依存関係を一致させます。これによって、AI Platform Training でコードを実行するときの予期しない動作を防ぎます。

インストール オプションやトラブルシューティング情報などの詳細については、各フレームワークのインストール手順をご覧ください。

Cloud Shell

次のコマンドを実行して、scikit-learn、pandas をインストールします。

pip install --user scikit-learn pandas

インストール オプションやトラブルシューティング情報などの詳細については、各フレームワークのインストール手順をご覧ください。

Cloud Storage バケットを設定する

トレーニング コードと依存関係を保存するための Cloud Storage バケットが必要です。このチュートリアルでは、AI Platform Training に使用しているのと同じプロジェクトで専用の Cloud Storage バケットを使用する方法が最も簡単です。

別のプロジェクトのバケットを使用する場合は、AI Platform Training サービス アカウントが Cloud Storage 内のトレーニング コードと依存関係にアクセスできるようにする必要があります。適切な権限がないと、トレーニング ジョブは失敗します。ストレージの権限を付与する方法をご覧ください。

必ず、トレーニング ジョブを実行するために使用しているのと同じリージョンのバケットを使用または設定してください。AI Platform Training サービスに利用可能なリージョンをご覧ください。

このセクションでは、新しいバケットの作成方法を説明します。既存のバケットを使用することもできますが、AI Platform ジョブを実行する予定のリージョンと同じリージョンにある必要があります。また、AI Platform Training を実行するプロジェクトに含まれていない場合は、明示的に AI Platform Training サービス アカウントへのアクセスを許可する必要があります。

  1. 新しいバケットに名前を指定します。名前は Cloud Storage のすべてのバケット全体で重複しないようにする必要があります。

    BUCKET_NAME="your_bucket_name"

    たとえば、プロジェクト名に -aiplatform を追加したものを使います。

    PROJECT_ID=$(gcloud config list project --format "value(core.project)")
    BUCKET_NAME=${PROJECT_ID}-aiplatform
  2. 作成したバケット名を確認します。

    echo $BUCKET_NAME
  3. バケットのリージョンを選択して、REGION 環境変数を設定します。

    AI Platform Training ジョブを実行する予定のリージョンと同じリージョンを使用してください。AI Platform Training サービスに利用可能なリージョンをご覧ください。

    たとえば、次のコードは REGION を作成し、us-central1 に設定します。

    REGION=us-central1
  4. 新しいバケットを作成します。

    gsutil mb -l $REGION gs://$BUCKET_NAME

データについて

このサンプルでトレーニングに使用している国勢調査所得データセットは、UC Irvine Machine Learning Repository でホストされています。

国勢調査データ転載元: Lichman, M.2013。UCI Machine Learning Repository http://archive.ics.uci.edu/ml。Irvine, CA: University of California, School of Information and Computer Science。このデータセットは、データセット ソース(http://archive.ics.uci.edu/ml)で指定される次の条件の下ですべてのユーザーが使用できるように公開されています。Google はこのデータセットを「現状有姿」で提供し、明示または黙示を問わず、いかなる保証も行いません。Google は、このデータセットの使用で、直接または間接の損害が発生したとしても一切の責任を負いません。

便利にお使いいただけるように、Google は公開されている Cloud Storage バケット gs://cloud-samples-data/ai-platform/sklearn/census_data/ にデータをホストしています。このデータは、Python トレーニング ファイル内でダウンロードできます。

Python モデルファイルの作成

このセクションのすべてのトレーニングコードは GitHub train.py にあります。

このセクションの残りの部分では、トレーニング コードの動作について説明します。

設定

Python、Cloud SDK、scikit-learn から、以下のライブラリをインポートします。Cloud Storage バケットの名前のための変数を設定します。

import datetime
import pandas as pd

from google.cloud import storage

from sklearn.ensemble import RandomForestClassifier
from sklearn.externals import joblib
from sklearn.feature_selection import SelectKBest
from sklearn.pipeline import FeatureUnion
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import LabelBinarizer

# TODO: REPLACE 'YOUR_BUCKET_NAME' with your GCS Bucket name.
BUCKET_NAME = 'YOUR_BUCKET_NAME'

Cloud Storage からデータをダウンロードする

一般的な開発プロセスでは、データを Cloud Storage にアップロードして、AI Platform Training がそのデータにアクセスできるようにします。このチュートリアルのデータは、公開バケット(gs://cloud-samples-data/ai-platform/sklearn/census_data/)にホストされています。

以下のコードはトレーニング データセット adult.data をダウンロードします(評価データは adult.test にありますが、このチュートリアルでは使用しません。)

# Public bucket holding the census data
bucket = storage.Client().bucket('cloud-samples-data')

# Path to the data inside the public bucket
blob = bucket.blob('ai-platform/sklearn/census_data/adult.data')
# Download the data
blob.download_to_filename('adult.data')

モデルコードを追加する

モデルのトレーニング コードでは、いくつかの基本操作を行います。

  • データを定義して読み込む
  • カテゴリの特徴を数値の特徴に変換する
  • scikit-learn パイプラインを使用して数値の特徴を抽出する
  • モデルを Cloud Storage にエクスポートして保存する

データを定義して読み込む

# Define the format of your input data including unused columns (These are the columns from the census data files)
COLUMNS = (
    'age',
    'workclass',
    'fnlwgt',
    'education',
    'education-num',
    'marital-status',
    'occupation',
    'relationship',
    'race',
    'sex',
    'capital-gain',
    'capital-loss',
    'hours-per-week',
    'native-country',
    'income-level'
)

# Categorical columns are columns that need to be turned into a numerical value to be used by scikit-learn
CATEGORICAL_COLUMNS = (
    'workclass',
    'education',
    'marital-status',
    'occupation',
    'relationship',
    'race',
    'sex',
    'native-country'
)

# Load the training census dataset
with open('./adult.data', 'r') as train_data:
    raw_training_data = pd.read_csv(train_data, header=None, names=COLUMNS)

# Remove the column we are trying to predict ('income-level') from our features list
# Convert the Dataframe to a lists of lists
train_features = raw_training_data.drop('income-level', axis=1).values.tolist()
# Create our training labels list, convert the Dataframe to a lists of lists
train_labels = (raw_training_data['income-level'] == ' >50K').values.tolist()

カテゴリの特徴を数値の特徴に変換する

# Since the census data set has categorical features, we need to convert
# them to numerical values. We'll use a list of pipelines to convert each
# categorical column and then use FeatureUnion to combine them before calling
# the RandomForestClassifier.
categorical_pipelines = []

# Each categorical column needs to be extracted individually and converted to a numerical value.
# To do this, each categorical column will use a pipeline that extracts one feature column via
# SelectKBest(k=1) and a LabelBinarizer() to convert the categorical value to a numerical one.
# A scores array (created below) will select and extract the feature column. The scores array is
# created by iterating over the COLUMNS and checking if it is a CATEGORICAL_COLUMN.
for i, col in enumerate(COLUMNS[:-1]):
    if col in CATEGORICAL_COLUMNS:
        # Create a scores array to get the individual categorical column.
        # Example:
        #  data = [39, 'State-gov', 77516, 'Bachelors', 13, 'Never-married', 'Adm-clerical',
        #         'Not-in-family', 'White', 'Male', 2174, 0, 40, 'United-States']
        #  scores = [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        #
        # Returns: [['State-gov']]
        # Build the scores array.
        scores = [0] * len(COLUMNS[:-1])
        # This column is the categorical column we want to extract.
        scores[i] = 1
        skb = SelectKBest(k=1)
        skb.scores_ = scores
        # Convert the categorical column to a numerical value
        lbn = LabelBinarizer()
        r = skb.transform(train_features)
        lbn.fit(r)
        # Create the pipeline to extract the categorical feature
        categorical_pipelines.append(
            ('categorical-{}'.format(i), Pipeline([
                ('SKB-{}'.format(i), skb),
                ('LBN-{}'.format(i), lbn)])))

scikit-learn パイプラインを使用して数値の特徴を抽出する

# Create pipeline to extract the numerical features
skb = SelectKBest(k=6)
# From COLUMNS use the features that are numerical
skb.scores_ = [1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0]
categorical_pipelines.append(('numerical', skb))

# Combine all the features using FeatureUnion
preprocess = FeatureUnion(categorical_pipelines)

# Create the classifier
classifier = RandomForestClassifier()

# Transform the features and fit them to the classifier
classifier.fit(preprocess.transform(train_features), train_labels)

# Create the overall model as a single pipeline
pipeline = Pipeline([
    ('union', preprocess),
    ('classifier', classifier)
])

モデルを Cloud Storage にエクスポートして保存する

Cloud Storage バケットが AI Platform Training で使用しているのと同じプロジェクトにある場合、AI Platform Training はそのバケットの読み取りと書き込みを行うことができます。そうでない場合は、AI Platform Training の実行で使用しているプロジェクトがその Cloud Storage バケットにアクセスできるようにする必要があります。ストレージの権限を付与する方法をご覧ください。

モデルファイルを使用して AI Platform Training でオンライン予測をリクエストする場合は、モデルファイルに model.pkl または model.joblib という名前を付けてください。

# Export the model to a file
model = 'model.joblib'
joblib.dump(pipeline, model)

# Upload the model to GCS
bucket = storage.Client().bucket(BUCKET_NAME)
blob = bucket.blob('{}/{}'.format(
    datetime.datetime.now().strftime('census_%Y%m%d_%H%M%S'),
    model))
blob.upload_from_filename(model)

モデルファイルが Cloud Storage にアップロードされていることを確認する(省略可)

コマンドラインで、保存先のモデルフォルダの内容を表示して、モデルファイルが Cloud Storage にアップロードされていることを確認します。バケット名の環境変数(BUCKET_ID)をまだ設定していない場合は、設定します。

gsutil ls gs://$BUCKET_ID/census_*

出力は次のようになります。

gs://[YOUR-PROJECT-ID]/census_[DATE]_[TIME]/model.joblib

トレーニング アプリケーション パッケージを作成する

トレーニング アプリケーション パッケージを作成する最も簡単な(推奨される)方法は、トレーニング ジョブを送信するときに gcloud を使ってアプリケーションをパッケージしてアップロードするという方法です。この方法では、ファイルが 2 つのみ含まれる非常に単純なファイル構造を作成するだけで済みます。このチュートリアルでは、トレーニング アプリケーション パッケージのファイル構造は次のようになります。

census_training/
    __init__.py
    train.py
  1. ディレクトリをローカルに作成します。

    mkdir census_training
    
  2. __init__.py という名前の空のファイルを作成します。

    touch census_training/__init__.py
    
  3. トレーニング コードを 1 つの Python ファイルに保存し、そのファイルを census_training ディレクトリ内に保存します。train.py のサンプルコードをご覧ください。cURL を使用してファイルをダウンロードして保存できます。

    curl https://raw.githubusercontent.com/GoogleCloudPlatform/cloudml-samples/master/sklearn/notebooks/census_training/train.py > census_training/train.py
    

詳細については、トレーニング アプリケーションのパッケージングをご覧ください。

トレーニング ジョブの送信

このセクションでは、gcloud ai-platform jobs submit training を使ってトレーニング ジョブを送信します。

トレーニング ジョブのパラメータを指定する

トレーニング ジョブ リクエストの各パラメータに次の環境変数を設定します。

  • PROJECT_ID - Google Cloud プロジェクトに対応した PROJECT_ID を使用します。
  • BUCKET_ID - Cloud Storage バケットの名前。
  • JOB_NAME - ジョブに使用する名前(英大文字と小文字、数字、アンダースコアのみを使用でき、先頭は文字にする必要があります)。ここでは、census_training_$(date +"%Y%m%d_%H%M%S") としています。
  • JOB_DIR - トレーニング ジョブの出力ファイルに使用する Cloud Storage の場所のパス。(例: gs://$BUCKET_ID/scikit_learn_job_dir)。
  • TRAINING_PACKAGE_PATH - トレーニング アプリケーションのルート ディレクトリのローカルパス。ここでは、./census_training/ としています。
  • MAIN_TRAINER_MODULE - AI Platform Training トレーニング サービスで実行するファイルを指定します。形式は [YOUR_FOLDER_NAME.YOUR_PYTHON_FILE_NAME] です。ここでは census_training.train としています。
  • REGION - トレーニング ジョブの実行に使用しているリージョンの名前。AI Platform Training トレーニング サービスに利用可能なリージョンのいずれかを使用します。Cloud Storage バケットが同じリージョンにあることを確認してください。
  • RUNTIME_VERSION - scikit-learn をサポートする AI Platform Training のランタイム バージョンを指定する必要があります。この例では、2.1 です。
  • PYTHON_VERSION - ジョブに使用する Python のバージョン。このチュートリアルでは Python 3.7 を指定します。
  • SCALE_TIER - トレーニング ジョブを実行するマシンの事前定義されたクラスタ仕様。ここでは、BASIC としています。カスタム スケール階層を使用して、トレーニング用の独自のクラスタ構成を定義することもできます。

このチュートリアルの環境変数は以下のとおりです。[VALUES-IN-BRACKETS] を適切な値に置き換えます。

PROJECT_ID=[YOUR-PROJECT-ID]
BUCKET_ID=[YOUR-BUCKET-ID]
JOB_NAME=census_training_$(date +"%Y%m%d_%H%M%S")
JOB_DIR=gs://$BUCKET_ID/scikit_learn_job_dir
TRAINING_PACKAGE_PATH="[YOUR-LOCAL-PATH-TO-TRAINING-PACKAGE]/census_training/"
MAIN_TRAINER_MODULE=census_training.train
REGION=us-central1
RUNTIME_VERSION=2.1
PYTHON_VERSION=3.7
SCALE_TIER=BASIC

リクエストを送信します。

gcloud ai-platform jobs submit training $JOB_NAME \
  --job-dir $JOB_DIR \
  --package-path $TRAINING_PACKAGE_PATH \
  --module-name $MAIN_TRAINER_MODULE \
  --region $REGION \
  --runtime-version=$RUNTIME_VERSION \
  --python-version=$PYTHON_VERSION \
  --scale-tier $SCALE_TIER

出力は次のようになります。

Job [census_training_[DATE]_[TIME]] submitted successfully.
Your job is still active. You may view the status of your job with the command

  $ gcloud ai-platform jobs describe census_training_[DATE]_[TIME]

or continue streaming the logs with the command

  $ gcloud ai-platform jobs stream-logs census_training_[DATE]_[TIME]
jobId: census_training_[DATE]_[TIME]
state: QUEUED

トレーニング ログの表示(省略可)

AI Platform Training はすべての stdout ストリームと stderr ストリーム、ログ ステートメントをキャプチャします。これらのログは Logging に保存されます。これらは実行中でも、実行後でも表示できます。

トレーニング ジョブのログを表示するには:

Console

  1. AI Platform Training の [ジョブ] ページを開きます。

    Cloud Console でジョブを開く

  2. 確認するトレーニング ジョブの名前を選択します。選択したトレーニング ジョブの [ジョブの詳細] ページが表示されます。

  3. [ジョブの詳細] の内部で、[ログを表示] リンクを選択します。[Logging] ページが表示され、選択したトレーニング ジョブのログを検索したり、フィルタリングしたりできます。

gcloud

gcloud ai-platform jobs stream-logs を使用して、ターミナルでログを表示できます。

gcloud ai-platform jobs stream-logs $JOB_NAME

次のステップ