ちょっと話題の記事

【初心者向け】Amazon SageMakerではじめる機械学習 #SageMaker

Amazon SageMaker の公式開発者ガイドの「開始方法」の手順に沿って手を動かすと、初心者でもすぐにAWSを使った機械学習を始めることができます。この記事では、「開始方法」の手順に従い、Amazonが提供する高レベルなSageMaker用のPythonライブラリを使って、機械学習モデルを構築してデプロイするまでの流れをご説明します。
2018.07.18

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Amazon SageMaker(以下SageMaker) の公式開発者ガイドの「開始方法」の手順に沿って手を動かすと、初心者でもすぐにAWSを使った機械学習を始めることができます。

この記事では、「開始方法」の手順に従い、Amazonが提供する高レベルなSageMaker用のPythonライブラリを使って、機械学習モデルをデプロイして動作を検証するまでの流れをご説明します。

ステップ 1: 事前準備

SageMakerを使い始める前に、以下の準備を済ませておく必要があります。

AWSアカウントおよび管理ユーザーの作成

AWSアカウントを持っていない方は、こちらの手順に従いまずアカウントを作成しましょう。アカウントの作成にはクレジットカードかデビットカードが必要です。

S3バケットの作成

SageMakerが機械学習モデルのトレーニングを行う際に、以下の2種類のデータを作成します。

  • モデルのトレーニングデータ
  • モデルのトレーニング中に生成するモデルアーティファクト

これらのデータを保存するAmazon S3(以下S3)バケットを作成します。今回は、1つのバケットだけを使用しますが、データ毎に使用するバケットを分けることもできます。

バケット名には、”sagemaker”という文字列を含める必要があります。SageMakerがノートブックインスタンスを作成する時に、”sagemaker”という文字列をバケット名に含むS3バケットへのアクセスを許可するIAMロールを作成するからです。

ステップ 2: Amazon SageMaker ノートブックインスタンスの作成

事前準備が済んだら、まず、「Amazon SageMakerノートブックインスタンス」を作成します。 Amazon SageMakerノートブックインスタンスとは、Jupyter Notebookがインストールされたフルマネージドな機械学習EC2コンピューティングインスタンスのことです。

まず、AWSアカウントにログインした状態で、以下のリンクを開き、「ノートブックインスタンスの作成」をクリックします。 https://console.aws.amazon.com/sagemaker/

インスタンス名に適当な名前を設定して、「新しいロールの作成」を選択します。他の設定は全て初期状態のままにしておきます。

既存のS3バケットで使いたいものがある場合は、「指定するS3バケット」で指定することができます。今回はデフォルトの設定のまま作業を進めるので「なし」を選択して「ロールの作成」をクリックします。

IAMロールが無事作成されると、作成されたIAMロール名が表示されます。

最後に、「ノートブックインスタンスの作成」をクリックして、ノートブックインスタンスの作成を開始します。

ノートブックインスタンスの作成には数分ほどかかります。作成直後は「ステータス」が「Pending」になっています。作成が完了し、ノートブックインスタンスが利用可能になるとステータスが「InService」になります。

ステップ 3: 組み込みのアルゴリズムでモデルをトレーニングし、デプロイする

ノートブックインスタンスが利用可能になったので、MNISTという1桁の手書き数字の画像のデータセットを、K-MeansというSageMakerの組み込みアルゴリズムで分類してみます。

Jupyterノートブックの作成

ノートブックインスタンスのステータスが「InService」になったら、右の「オープン」をクリックしてJupyterノートブックを開きます。

Jupyterノートブックが開いたら、右端の「New」から「conda_python3」を選択します。新しいノートブックが作成されます。

新しいノートブックが開いたら、画面上の「Untitled」をクリックして適当な名前を入力します。

次に、以下のPythonコードをコピーして、Jupyterノートブックの最初の「セル」にペーストします。ペーストしたら、'bucket-name'をステップ1で作成したS3バケット名に書き換えてから「Run」ボタンをクリックします。

from sagemaker import get_execution_role

role = get_execution_role()
bucket='bucket-name' # 「事前準備」で作成したS3バケット名に書き換える

