Переобучение и регуляризация

Главная болезнь обучения — переобучение — и два рабочих лекарства от неё.

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

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

Признак простой и надёжный: loss на обучении продолжает падать, а на валидации перестаёт улучшаться или начинает расти. Модель «зубрит» тренировочные примеры вместо того, чтобы выучить общую закономерность.

train lossval lossДиагноз
высокийвысокийнедообучение (модель слаба)
низкийнизкийхорошо
низкийвысокийпереобучение

Поэтому валидация (из прошлого раздела) — не формальность: только разрыв между train и val loss показывает переобучение. Без неё вы бы радовались падающему train loss, не зная, что модель бесполезна на новых данных.

Лекарство 1: Dropout

nn.Dropout(p) при обучении случайно обнуляет долю p нейронов на каждом шаге. Модель не может полагаться на конкретные нейроны и вынуждена учить более устойчивые, «размазанные» представления. Ставят его между слоями:

import torch.nn as nn

model = nn.Sequential(
    nn.Linear(784, 256),
    nn.ReLU(),
    nn.Dropout(0.5),        # гасим 50% нейронов при обучении
    nn.Linear(256, 10),
)

Здесь критична связь с прошлым уроком: dropout работает только в model.train(). В model.eval() он автоматически отключается и пропускает все нейроны. Вот зачем нужны режимы — забыть переключить значит либо потерять регуляризацию, либо получить случайные предсказания.

Лекарство 2: Weight decay (L2)

Второй приём — штрафовать модель за слишком большие веса. Большие веса часто означают, что модель подгоняется под шум. Weight decay добавляет к loss штраф, пропорциональный размеру весов, мягко притягивая их к нулю. В PyTorch это не отдельный код, а один аргумент оптимизатора:

optimizer = torch.optim.Adam(
    model.parameters(),
    lr=0.001,
    weight_decay=1e-4,     # сила L2-регуляризации
)

Чем больше weight_decay, тем сильнее давление на веса. Типичные значения — 1e-4, 1e-5. Удобно тем, что не требует менять архитектуру: дописали один параметр.

Другие способы бороться

  • Больше данных — самый надёжный способ: чем больше примеров, тем труднее их зазубрить.
  • Проще модель — меньше слоёв/нейронов, меньше способность запоминать.
  • Early stopping — остановить обучение, когда val loss перестал падать.
  • Аугментация данных — случайные повороты/сдвиги картинок расширяют датасет искусственно.

Как применять на практике

Обычный рецепт: следите за train и val loss; как только они разойдутся — добавьте dropout и/или weight decay, упростите модель или дайте больше данных. Регуляризация — это всегда баланс: слишком сильная мешает учиться (недообучение), слишком слабая не спасает от переобучения. Подбирают экспериментом по валидации.

Итог

  • Переобучение видно по разрыву: train loss низкий, val loss высокий.
  • nn.Dropout(p) гасит нейроны при обучении; работает только в режиме train().
  • weight_decay у оптимизатора штрафует большие веса (L2) — один аргумент, без смены архитектуры.
  • Также помогают: больше данных, более простая модель, early stopping, аугментация.
Проверьте себя
1. Как по значениям loss распознать переобучение?
Atrain loss высокий и val loss высокий
Btrain loss низкий, а val loss высокий
Cоба loss низкие
Dval loss всегда равен train loss
2. В каком режиме модели действует Dropout?
AВсегда, в любом режиме
BТолько в model.train(); в eval() он отключается
CТолько в model.eval()
DТолько на GPU
3. Как включить L2-регуляризацию (weight decay) в PyTorch?
AДобавить слой nn.L2()
BПередать аргумент weight_decay в оптимизатор
CВызвать model.regularize()
DУмножить loss на коэффициент вручную
Поддержать проект