Overfitting
過学習は、モデルがノイズも含めて学習データを記憶し、新しいデータに対応できなくなる状態です。過学習の見分け方と防止方法を紹介します。
過学習は、機械学習モデルが学習データに過度に適合し、実際のパターンだけでなく、特定のサンプルに含まれるノイズや特徴まで学習してしまう状態です。過学習したモデルは学習データでは高いスコアを出しますが、新しいデータでは明らかに性能が低下します。この差の大きさが過学習の程度を示します。バイアスと分散の観点では、過学習は高分散にあたり、モデルの予測が、たまたま見た特定のサンプルに過度に依存します。
過学習の見分け方#
過学習の典型的な兆候は、学習データと検証データの性能差が拡大することです。エポックごとにプロットした学習曲線では、学習損失が下がり続ける一方、検証損失は横ばいになってから上昇し、平均適合率(mAP)などの検証指標は停滞または低下します。小規模な典型例では、正弦波からサンプリングしたノイズを含む12点に、次数の異なる2つの多項式を当てはめます。
import numpy as np
from numpy.polynomial import Polynomial
rng = np.random.default_rng(0)
# 12 noisy training points from a sine wave, plus clean test points
x_train = rng.uniform(0, 1, 12)
y_train = np.sin(2 * np.pi * x_train) + rng.normal(0, 0.2, 12)
x_test = np.linspace(0, 1, 200)
y_test = np.sin(2 * np.pi * x_test)
for degree in (3, 9):
fit = Polynomial.fit(x_train, y_train, degree)
train_mse = np.mean((fit(x_train) - y_train) ** 2)
test_mse = np.mean((fit(x_test) - y_test) ** 2)
print(f"Degree {degree:2d}: train MSE {train_mse:.4f}, test MSE {test_mse:.4f}")9次多項式はノイズに合わせて曲がるだけの柔軟性があるため、学習誤差は0.0356から0.0148に下がりますが、テスト誤差は0.0182から0.1859へと10倍に増加します。
過学習と未学習#
アンダーフィッティングはその逆で、モデルが単純すぎる、または学習時間が短すぎるためにデータのパターンを捉えられず、学習データと検証データの両方で性能が低くなります。2つの誤差を比べると、どちらの状態かを見分けられ、異なる対処法を選ぶ手掛かりになります。
よくある原因#
- データに対してモデル容量が大きすぎる: 数百万のパラメーターを持つニューラルネットワークは、数百枚の画像を完全に記憶してしまうことがあります。
- ノイズの多いデータまたは誤ラベルのデータ: ボックスの欠落、クラスの誤り、外れ値があると、現実世界には存在しない誤りまでモデルが適合することになります。
- 学習時間が長すぎる: 有用なパターンを学習した後、エポックを追加しても、残ったノイズへの適合が主になります。
- 学習データの範囲が狭い: 1台のカメラによる昼間の画像だけで学習した検出器は、そのカメラの背景や照明に過度に適合し、新しい場所では物体を見逃すことがあります。
過学習の防止#
- 量と多様性を増やしたデータ: 実例を追加することが最も直接的な対策です。データ拡張では、既存画像の反転、スケーリング、色変更、合成によって多様性を増やします。
- 正則化: 重み減衰は大きな重みにペナルティを課します。また、ドロップアウトは学習中にユニットをランダムに無効化し、単一の特徴が不可欠になるのを防ぎます。
- 小規模モデルまたは事前学習済みモデル: 小規模モデルは記憶できる余地が少なく、初期層を凍結した転移学習では、小規模データセットから学習する必要がある重みの数を減らせます。
- 早期終了: 各エポック後に検証データで評価し、スコアの改善が止まった時点で学習を終了すると、モデルがノイズに過度に適合するのを防げます。
- 適切な評価: 交差検証は小規模データセットにおける汎化誤差をより確実に推定します。また、独立したテストセットを用意すると、ハイパーパラメーター調整中に検証データへ過学習していないかを確認できます。
Ultralytics YOLOの学習では、patience引数で早期終了を適用します。この引数で指定したエポック数だけ検証時の適合度(検出ではmAP50-95)が改善しないと、実行を終了します。また、学習が最後まで続いた場合でも、最良エポックの重みをbest.ptとして保存します。
from ultralytics import YOLO
# 事前学習済みYOLO26nモデルを読み込みます
model = YOLO("yolo26n.pt")
# 最大100エポックまで許可しますが、検証スコアが20エポック改善しなければ停止します
results = model.train(data="coco8.yaml", epochs=100, patience=20)デフォルトはpatience=100です。1,000枚未満のデータセットについて、YOLO26のファインチューニングガイダンスでは、epochs=50とpatience=20の使用を推奨しています。
過学習と関連用語の違い#
- データリーク: 学習データと評価データが重複すると、過学習が隠れてしまいます。同じ動画のほぼ重複するフレームが学習用と検証用の両方に入ると、学習セットを記憶したモデルでも検証で高いスコアを出し、問題はデプロイ後に初めて明らかになります。動画またはシーン単位で分割すれば防止できます。
- ショートカット学習: モデルが、透かしや背景など、学習データと検証データの両方に含まれる見せかけの手掛かりに依存します。検証スコアは良好でも、その手掛かりがない新しいデータではモデルが失敗します。