トレーニングデータのダウンロード、調査、および変換

MNISTデータセットのダウンロード

以下のPythonコードを2つ目のセルにペーストして、「Run」ボタンをクリックします。

%%time
import pickle, gzip, numpy, urllib.request, json

# Load the dataset
urllib.request.urlretrieve("http://deeplearning.net/data/mnist/mnist.pkl.gz", "mnist.pkl.gz")
with gzip.open('mnist.pkl.gz', 'rb') as f:
    train_set, valid_set, test_set = pickle.load(f, encoding='latin1')

トレーニングデータセットの調査

以下のPythonコードを3つ目のセルにペーストして、「Run」ボタンをクリックします。MNISTデータセットの31枚目の画像データがラベルの内容(3)と共に表示されます。

%matplotlib inline
import matplotlib.pyplot as plt
plt.rcParams["figure.figsize"] = (2,10)


def show_digit(img, caption='', subplot=None):
    if subplot==None:
        _,(subplot)=plt.subplots(1,1)
    imgr=img.reshape((28,28))
    subplot.axis('off')
    subplot.imshow(imgr, cmap='gray')
    plt.title(caption)

show_digit(train_set[0][30], 'This is a {}'.format(train_set[1][30]))

トレーニングデータセットの変換とS3へのアップロード

モデルの学習を効率良く行うために、ダウンロードしたMNISTデータセットを numpy.array フォーマットから RecordIO protobuf フォーマットに変換します。この形式は、SageMakerの全ての組み込みアルゴリズムでnumpy.arrayフォーマットよりも効率良くデータを扱うことができるフォーマットだそうです。今回は、高レベルな SageMaker 用の Python ライブラリを使用するため、ここでやる作業はありません。

モデルのトレーニング

トレーニングアルゴリズムの選定

機械学習では、通常モデルに適したアルゴリズムをみつけるための評価プロセスが必要になりますが、今回は SageMaker の組み込みアルゴリズムの1つである k-means を使うことが決まっているため評価プロセスはスキップすることができます。

トレーニングジョブの作成

以下のPythonコードを4つ目のセルにペーストして、「Run」ボタンをクリックします。

from sagemaker import KMeans

data_location = 's3://{}/kmeans_highlevel_example/data'.format(bucket)
output_location = 's3://{}/kmeans_example/output'.format(bucket)

print('training data will be uploaded to: {}'.format(data_location))
print('training artifacts will be uploaded to: {}'.format(output_location))

kmeans = KMeans(role=role,
                train_instance_count=2,
                train_instance_type='ml.c4.8xlarge',
                output_path=output_location,
                k=10,
                data_location=data_location)

トレーニングの実行

モデルのトレーニングを実行します。以下のPythonコードを5つ目のセルにペーストして、「Run」ボタンをクリックします。トレーニングの完了まで約15分ほどかかります。

%%time

kmeans.fit(kmeans.record_set(train_set[0]))

実行結果のログ表示が真っ赤で、エラーが発生したかのように見えますが、冷静にログを追ってみると”INFO”か”WARN”のログのみで、エラーは発生しておらず実行は完了しているようです。

モデルのトレーニング実行後に事前に準備したS3バケットを確認すると、モデルのトレーニングデータ・モデルのトレーニング中に生成されるモデルアーティファクトが格納されています。

Amazon SageMaker ホスティングサービスにモデルをデプロイする

SageMaker にモデルをデプロイするためには、以下の3ステップの手順を実施する必要があります。

  1. SageMaker上でモデルを作成
  2. エンドポイントの設定の作成
  3. エンドポイントの作成

高レベルPythonライブラリを使うと、deployというメソッド一つでこれらの作業を行うことができます。以下のPythonコードを6つ目のセルにペーストして、「Run」ボタンをクリックします。

%%time

kmeans_predictor = kmeans.deploy(initial_instance_count=1,
                                 instance_type='ml.m4.xlarge')

モデルの検証

モデルが無事デプロイされたので、検証を行います。以下のPythonコードを7つ目のセルにペーストして、「Run」ボタンをクリックします。

