🤖

①ポケモンカード傷検知モデルを構築・評価するまでの振り返り

2024/01/24に公開

プロジェクト概要

本プロジェクトの目的は、ポケモンカードに自然的につく複数傷の種類をある程度の精度で検知することができる物体検知モデルを構築することです。ある程度の精度とは、傷のカテゴリ毎に200~300枚程度の画像を学習させてそれぞれの傷を60%以上のaccurayで分類できる精度、という意味です。
精度の目標が低いと思うかもしれませんが、まずは最低限のデータ数を用意、アノテーションしてどれぐらい精度で分類できるかを手っ取り早く確認したかったというのがあります。もし50%以上の精度が確認できたら入力、教師データをコツコツ蓄積していけば少しずつではあるが精度改善ができるだろうという期待を含めてこの制度目標としました。

用意したデータ

最初に用意したデータの概要を述べます。
集めたデータ数は1352枚です。
傷カテゴリ毎の内訳は以下です。

それぞれの意味は
broken=折れ
concave=へこみ
dirt=汚れ
run_back=背面擦れ
rub_front=正面すれ
scratch=線傷
shirokake=白かけ
wrinkles=しわ
です。

当たり前ですが、傷付きポケモンカードのデータセットなんかオープンソースで提供されているはずもないので、労力を費やして自前で用意する必要がありました。
データを集めた方法は

  • ポケモンカード好きな友人からデータを提供してもらう
  • ネットからデータをスクレイピングする

の二つの手法で収集しました。
最初の300枚はぐらいはマンパワーフル投下で友人の二人に協力してもらって集めてました。
しかし、みんな社会人で忙しいということもあり、段々と収集のペースが落ちてきてこのままではデータ集めで数ヶ月を費やすことになりかねないと思ったので、もっと効率的な手法を探した結果、メルカリから画像データをスクレピングする方法を思いつきました。(いやいや最初からそうするだろ普通!!という突っ込みが聞こえてきます。)

メルカリから画像データをスクレイピングする際に実装したコードはこちら。
https://github.com/yonaimineakio/ScrapingItemImageFromMercari

アノテーションデータ例

アノテーションツールの使用上、長方形の形でしか対象領域を指定できないため連続した短形で囲っています。
一つの短形で囲むこともできますが、そうなると本来対象にはならない領域も大幅に含まれてしまうためこれはいかがなものかと思いこの手法を取りました。どっちが正解なのでしょう、、

wrinkle(しわ)とbroken(折れ)の違いがよくわかっていません。

環境

学習環境: Google Colab(T4 GPUを使用)
アノテーションツール: YoloLabel

利用したモデル

利用したモデルはYolov5です。
yolov5とは, ultralytics社が提供からオープンソースで提供されている物体検知モデルです。
詳細は以下。
https://github.com/ultralytics/yolov5

結果

以下、学習したモデルの評価値です。

それぞれの評価値の意味、モデル性能の考察は以下(gpt4で生成)

  • Class: 評価されたクラスのカテゴリーです。
  • Images: 評価に使用された画像の数を示します。
  • Instances: 検出されるべきオブジェクトのインスタンス数です。
  • P (Precision): モデルが正しく物体を検出した割合を示します。これは、True Positive / (True - Positive + False Positive)の計算で、検出された物体が実際に正しいかどうかの指標です。
  • R (Recall): 正しい物体をどれだけ検出できたかを示します。これは、True Positive / (True - - Positive + False Negative)の計算で、すべての正しい物体の中でモデルが検出した割合です。
  • mAP50: mean Average Precision at IOU (Intersection Over Union) threshold of 50%です。この値は、異なる信頼度閾値でのPrecisionとRecallの平均を取ったもので、物体検出モデルの性能を評価する標準的な指標の一つです。IOUが50%を超える検出を正しいと見なします。
  • mAP50-95: これはIOUの閾値を50%から95%まで5%刻みで変化させた時のmAPの平均値です。この値が高いほど、モデルの検出性能が優れていることを意味します。
  • YOLOv5s summary: YOLOv5のバリエーションの一つで、モデルのサイズやパラメータ数を示しています。ここでは157層、703万1701パラメータ、15.8 GFLOPs(モデルの計算複雑性)と表示されています。

評価値からは、モデルがある特定のクラスに対してどれだけ効果的に物体を検出できるかがわかります。この結果だけからは、モデルの性能が高いか低いかを判断するのは難しいですが、PrecisionとRecallが共に0.5であること、mAP値が極めて低いことから、モデルが非常に限られたデータセットでテストされているか、 もしくは性能が低い可能性があります。通常、より広範なデータセットと多様なクラスで高いmAP値を得ることが望ましいです。

考察で述べられている特定のクラスとはscratch(線傷)で、今回の評価結果では線傷しか検出できなかったので全体(all)の評価結果も同様となっています。

反省

  • データ数が少なかった
  • 評価データが少なかった
  • アノテーションのやり方がそもそも最適かわからない
  • 傷カテゴリ別のデータ数に大幅に偏りがある
  • データの水増し(データオーギュメンテーション)をしていなかった
  • Yolov5の最適な学習パラメータを考察していない

次回試すこと

  • 引き続きメルカリからデータ収集
  • データオーギュメンテーション
  • 評価データの拡張
  • ラベルリング手法の見直し
  • Yolov5の学習パラメータの考察

まとめ

ポケモンーカード傷検知モデルの構築におけるデータ収集、アノテーション、学習、評価までのプロセスをまとめました。当方は多少の深層学習、pythonの知識を持っているだけで画像検知に関しては完全に実務未経験の素人です。協力して頂いた友人に関しては業界すら違います。
データ収集から始まるプロジェクトの進め方、教師データの作成、検知モデルの学習もネットで情報収集して見よう見まねで実施しました。
もしこの記事を見てくださった方で「私ならこうするけどな」、「このアノテーションの仕方はダメやろ」などの意見を持たれた方がいれば、是非コメントしていただけますと幸いです。

協力者

Discussion