[Amazon SageMaker] CloudWatch Logsからaccuracyに関するスコアを取得して一覧してみました

2020.05.16

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

1 はじめに

CX事業本部の平内(SIN)です。

Amazon SageMaker(以下、SageMaker)の組み込みアルゴリズム(イメージ分類)では、accuracyに関するメトリクスを自動で計算して発行しています。

そして、トレーニングの結果は、コンソールからグラフとして確認することもできます。

しかし、この機能は、トレーニングジョブ単位のため、増分学習などで、複数回に分けたジョブを俯瞰することは出来ません。また、グラフは時系列であり、epoch回数との関連を見ることは難しいと思います。

今回は、CloudWatch Logsから学習の進行の目安となる行を抜き出し、複数に分けたジョブも俯瞰できるようにしてみました。

以前、「物体検出アルゴリズム」用に書いた下記の「イメージ分類」版となります。

参考:[Amazon SageMaker] CloudWatch Logsからcross_entropyやmAPのスコアを取得して一覧してみました

2 CloudWatch Logs

SageMakerによるトレーニングのログでは、Epoch(ミニバッチ)ごとに、caccuracy の値がメトリックスとして出力されています。

ここで、caccuracyの上昇などは、モデルが十分に学習されているかどうかの目安になります。

以下は、CloudWatch Logsから"Epoch"という文字列でフィルタした出力例です。

Epoch[12] Batch [20]#011Speed: 227.297 samples/sec#011accuracy=0.879464
Epoch[12] Batch [40]#011Speed: 234.214 samples/sec#011accuracy=0.899390
Epoch[12] Batch [60]#011Speed: 233.078 samples/sec#011accuracy=0.896004
Epoch[12] Batch [80]#011Speed: 237.086 samples/sec#011accuracy=0.906636
Epoch[12] Train-accuracy=0.900735
Epoch[12] Time cost=11.420
Epoch[12] Validation-accuracy=0.931818
Epoch[13] Batch [20]#011Speed: 223.938 samples/sec#011accuracy=0.937500
Epoch[13] Batch [40]#011Speed: 223.945 samples/sec#011accuracy=0.926829
Epoch[13] Batch [60]#011Speed: 216.544 samples/sec#011accuracy=0.922131
Epoch[13] Batch [80]#011Speed: 224.821 samples/sec#011accuracy=0.931327
Epoch[13] Train-accuracy=0.924265
Epoch[13] Time cost=11.892
Epoch[13] Validation-accuracy=0.971726
Epoch[14] Batch [20]#011Speed: 223.023 samples/sec#011accuracy=0.949405
Epoch[14] Batch [40]#011Speed: 228.503 samples/sec#011accuracy=0.930640
Epoch[14] Batch [60]#011Speed: 230.378 samples/sec#011accuracy=0.939037
Epoch[14] Batch [80]#011Speed: 224.063 samples/sec#011accuracy=0.939429
Epoch[14] Train-accuracy=0.933088
Epoch[14] Time cost=11.973
Epoch[14] Validation-accuracy=0.991071

3 集計

上記のログを対象に、Train-accuracy及び、Validation-accuracyの数値を抜き出して、一覧にするコードです。 ジョブ名は、配列で指定するようになっており、複数回に分けてトレーニングしたログも纏めて処理できます。

from boto3.session import Session
import re

# Job名(複数指定可能)
jobs = ['ic-Traning-001/algo-1-1589483525']

session = Session(profile_name='developer')
client = session.client('logs')

group_name = '/aws/sagemaker/TrainingJobs'

# "Epoch" 及び "Early" が含まれるログ抽出する
filter_pattern = "?Epoch ?Early"
response = client.filter_log_events(
logGroupName=group_name,
logStreamNames=jobs,
limit=1000,
filterPattern=filter_pattern,
)

# Train-accuracy, Validation-accuracy にそれぞれ振り分ける
train = []
validation = []
early = ''
for event in response["events"]:
message = event["message"]
if("Train-accuracy" in message):
value = re.split('=', message)[1]
# 視認しやすいように、少数第三位で丸める
value = round(float(value), 3)
train.append(value)

if("Validation-accuracy" in message):
value = re.split('=', message)[1]
# 視認しやすいように、少数第三位で丸める
value = round(float(value), 3)
validation.append(value)
if("criteria" in message): # Early stopping で停止した場合にログ出力する
early = message[message.find('Early'):]
# 表示
print("epoch\tTrain-accuracy\tValidation-accuracy")
print("-----------------------------------------")
for i in range(len(train)):
print("{}\t{}\t{}".format(i, train[i], validation[i]))
print(early)

出力結果です。ここで表示されているEpochは、ログが抽出したものではなく、単純に0からの連番になっているため、ストリームを複数指定したは、増分学習のログという前提です。 なお、早期に学習が止まった場合のログである、 "Early stopping criteria met." についても出力しています。

epoch Train-accuracy Validation-accuracy
-----------------------------------------
0 0.173 0.149
1 0.185 0.381
2 0.45 0.695
3 0.675 0.824
4 0.793 0.874
5 0.867 0.943
6 0.888 0.942
7 0.886 0.967
8 0.886 0.92
9 0.902 0.964
10 0.887 0.954
11 0.896 0.96
12 0.901 0.932
13 0.924 0.972
14 0.933 0.991
15 0.935 1.0
16 0.933 0.997
17 0.967 0.997
18 0.969 0.999
19 0.973 1.0
20 0.982 1.0
Early stopping criteria met.

4 最後に

今回は、複数に分けて行ったイメージ分類のトレーニング状況をEpochと共に俯瞰してみました。

一覧では、数値の桁数を丸めたりしていますが、このように、一定の形式で学習の進度を俯瞰することは有効なのではないかと考えています。