Ultralytics YOLO27: ウェイトリストに登録する。
レッスン初級

検証と診断

best.ptをベースラインと照らし合わせて検証し、混同行列、クラス別の数値、予測画像を確認して、具体的な修正項目のリストを作成します。

単一のmAPの値から分かるのは、モデルがどの程度間違えているかであり、何を間違えているかではありません。小さい物体の見逃し、2つのクラスの混同、緩いボックスはどれもmAPを低下させますが、それぞれ必要な修正は異なります。判断を誤ると、間違ったデータを集めるために1週間を費やすことになります。

このレッスンでは、best.pt でValモードを実行してベースラインと比較します。次の改善項目リストを書けるようになるまで、混同行列と予測画像を確認します。性能指標ガイドでは、さらに詳しく解説しています。

成果

条件を揃えてモデルを検証し、混同行列とクラス別の表から最も弱いクラスと失敗パターンを見つけ、次のラウンドで行う具体的な変更を3つ書き出せます。

短期集中コース
すでに使い方をご存じの方は、こちらをご覧ください。
  1. yolo val model=runs/detect/pills_v1/weights/best.pt data=my_dataset/data.yaml を実行します。

  2. mAP50とmAP50-95をベースラインと比較します。両者に大きな差がある場合、ボックスが緩いことを示しています。

  3. confusion_matrix_normalized.png を確認します。列は正解クラス、行は予測クラスです。

  4. val_batch0_labels.jpg と val_batch0_pred.jpg を比較し、失敗パターンを列挙します。

実践的

実践例:best.ptを検証する#

from ultralytics import YOLO

model = YOLO("runs/detect/pills_v1/weights/best.pt")
metrics = model.val(data="my_dataset/data.yaml")

print(f"precision {metrics.box.mp:.3f}  recall {metrics.box.mr:.3f}")
print(f"mAP50 {metrics.box.map50:.3f}  mAP50-95 {metrics.box.map:.3f}")

val.py の実際の出力:

precision 0.970  recall 0.957
mAP50 0.977  mAP50-95 0.659

プロットは新しい runs/detect/val フォルダーに保存されます(続いて val-2 など)。数値をベースラインと並べて記録します。

モデルmAP50mAP50-95
事前学習済み yolo26n.pt(錠剤クラスなし)0.0010.0002
pills_v1(10エポック、imgsz 320、CPU)0.9770.659

数値が示すこと:

  • Precision 0.970、recall 0.957: バランスが取れています。誤検出も見逃しも少数です。
  • mAP50 0.977: 重なりの条件が緩い場合、モデルはほぼすべての錠剤を検出します。
  • mAP50-95 0.659: 重なりの条件が厳しい場合、多くのボックスがぴったり合っていません。この大きな差は、データ不足ではなく、位置特定の問題を示しています。エポック数を増やす、大きなimgszを使う、またはラベルをより厳密に付けるといった対策が考えられます。

precision、recall、mAPのトレードオフについては、検出メトリクスを正しく読み解くをご覧ください。

質問への答えがわかるファイルを確認する#

質問ファイル
どのクラスが混同され、どのクラスが見逃されていますか?confusion_matrix_normalized.png
クラスごとにprecisionとrecallのバランスはどうなっていますか?BoxPR_curve.png
どのconfidenceしきい値でデプロイすればよいですか?BoxF1_curve.png: ピーク値は適切な初期confです
失敗例はどのような見た目ですか?val_batch0_labels.jpgとval_batch0_pred.jpg
モデルは過学習していますか?トレーニングフォルダー内のresults.png

混同行列を読み解く#

正解クラスが列、予測クラスが行として表示された、正規化混同行列を示すUltralytics Platformのモデルページ

混同行列は、最も役立つ診断ツールです。Ultralyticsのプロットでは、列が正解クラス、行が予測クラスで、backgroundの行と列が追加されています。正規化された行列では各列をその合計で割るため、各クラスのオブジェクトがどこに分類されたかがわかります。錠剤モデルのクラスは1つだけなので、3クラスの倉庫の例(数値は説明用)で練習してみましょう。

予測 ↓ / 正解 →フォークリフト人パレット背景
フォークリフト0.780.030.180.45
人0.040.910.000.20
パレット0.100.000.650.35
背景0.080.060.17—
  • 対角成分: 各クラスが正しく検出された割合です。パレットは0.65で、最も性能が低いクラスです。
  • 非対角成分: クラスの混同を示します。正解がパレットのデータの18%がフォークリフトと予測され、フォークリフトの10%がパレットと予測されました。
  • 背景の行: 見逃しを示します。パレットの17%がまったく検出されませんでした。
  • 背景の列: 空の領域にボックスが描画された誤検出を示します。そのうち45%はフォークリフトと判定されました。

各セルの種類に対応する対策は次のとおりです。

パターン対策
2つのクラスが互いに混同される両者を区別できる例を追加します。パレットを運ぶフォークリフトや、フォークリフトの隣に積まれたパレットなどです
背景の行の値が高い(見逃しが多い)見逃しが発生する条件下で、そのクラスの例を増やします
背景の列の値が高い(誤検出が多い)空の通路など、誤検出を引き起こすシーンの背景画像を追加します

クラスごとの数値を読み解く#

