SageMakerの物体検出によるオブジェクトカウント

SageMakerの物体検出によるオブジェクトカウント

Ground Truthで画像にラベルを付け、SageMakerの物体検出モデルを学習させ、推論結果からオブジェクトをカウントする。

Takahiro Iwasa
12 min read

Ground Truthでの画像ラベリングからモデルの学習・デプロイ、推論の実行までを通しで扱います。

ℹ️ Note

この記事内の画像は説明用のものであり、特定の顧客プロジェクトとは関係ありません。

なお、SageMakerの推論エンドポイントはテスト目的での利用にとどめています。

Ground Truthによるラベリング

ラベリングワークフォースの作成

ラベリングを始めるには、まずラベリングワークフォースをセットアップする必要があります。この記事ではプライベートワークフォースを作成します。チームメンバーはCognitoまたはOIDCで認証できます。

ワークフォースが作成されると、招待メールがワーカーに送信されます。このメールにはラベリングポータルへのURLが含まれています。

ラベリングポータルのURLは、SageMaker管理コンソールのPrivate workforce summary > Labeling portal sign-in URLからも取得できます。

ワーカーは招待メールの手順に従ってサインアップし、ラベリングポータルにアクセスする必要があります。

招待メールの例は以下のとおりです。

Hi,
You are invited by [email protected] from <COMPANY> to work on a labeling project.
Click on the link below to log into your labeling project.
"https://<LABELING_PORTAL_URL>"
You will need the following username and temporary password provided below to login for the first time.
User name: <USER_NAME>
Temporary password: <PASSWORD>
Once you log in with your temporary password, you will be required to create a new password for your account.
After creating a new password, you can log into your private team to access your labeling project.
If you have any questions, please contact us at [email protected].

URLにアクセスした後、ワーカーは招待メールに記載されたユーザー名と一時パスワードを入力する必要があります。

その後、一時パスワードを新しいパスワードに変更するよう求められます。

ログインに成功すると、ワーカーはラベリングポータルのトップページにリダイレクトされます。割り当てられたラベリングジョブがこのページに表示されます。

ラベリングジョブの作成

SageMaker管理コンソールに戻り、新しいラベリングジョブの作成を開始します。以下の画像に示すとおり必要な項目を入力します。プロセスを完了させるために、必ずComplete data setupをクリックしてください。

💡 Tip

ラベリングジョブを作成した後は削除できません。次のようなコマンドで生成した一意な値を使用してください: uuidgen | tr "[:upper:]" "[:lower:]"

複雑なラベリングタスクの場合は、Task timeoutパラメータに長めの値を指定することを検討してください。

ラベリングの開始

ラベリングポータルにサインインすると、先ほど作成したラベリングジョブが表示されるはずです。Start workingボタンをクリックして開始します。

ℹ️ Note

ラベリングジョブが一覧に表示されるまで、しばらく時間がかかることがあります。

ジョブの指示に従ってデータセットにラベルを付けます。以下はラベル付けされたデータセットの例です。

すべてのワーカーがタスクを完了したら、ラベリングジョブを停止します。

ラベリング出力の確認

ラベリングジョブが停止すると、最終的な出力が指定したS3バケットに保存されます。物体検出タスクにおいては、manifests/output/output.manifestファイルが重要です。詳細は公式ドキュメントを参照してください。

Terminal window
annotation-tool/
annotations/
consolidated-annotation/
worker-response/
manifests/
intermediate/
output/
output.manifest
temp/

Ground TruthはAugmented Manifest形式でラベリング結果を生成します。詳細は公式ドキュメントを確認してください。

SageMakerによる学習

ラベリングプロセスが完了したら、SageMakerコンソールを使ってモデルの学習に進みます。学習ジョブを以下のように設定します。

  • Job settings
  • Job name: 一意な値を使用します(例: uuidgen | tr "[:upper:]" "[:lower:]")。
  • Algorithm source: SageMaker built-in algorithm
  • Choose an algorithm:
  • Algorithm: Vision - Object Detection (MXNet)
  • Input mode: Pipe
  • Resource configuration
  • Instance type: ml.p2.xlargeのようなGPUインスタンスを使用します。
  • SageMakerの物体検出アルゴリズムをサポートするのはGPUインスタンスのみです。
  • Hyperparameters
  • num_classes: オブジェクトクラスの数を設定します(本記事では1)。
  • num_training_samples: マニフェストファイルの行数と同じ値にします。
  • Input data configuration
  • Training channel
  • Channel name: train
  • Input mode: Pipe
  • Content type: application/x-recordio
  • Record wrapper: RecordIO
  • Data source: S3 (Augmented Manifest File)
  • Attribute names: source-refやバウンディングボックスのデータキーなどの属性を含めます。
  • S3 location: 学習データのマニフェストファイルのS3 URIを指定します。
  • Validation channel
  • Channel name: validation
  • Output data configuration
  • S3 location: モデルアーティファクトを保存するS3 URIを指定します。

Augmented Manifest形式を利用することで、追加のRecordIOファイルを作成することなくPipe入力モードとRecordIOラッパー型を使用できます。詳細は公式ドキュメントを参照してください。

推論

学習ジョブからモデルを作成する

完了した学習ジョブからモデルを作成するには、SageMakerコンソールでCreate modelをクリックします。

