Safie Engineers' Blog!

Safieのエンジニアが書くブログです

Amazon SagemakerでYOLOv4の学習環境を作ってみた

セーフィー株式会社要素技術開発部のおにきです。 クラウドカメラを用いた画像解析の開発を担当しています。

AWSのMLOps環境であるSagemakerについて調査しました。試しに物体検出アルゴリズムであるYOLOv4の学習環境を作ってみたので紹介します。今回学習環境としてYOLOv4の著者Alexey Bochkovskiy氏が公開しているソースコードを利用しています。これはYOLOv3までの著者であるJoseph Redmon氏の開発していたフレームワークであるDarknetをブランチしたものになります。

今回作成したコードはGithubにあげているのでご参照ください。

Amazon Sagemaker

Amazon Sagemakerは機械学習を用いたサービスを実現するために、データ作成、モデル開発、学習実行、サービス運用といういわゆるMLOpsと呼ばれる業務を実現する環境を提供するAWSのサービスです。AWSのサービスなのでもちろんクラウド環境であり、初期費用が必要なく物理サーバーの管理が不要などのメリットがあります。

SagemakerはMLOpsを実現するための多様なツール・環境を提供しています。代表的な機能を上げると以下になります。

  • 学習データ作成
  • 学習
  • デプロイ
  • エンドポイント構築

今回の記事ではSagemakerの学習機能を利用しています。

Sagemakerによる学習

Sagemakerによる学習ではGPUインスタンスを必要な時に必要なだけ利用できる点がメリットとしてあげられます。機械学習の開発ではモデルの比較やハイパーパラメタ比較のためにある一時期だけGPUマシンが必要となる場合がありますが、その時に必要な分だけGPUインスタンスを確保できます。

Sagemakerによる学習は以下の3つのパターンに分けられます。

  • 組み込みアルゴリズムの利用
    Amazonがすでに用意したアルゴリズムを利用します。開発者は学習データを用意するだけすみます。画像認識ではイメージ分類、オブジェクト検出、セマンティックセグメンテーションが用意されています。

  • 構築済みのコンテナイメージの利用
    Pythonを用いてTensorFlow、PyTorch、Chainer、MXNetなどのフレームワークが動作する学習用Dockerコンテナが用意されており、Pythonでアルゴリズムを開発する場合にはJupyter Notebookから学習インスタンスにアルゴリズムを自動で転送しての実行ができるなどスムーズな開発ができます。

  • 独自のカスタムコンテナイメージの利用
    開発者が独自のDockerコンテナを作成して学習インスタンスで実行させることができます。Dockerコンテナとしての仕様に合わせていればPython以外の言語でも学習を行うことができます。YOLOv4の学習環境であるDarknetはC言語+CUDA Cで実装されているため、今回は独自のカスタムコンテナイメージを利用した学習を選択しました。Pythonベースのアルゴリズムであっても一部C/C++によるMakeが必要な場合などは独自のカスタムコンテナイメージの利用が選択肢になります。

学習の処理の流れ

Sagemakerによる独自のカスタムコンテナイメージを利用した学習を図にすると以下になります。

f:id:safie:20200918153206p:plain

開発者は①のJupyter Notebookから学習実行をするだけで ② ~ ⑤ の処理は自動で行われます。

カスタムコンテナの仕様

カスタムコンテナを作成するためには、処理のエントリーポイント・入力・出力の仕様を抑えることが重要となります。この仕様に合わせさえすれば、様々なケースに対応したカスタムコンテを作成する事が可能になります。

エントリーポイント

学習インスタンス内ではコンテナイメージがダウンロードされたあとに以下のコマンドが実行されます。

docker run <image> train

上記のコマンドが呼ばれた場合に実行したい学習処理が起動するコンテナイメージを作成するには以下の2つの方法があります。

(1)コンテナイメージ内にtrainというファイル名で実行可能なファイルを配置する (2)DockerfileでENTRYPOINTを定義する

どちらも大きな差はないので、今回は(2)の方法を採用しました。

入力

  • トレーニングデータ
    /opt/ml/input/data/<channel>
    S3においた学習データは上記のディレクトリにダウンロードされます。チャネルを利用することでデータを学習、バリデーション、テストなどに分けて扱うことが可能です。チャネルの名前は開発者が自由に選択することができます。今回はtrainだけを利用することにしました。

  • ハイパーパラメタ
    /opt/ml/input/config/hyperparameters.json
    Jupyter Notebookから起動する際にハイパーパラメタを渡すことができます。注意点としてJupyter Notebook側から数値型で値を与えても文字列型に変換されたjsonがコンテナに設置されます。Jupyter Notebookで学習処理を起動する際にグリッドサーチを行うことも可能です。

  • 入力データ設定
    /opt/ml/input/config/inputdataconfig.json
    起動したコンテナがどのチャネルを利用できるかの情報を得ることができますが、今回はtrainだけを使用するため使用していません。

Amazon SageMaker がトレーニング情報を提供する方法 - Amazon SageMaker #入力データ設定

出力

  • 学習済みモデルデータ
    /opt/ml/model
    学習処理が終了した時点で上記のディレクトリ内にあるファイルがアーカイブ化されてS3にアップロードされます。

Sagemakerについてのより詳しい情報は以下を参照ください。
Amazon SageMaker で独自のアルゴリズムやモデルを使用する - Amazon SageMaker