クラスが複数ある場合、検証ログにはクラスごとに1行が出力され、metrics.box.mapsにはコードで使えるクラス別mAP50-95が格納されます。倉庫の例を続けます。

                 Class     Images  Instances      Box(P          R      mAP50  mAP50-95)
                   all         50        102       0.78       0.71       0.74       0.51
              forklift         30         45       0.85       0.78       0.81       0.58
                person         40         50       0.92       0.88       0.91       0.64
                pallet          5          7       0.58       0.48       0.51       0.31

palletは他のクラスを大きく下回り、検証データ内のインスタンスはわずか7件です。モデルのパレット検出が苦手なのか、判断するには検証データが少なすぎるのか、どちらかです。どちらの場合も、トレーニング用と検証用にパレットのデータをさらに収集する必要があります。

失敗例を確認する#

val_batch0_labels.jpgとval_batch0_pred.jpgを並べて開きます。違いは失敗例を画像として示しており、そこに見られるパターンが診断の手がかりになります。画像の端での見逃し、小さなオブジェクト、特定の照明条件、見た目が似た対象などです。こうしたデータセットのパターンは、ほとんどの場合、ハイパーパラメーターの調整よりも重要です。

錠剤モデルの検証画像では、はっきり見える錠剤のスコアは1.0近くです。confidenceが0.3~0.5程度の低いボックスは、別のブリスターパックの下に一部が隠れた錠剤や、画像の端で切れている錠剤に集中しています。これはconfで解消する問題ではなく、ラベリング方針の問題です。半分隠れた錠剤を対象として数えるべきでしょうか?方針を決めて明文化し、すべての画像に同じルールを適用してください。

次にresults.pngを開きます。トレーニング損失と検証損失はどちらも低下するはずです。トレーニング損失が低下し続ける一方で検証損失が上昇する場合は過学習です。どちらも高いままなら未学習です。どちらの場合も、バイアスと分散のトレードオフが判断の枠組みになります。

同じデータへの3種類のフィッティングを並べた図。未学習の直線、適切にフィットした曲線、すべての点を通るように曲がった過学習の曲線

過学習への対策は、効果が得られる頻度が高い順に、より多様なデータ、エポック数を減らすかpatienceをより厳しくすること、そしてデータ拡張(hsv_h、degrees、translate、scale、fliplr、mosaicなど)です。データ拡張のデフォルト設定はすでに強力なので、左右の区別が重要な場合にfliplrを無効にするなど、理由がある場合にのみ変更してください。

調査結果を対策リストにまとめる#

ハイパーパラメーターを調整する前にデータを修正し、何が効果をもたらしたか把握できるよう、1回のイテレーションで変更する項目は1つにします。このループのデータセット側の作業については、初回のファインチューニングとイテレーションループで説明しています。

次の間違いに注意する#

異なる画像サイズで検証する

症状: mAP50-95が0.659だったモデルのスコアが、突然0.403になります。原因: pills_v1 は imgsz=320 でトレーニングされ、imgsz=640 で検証されました。そのため、オブジェクトが学習時の2倍の大きさで表示されます。対処: トレーニング時の imgsz で検証とデプロイを行い、同じサイズで実行した結果だけを比較してください。

検証時の検出結果をデプロイ時の検出結果として読む

検証は全精度-再現率曲線を追跡できるよう conf=0.001 で実行されるため、val_batch0_pred.jpg にはアプリが報告しないボックスも表示されます。BoxF1_curve.png からデプロイ時のしきい値を選び、predict で確認してください。

小さな検証セットでは結果のばらつきが大きい

画像が23枚の場合、あるエポックのprecisionは0.93から0.80に下がり、再び上昇しました。エポックと実行間の傾向を見て判断し、1~2ポイントの差を信頼する前に検証セットを増やしてください。

試してみる

pills_v1/weights/best.ptを検証してください。1ページの診断レポートを作成します。mAP50とmAP50-95を記載したベースラインとトレーニング後の比較表、val_batch0_labels.jpgとval_batch0_pred.jpgを比較して見つけた具体的な失敗例2つ(内容と場所)、results.pngから判断した過学習についてのメモ、次のラウンドで行う具体的な変更3つを含めてください。

完了条件
以下のすべてを満たすと、レッスンは完了です。
  • トレーニング時のimgszでのmAP50とmAP50-95を記載した、ベースラインとトレーニング後の比較表があります。

  • 検証画像における具体的な失敗例を少なくとも2つ挙げています。

  • 次のラウンドに向けて、データまたはトレーニングに関する具体的な変更を3つ記載しています。

解答を表示
Baseline mAP50-95 0.0002 -> pills_v1 0.659 (mAP50 0.977), both at imgsz=320

Failures:
- Low-confidence boxes (about 0.3-0.5) on pills half-hidden under another pack.
- Low-confidence or missing boxes on pills cut off at the image edge.

Overfitting: none. val/box_loss flattened near 1.05; val/cls_loss spiked at epochs 4-6
and then fell to its lowest value (1.08) at epoch 10.

Fix list:
1. Write a labeling rule for partly hidden and edge pills, then relabel the val set to match.
2. Train longer and larger: epochs=50, imgsz=640 (mAP50-95 lags mAP50, so box tightness is the gap).
3. Add 20 frames with overlapping packs, labeled under the new rule.
次のステップ

変更すべき内容がわかりました。次は中断した実行を再開し、最良の重みからウォームスタートして、次のラウンドを効率よく実行します。