result = kmeans_predictor.predict(valid_set[0][30:31])
print(result)

valid_setデータセットの30番目の画像に対する推論結果が得られました。valid_setの30番目のデータは、クラスター4に属していることがわかります。

valid_setデータセットの先頭から100個分の推論結果を取得してみます。以下のPythonコードを8つ目のセルと9つ目のセルにペーストして、順番に「Run」ボタンをクリックします。

%%time 

result = kmeans_predictor.predict(valid_set[0][0:100])
clusters = [r.label['closest_cluster'].float32_tensor.values[0] for r in result]
for cluster in range(10):
    print('\n\n\nCluster {}:'.format(int(cluster)))
    digits = [ img for l, img in zip(clusters, valid_set[0]) if int(l) == cluster ]
    height = ((len(digits)-1)//5) + 1
    width = 5
    plt.rcParams["figure.figsize"] = (width,height)
    _, subplots = plt.subplots(height, width)
    subplots = numpy.ndarray.flatten(subplots)
    for subplot, image in zip(subplots, digits):
        show_digit(image, subplot=subplot)
    for subplot in subplots[len(digits):]:
        subplot.axis('off')

    plt.show()

推論結果が視覚化されます。クラスター4は、こんな感じに分類されています。

「トレーニングデータセットの調査」で使用したshow_digitメソッドを利用して、valid_setデータセットの30番目を表示してみると、確かにクラスター4に含まれている画像です。

ステップ 4: 使ったリソースの後始末

モデルがデプロイされて、動作していることも無事検証できましたので、リソースの後始末を行います。 引き続きの別の作業を行う場合は残しておいてもいいリソースもありますが、今回はいったん全てのリソースを削除してみます。

Amazon SageMaker リソースの削除

まず、Amazon SageMaker のダッシュボードを開きます。

エンドポイントの削除

左側の「エンドポイント」タブをクリックしてからエンドポイント一覧を表示します。作成されたエンドポイントの左側の○をクリックして、「アクション」のドロップダウンリストで「削除」を選択します。ダイアログが表示されるので、「削除」をクリックするとエンドポイントが削除されます。

エンドポイント設定の削除

左側の「エンドポイント設定」タブをクリックしてからエンドポイント設定一覧を表示します。作成されたエンドポイント設定の左側の○をクリックして、「アクション」のドロップダウンリストで「削除」を選択します。ダイアログが表示されるので、「削除」をクリックするとエンドポイント設定が削除されます。

モデルの削除

左側の「モデル」タブをクリックしてからモデル一覧を表示します。作成されたモデルの左側の○をクリックして、「アクション」のドロップダウンリストで「削除」を選択します。ダイアログが表示されるので、「削除」をクリックするとモデルが削除されます。

ノートブックインスタンスの削除

まずはノートブックインスタンスを停止する必要があります。 左側の「ノートブックインスタンス」タブをクリックしてからノートブックインスタンス一覧を表示します。作成されたノートブックインスタンスの右側の「停止」をクリックして、ステータスが「Stopped」になるのを待ちます。

次に、ノートブックインスタンスの左側の○をクリックして、「アクション」のドロップダウンリストで「削除」を選択します。ダイアログが表示されるので、「削除」をクリックするとノートブックインスタンスが削除されます。

S3バケットの削除

Amazon S3 コンソールを開いて、ステップ1で作成したバケットを選択します。

フォルダが2つ作成されているので、それぞれの中身を削除します。

最後に、S3バケット自体を削除します。

IAMロールの削除

IAM コンソールを開いて、"AmazonSageMaker-ExecutionRole-"ではじまるロール名のロールを削除します。

Cloudwatch logsの削除

Amazon CloudWatch コンソールを開いて、名前が/aws/sagemaker/ではじまるロググループをすべて削除します。

おわりに

公開されているデータセットと SageMaker の組み込みアルゴリズムを利用することで、簡単に機械学習を行うことができました。より高度な SageMaker の使い方については、記事を改めてご紹介したいと思います。

最後まで読んでいただきありがとうございました。参考になるところがありましたら、SNSでシェアしていただけると嬉しいです。コメントもお待ちしています!

参考