YOLOv4用にSagemakerでカスタムコンテナを用いた学習環境の作成

ここまではSagemakerの一般的な説明してきましたが、ここからはYOLOv4を学習するための環境の作成について説明します。

Sagemakerで利用するS3、ECR、Sagemaker ノートブックインスタンスはすべて同じリージョンで作成しないと動作しないのでご注意ください。

Step1 エントリーポイントの作成

コンテナイメージのエントリーポイントとしてmain.pyというPython3スクリプトを作成しました。 機械学習における本来的な意味でのハイパーパラメタではないのですが、dataファイルとcfgファイルのファイル名を読み取って、Darknetの引数として起動しています。

Step2 Dockerfileの作成

コンテナイメージ作成用に以下のDockerfileを作成しました。

上記のDockerfileでは、DarknetがGPU、cuDNN、OpenCVを利用できるようMakefileを書き換えてビルドしています。

Step3 ECRの準備

ECRにレポジトリを作成します。dockerコマンドを用いてイメージを作成して、レポジトリにプッシュします。

$ aws ecr get-login-password --region us-west-2 | docker login --username AWS --password-stdin xxxx.dkr.ecr.us-west-2.amazonaws.com
$ docker build -t darknet-yolov4 .
$ docker tag darknet-yolov4:latest xxxx.dkr.ecr.us-west-2.amazonaws.com/darknet-yolov4:latest
$ docker push xxxx.dkr.ecr.us-west-2.amazonaws.com/darknet-yolov4:latest

Step4 S3に学習データをアップロード

学習データをS3にアップロードします。

$ aws s3 cp dataset/ s3://sagemaker-xxxx/dataset --recursive

Darknetでは画像データのパスをdataファイルに記載する必要があるため、dataファイルにはSagemakerのコンテナイメージでの絶対パスとして記述しました。 Darknetではbackupがモデルファイルの出力先であるため、/opt/ml/model/に指定しています。

classes= 1
train  = /opt/ml/input/data/train/train.txt
valid  = /opt/ml/input/data/train/test.txt
names = /opt/ml/input/data/train/classes.txt
backup = /opt/ml/model/

train.txtは同様に絶対パスで記述しています。

/opt/ml/input/data/train/camera/000.jpg
/opt/ml/input/data/train/camera/001.jpg
/opt/ml/input/data/train/camera/002.jpg
・・・

このあたりのファイルパスの扱いはmain.pyで自動生成するなど改善の余地はありそうです。

yolov4-custom.cfgはGithubのファイルをもとに作成しました。

S3にアップロードしたファイルは以下の構造です。

s3://sagemaker-xxxx
└── train
    ├── camera
    │   ├── 000.jpg
    │   ├── 000.txt
    │   ├── 001.jpg
    │   ├── 001.txt
    │   ・・・
    │   
    ├── camera.data
    ├── classes.txt
    ├── test.txt
    ├── train.txt
    └── yolov4-custom.cfg

Step5 学習の実行

AWSのコンソールでSagemaker > ノートブックインスタンスでノートブックインスタンスの作成を行います。ノートブックインスタンス自体は学習を行わないのでインスタンスのタイプは一番安いml.t2.mediumで十分です。Jupyter上にノートブック作成する際には「conda_python3」を選択しました。

Jupyter Notebook上から学習の実行を行います。以下のコードでは先ほど作成したエントリーポイント(main.py)に渡すハイパーパラメタとしてdataファイルとcfgファイルを設定しています。

estimator = Estimator(
    image_name="xxxx.dkr.ecr.us-west-2.amazonaws.com/darknet-yolov4:latest",
    role=role,
    train_instance_type="ml.g4dn.xlarge",
    train_instance_count=1,
    train_max_run = 3 * 60 *60,
    hyperparameters={
        "data_file": "camera.data",
        "cfg_file": "yolov4-custom.cfg"
    }
)

estimator.fit({"train": "s3://sagemaker-xxxx/dataset/"})

ml.g4dn.xlargeはGPUが利用できるインスタンスタイプとしては最安(オレゴンで0.736$/時)ですが、16GBという大きなGPUメモリが利用できます。

学習中の状態はAWSのコンソールのSageMaker > トレーニングジョブで確認することもできます。 f:id:safie:20200918153454p:plain

学習結果

学習処理が終了すると結果であるモデルファイルはS3にアップロードされます。 f:id:safie:20200918153505p:plain

Sagemakerで学習したYOLOv4のモデルで推論してみた結果です。今回はお試しとして、弊社で扱っているセキュリティカメラの画像から学習データを作成し、学習処理を行ってみました。 f:id:safie:20200918153954p:plain

さいごに

今回はクラウドのMLOps環境であるAWSのSagemakerを利用してYOLOv4の学習を行う環境を作成しました。クラウド環境を利用することで一時的に大量の学習インスタンスを確保するといった柔軟な開発が可能になるかと思います。今回は学習処理についてだけ扱いましたが、Sagemakerを適切に利用することで機械学習を用いた製品を効率よく開発・運用できるのではないかと考えています。

セーフィーでは現在数万台のセキュリティカメラが弊社システムに接続されており、これらのカメラから画像認識技術を用いて情報を抽出するサービスを開発しています。そのために一緒に開発を進めていくメンバーを募集しています。

www.wantedly.com

© Safie Inc.