モデルのデプロイ

モデルを作成したら、Create endpointをクリックしてデプロイします。コスト効率よく低頻度で使用する場合は、サーバーレスエンドポイントの利用を検討してください。

リクエストの送信

エンドポイント詳細ページでSageMaker推論エンドポイントを確認します。このエンドポイントにはcurlPostman、独自のアプリケーションなどからアクセスできます。

🔥 Caution

SageMakerの推論エンドポイントを本番ワークロードに直接使用することは推奨されません。この例はあくまでテスト目的でのエンドポイント使用方法を示しています。

例: Postmanの設定

AWS Signature V4による認証には、以下のパラメータを使用します。

  • AccessKey
  • SecretKey
  • Session Token: 永続的な認証情報ではなく、一時的な認証情報を使用してください。
  • AWS Region: SageMakerエンドポイントのリージョン。
  • Service Name: sagemaker

リクエストにAccept: application/jsonヘッダーを設定します。

学習済みモデルはバイナリの画像入力を期待するため、画像がバイナリ形式で渡されるようにしてください。

例: AWS SDK(boto3)の使用

boto3のinvoke_endpoint APIを使って、プログラムから推論を実行することもできます。以下はスクリプトの例です。

import json
import boto3
# Initialize SageMaker runtime client
runtime = boto3.client('sagemaker-runtime')
# Define endpoint and input details
endpoint_name = '<YOUR_ENDPOINT_NAME>'
content_type = 'application/x-image'
payload = None
# Read the image file in binary mode
with open('/path/to/image.jpg', 'rb') as f:
payload = f.read()
# Invoke the endpoint
response = runtime.invoke_endpoint(
EndpointName=endpoint_name,
ContentType=content_type,
Body=payload
)
# Parse and display the response
body = response['Body'].read()
predictions = json.loads(body.decode())
print(json.dumps(predictions, indent=2))
# Save the response to a file
with open('./response.json', 'w') as f:
json.dump(predictions, f, indent=2)

レスポンスの確認

レスポンスはJSON形式で返され、以下を含みます。

  • クラスラベルID
  • 信頼度スコア
  • バウンディングボックスの座標
ℹ️ Note

バウンディングボックスの座標は実際の画像サイズに対する相対値です。詳細は公式ドキュメントを参照してください。

{
"prediction": [
[
0.0,
0.9953756332397461,
0.3821756839752197,
0.007661208510398865,
0.525381863117218,
0.19436971843242645
],
[
0.0,
0.9928023219108582,
0.3435703217983246,
0.23781903088092804,
0.5533013343811035,
0.6385164260864258
],
[
0.0,
0.9911478757858276,
0.15510153770446777,
...
0.9990172982215881
]
]
}

レスポンスの可視化

推論結果を視覚的に解釈するには、Jupyter Notebookmatplotlibを組み合わせて使用できます。

以下のPythonスクリプトは、入力画像にバウンディングボックスと注釈を重ねて表示する方法を示しています。

import json
import matplotlib.patches as patches
import matplotlib.pyplot as plt
from PIL import Image
# Configure plot
plt.figure()
axes = plt.axes()
# Read an image
im = Image.open('/path/to/image.jpg')
# Display the image
plt.imshow(im)
# Read SageMaker inference predictions
with open('response.json') as f:
predictions = json.loads(f.read())['prediction']
# Set initial count
count = 0
# Create rectangles
for prediction in predictions:
score = prediction[1]
if score < 0.2:
continue
# Count up
count += 1
x = prediction[2] * im.width
y = prediction[3] * im.height
width = prediction[4] * im.width - x
height = prediction[5] * im.height - y
rect = patches.Rectangle((x, y), width, height, linewidth=1, edgecolor='r', facecolor='none')
axes.annotate(count, (x + width / 2, y + height / 2), color='yellow', weight='bold', fontsize=18, ha='center', va='center')
axes.add_patch(rect)
# Display the rectangles
plt.show()

このスクリプトは、JSON形式の予測レスポンスを読み込み、バウンディングボックスの座標を抽出して、検出されたオブジェクトの周囲に矩形を描画します。各バウンディングボックスには、対応するオブジェクトのカウント番号が注釈として付けられます。

まとめ

Ground Truthで画像にラベルを付け、SageMakerの物体検出モデルを学習させ、テスト用エンドポイントに対して推論を実行したところ、matplotlibでカウントおよび可視化できるバウンディングボックスが得られました。可視化スクリプト内のscore < 0.2というフィルタは、地味ながら大きな役割を果たしています。オブジェクトカウントの精度は、何を検出とみなすかを決める信頼度しきい値の設定次第であり、そのしきい値は1枚のテスト画像でたまたま妥当に見えるデフォルト値のままにせず、実際の検証データに対してチューニングする必要があります。また、このモデルはプライベートワークフォースによるGround Truthのラベルで学習されているため、カウントの精度は最終的に、重なり合ったオブジェクトや部分的にしか見えないオブジェクトをワーカーがどれだけ一貫してアノテーションできたかに左右されます。このパイプラインが大規模に生成する数値を信頼する前に、その点を確認しておく価値があります。

About the author

Takahiro Iwasa

Takahiro Iwasa

Software Developer

This blog shares technical notes from hands-on projects—architecture, implementation, and AWS service integrations.