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

2020.04.24

1 はじめに

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

Amazon SageMaker(以下、SageMaker)の組み込みアルゴリズムでは、トレーニング、評価、および検証メトリクスを自動で計算して発行しています。

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

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

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

2 CloudWatch Logs

SageMakerによるトレーニングのログでは、Epochごとに、cross_entropy (loass)、smooth_l1(loss) 及び、mAPの(score)の値がメトリックスとして出力されています。

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

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

epoch=0, batch=113 train cross_entropy <loss>=(1.4180332298993061)
epoch=0, batch=113 train smooth_l1 <loss>=(0.6312907669714584)
epoch=0, validation mAP <score>=(0.06950676633142766)
epoch=1, batch=113 train cross_entropy <loss>=(1.1537240667553887)
epoch=1, batch=113 train smooth_l1 <loss>=(0.5577520465688716)
epoch=1, validation mAP <score>=(0.5435744797706069)
epoch=2, batch=113 train cross_entropy <loss>=(0.882764700426082)
epoch=2, batch=113 train smooth_l1 <loss>=(0.4858317924157635)
epoch=2, validation mAP <score>=(0.7965334703107155)
epoch=3, batch=113 train cross_entropy <loss>=(0.7305765847092396)
epoch=3, batch=113 train smooth_l1 <loss>=(0.3920442789711215)
epoch=3, validation mAP <score>=(0.9287345323256168)
epoch=4, batch=113 train cross_entropy <loss>=(0.6735127696786309)
epoch=4, batch=113 train smooth_l1 <loss>=(0.32503517851902314)
epoch=4, validation mAP <score>=(0.983961968966895)
epoch=5, batch=113 train cross_entropy <loss>=(0.6005626925608006)
epoch=5, batch=113 train smooth_l1 <loss>=(0.2669418989158258)
epoch=5, validation mAP <score>=(0.9913976509103337)

3 集計

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

from boto3.session import Session
import re

# Job名(複数指定可能)
jobs = ['object-detection-2020-04-24-23-53-37-140/algo-1-1587772559']

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

group_name = '/aws/sagemaker/TrainingJobs'

# "epoch="が含まれるログ抽出する
filter_pattern = 'epoch='
response = client.filter_log_events(
            logGroupName=group_name,
            logStreamNames=jobs,
            limit=300,
            filterPattern=filter_pattern,
)

# cross_entropy, smooth_l1, mAPにそれぞれ振り分ける
cross_entropy = []
smooth_l1 = []
mAP = []
for event in response["events"]:
    message = event["message"]
    print(message) # debug

    # ()の中を抜き出す
    m = re.search(r'\(.*\)', message)
    num = m.group().replace('(','').replace(')','')
    # 視認しやすいように、少数第三位で丸める
    num = round(float(num), 3) 

    if('cross_entropy' in message):
        cross_entropy.append(num)
    elif('smooth_l1' in message):
        smooth_l1.append(num)
    elif('mAP' in message):
        mAP.append(num)

# 表示
print("epoch\tmAP\tsmooth_l1\tcross_entropy")
print("-----------------------------------------")
for i in range(len(mAP)):
    print("{}\t{}\t{}\t{}".format(i, mAP[i], smooth_l1[i], cross_entropy[i]))

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

epoch   mAP     smooth_l1       cross_entropy
-----------------------------------------
0       0.07    0.631   1.418
1       0.544   0.558   1.154
2       0.797   0.486   0.883
3       0.929   0.392   0.731
4       0.984   0.325   0.674
5       0.991   0.267   0.601
6       0.991   0.239   0.547
7       0.991   0.214   0.502
8       0.992   0.198   0.465
9       0.992   0.177   0.449
10      0.994   0.159   0.419

4 最後に

今回は、複数に分けて行ったトレーニングの状況をEpochと共に俯瞰してみました。次回は、HPO(ハイパーパラメータ最適化)アルゴリズムで学習が進行する状況を、この一覧で確認してみたいと考えています。

5 参考にさせて頂いたリンク


Amazon SageMaker でモデルトレーニング中にメトリクスを簡単にモニタリングして視覚化する