Inside of LOVOT

GROOVE X 技術ブログ

人物認識ライブラリのデータ管理と性能評価をするパイプラインを作ってみた

こんにちは! GROOVE X の 認識技術を扱うチームに所属している id:numa-gx です。

この記事は、GROOVE X Advent Calendar 2023 7日目の記事です。

LOVOTにはホーンと呼ばれるパーツに広角のカメラが備わっています。

このカメラを使って人物を認識し、なつき具合に応じたふるまいを行う仕組みがLOVOTには備わっています。

そして、この人物を認識する機能に関してはAI顔認証エンジンであるFaceMeを利用しています。

prtimes.jp

このFaceMeを導入するにあたって様々な状況でデータを収集・管理しながら性能を評価する仕組みを作る必要がありました。

そこで、データ管理のパイプラインを構築するために使われている DVC を利用してみました。

その仕組みや使用感について説明していきたいと思います。

DVC とは?

dvc.org

Data Version Control の頭文字を取って DVC と呼ばれています。

ML(機械学習)モデルを共有しやすく再現もしやすい状態で保持し、モデルだけでなくデータセット、評価結果も管理対象に含まれます。

特に、バージョン管理に関しては git like な API が提供されていて、コード管理をするような感覚で扱うことができます。 ソフトウェアエンジニアにとってはありがたいです。

使い方に関しては、公式のチュートリアルの説明が分かりやすいので、割愛して実際にどのようにパイプラインを作ったのかについて説明していきます。

DVC を使ったパイプラインの構築

DVCを導入する前のFaceMeの性能評価をするワークフローは以下のような流れになっていました。

  1. FaceMeを含む顔認識アプリケーションの開発リポジトリがGitHubで管理されている
  2. 検証・評価のデータセットは、データ収集チームが作業を行い、社内のGoogleDrive上にアップロードする
  3. 性能評価は開発リポジトリ内のテストツールで実行され、アップロードされたデータセットと組み合わせて実行する
  4. 実行した結果はスプレッドシートや社内のドキュメントツールにまとめてチームに展開する

この中で、手順3,4を開発者が行っていたのですが、以下のような状況のため情報を管理するのが難しいことが分かってきました。

  • データセットとライブラリ内で調整したパラメータの組み合わせの数だけ評価結果がある
  • 時間の経過とともに組み合わせのパターンが増える

そこで DVC を組み込んだパイプラインを構築して3と4の部分を自動化することにしました。

全体像

構築したパイプライン

こちらがパイプラインの全体像になります。 データの管理にはGCP、パイプラインの実行には Github Actions を使っています。

いくつかの dvc を使う上でのポイントを解説します。

データ管理のリポジトリとアプリケーションのリポジトリの分離

FaceMeの認識ロジックを含むアプリケーションは object-detection-app リポジトリ側で管理していますが、データセットは dataset-registory 側で管理しています。

DVC では Data Registry という考え方があります。 以下の図のようにデータを実際に管理するストレージとアプリケーションの間に、Data Registoryとして組み込むことで、再利用性・永続性を高く保ちつつ、データをコードのように管理することができます。

https://dvc.org/doc/use-cases/data-registry より

実際の流れを順番に説明していきたいと思います。

データセットの追加・登録

data-regisotry側のリポジトリでは、以下のように gcp との 紐付けを .dvc/configに書き、

[core]
    remote = gcps
['remote "gcps"']
    url = gs://dataset-registry

videos/static/0001.dvc に以下のような形式で具体的なデータの紐付けを書きます。(dvcではmd5ハッシュ値でデータが管理されます)

outs:
- md5: 4846b900cac89f2248e562f9f051f4ac.dir
  size: 10471030
  nfiles: 25
  hash: md5
  path: '0001'

新しくデータセットを追加する際には、これらの変更をPullRequestとして作成し、マージすることでデータの追加を行います。

新しいデータセットを使った評価

アプリケーション側のリポジトリでは data-registory側のリポジトリと連携させることで dvc で管理されたデータをインポートし、そのデータを使って一連の処理を実装することができます。 その流れを記述するために2つのファイルを用意します。

# dvc.yaml
stages:
  evaluate:
    cmd: python person_create_check.py
    deps:
    - person_create_check.py
    params:
    - evaluate.f2f
    - evaluate.left
# params.yaml
evaluate:
  f2f:
    description: "被験者がLOVOTと顔を向き合わせた状態. Personが生成される想定"
    data_list:
      - "0001"
      - "0004"
      - "0005"
  left:
    description: "被験者がLOVOTに対して顔を左側に向けた状態. Personが生成されない想定"
    data_list:
      - "0040"
      - "0043"
      - "0044"

dvc.yaml では、全体のパイプラインを定義します。今回の用途としては以下を想定しています。

  1. dvc で管理されたデータセットから特定のデータを選択
  2. 特定のデータを対象として、 person_create_check.py という評価用スクリプトを実行
  3. 評価結果をレポートとして保持

yaml上の定義では、 - データのサブセットを作る - データについてのドキュメントを残す などを管理し、性能評価の実行、レポートの生成といった処理は python のコードで書いています。

以下のコードは、person_create_check.py の一部抜粋になります。

# pip install dvc 
from dvc.repo import Repo

# dvcで管理されているデータセットを取得する
params = yaml.safe_load(open("params.yaml"))["evaluate"]
repo = Repo()
# dvc import を実行して、xxx/static.dvc を作成する
# cacheの情報を使ってデータを展開したいため、no_download=True を指定する
# force=Trueにすることで、すでにデータが存在していても再実行できるようにする
repo.imp(
    url="git@github.com:groove-x/dataset-registry.git",
    path="videos/static",
    out=_DATA_PATH,
    force=True,
    no_download=True,
)
# dvc pull を実行して、xxx/static 以下にデータを展開する
repo.pull(targets=str(_DATA_PATH / "static.dvc"))

このコードを GitHubAction上で実行することで、CI環境上に使いたいデータセットを展開し、検証に必要なロジックの実行が可能となります。

データの評価結果の可視化

可視化についてはまだ検討ができておらず、現在は以下のような仕組みで仮実装しています。

  1. GCP上にドキュメンテーション置き場を用意
  2. jinja2 を使って用意した template.html を使って、html を作成
  3. html をアップロードして、特定のページを更新

実際の表示結果(数値などは仮のもので意味があるものではありません)

実験結果のレポート

作ってみて

全体の流れを実装してみて、DVCというツールには機械学習アプリケーションを持続的に開発していく過程で役に立つ可能性をとても感じました。

フローを一回作ってしまえば再利用しやすいということがあり、git like な 操作感での理解のしやすさもあり、メンテナンス性を高く保てそうだと思いました。

一方で、DVCはあくまでデータの管理ツールであるため、評価結果の可視化などをサポートする機能はなく、そのような目的の場合は他のツールを組み合わせる必要がありそうです。

おわりに

最後まで読んでいただいてありがとうございました。

GROOVE Xでは一緒に働く仲間を募集しています!是非下記リンクをチェックしてみてください。 recruit.jobcan.jp