Переобучение и валидация

Урок объясняет переобучение — главную ловушку обучения — и как его замечать по графику loss.

Переобучение (overfitting) — это когда модель отлично запомнила обучающие данные, но плохо работает на новых, потому что выучила шум вместо закономерностей.

Высокая точность на train ничего не значит, если на новых данных модель ошибается. Цель — обобщение, а не зубрёжка. Чтобы поймать переобучение, нужна отложенная валидационная выборка.

Train / val / test

ВыборкаЗачем
trainна ней обновляются веса
validationконтроль во время обучения, подбор гиперпараметров
testфинальная честная оценка, используется один раз

Как выглядит переобучение

Признак — train loss продолжает падать, а val loss разворачивается вверх. Сэмулируем такие кривые и найдём момент расхождения — код запускается:

train_loss = [0.9, 0.6, 0.4, 0.3, 0.25, 0.2, 0.18]
val_loss   = [0.95, 0.62, 0.45, 0.42, 0.46, 0.52, 0.60]

best_epoch = val_loss.index(min(val_loss))
print("лучшая эпоха (мин. val_loss):", best_epoch + 1)
print("после неё val_loss растёт -> переобучение")
for e, (t, v) in enumerate(zip(train_loss, val_loss), 1):
    flag = "  <-- разворот" if e == best_epoch + 2 else ""
    print(f"эпоха {e}: train={t}, val={v}{flag}")

Вывод:

лучшая эпоха (мин. val_loss): 4
после неё val_loss растёт -> переобучение
эпоха 1: train=0.9, val=0.95
эпоха 2: train=0.6, val=0.62
эпоха 3: train=0.4, val=0.45
эпоха 4: train=0.3, val=0.42
эпоха 5: train=0.25, val=0.46  <-- разворот
эпоха 6: train=0.2, val=0.52
эпоха 7: train=0.18, val=0.6

После 4-й эпохи val_loss пошёл вверх — модель начала переобучаться. Лучшая модель — на эпохе 4.

Кривые обучения

loss
 |\
 | \__ train (падает дальше)
 |  \______
 |   \          ___ val (разворот вверх)
 |    \____ ___/
 |         V  <-- здесь переобучение начинается
 +---------------------- эпохи

В Keras

Валидацию подключают параметром validation_split или validation_data (требует TF):

history = model.fit(
    x_train, y_train,
    epochs=20,
    validation_split=0.2,
)
# затем сравнить history.history["loss"] и ["val_loss"]

Как работает под капотом

Чем больше параметров и эпох, тем легче сети «запомнить» обучающие примеры дословно, включая случайный шум. На train loss это выглядит как успех, но на новых данных проваливается. Валидационная выборка — это «экзамен по неизвестным билетам»: расхождение train и val loss — самый надёжный сигнал, что пора останавливаться или упрощать модель.

Частые ошибки

  • Смотреть только на train. Без валидации переобучение незаметно.
  • Подсматривать в test. Тестовую выборку трогают один раз в самом конце, иначе оценка нечестная.
  • Слишком сложная модель для малых данных. Много параметров + мало примеров = гарантированное переобучение.

Итог

  • Переобучение — модель запомнила шум и плохо обобщает.
  • Сигнал — train loss падает, а val loss растёт.
  • Нужны три выборки: train (обучение), validation (контроль), test (финал).
  • Лучшая модель — там, где val loss минимален.
Проверьте себя
1. Какой признак переобучения по кривым обучения?
AИ train, и val loss падают одинаково
Btrain loss падает, а val loss начинает расти
CОба растут
Dval loss всегда ниже train loss
2. Для чего нужна валидационная выборка?
AЧтобы обучать веса
BЧтобы контролировать обобщение во время обучения и ловить переобучение
CЧтобы заменить тестовую
DЧтобы ускорить fit
3. Почему тестовую выборку нельзя использовать многократно во время разработки?
AОна слишком маленькая
BИначе финальная оценка станет нечестной — мы подстроимся под неё
CЭто замедляет обучение
DTest нужен только для отрисовки графиков