R Academy · Урок

Обучение, проверка и предотвращение переобучения

Отслеживайте val_loss, применяйте Dropout и используйте обратные вызовы для ранней остановки

Урок 4 из 413 шагов

«Обучение, проверка и предотвращение переобучения» — бесплатный урок R Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения R Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс R Academy содержит 4 уроков всего.

Разделение данных на обучающую, проверочную и тестовую выборки

Для глубокого обучения нужны три части данных: обучающая (модель изучает параметры), проверочная (контроль обобщающей способности во время обучения и настройка гиперпараметров) и тестовая (окончательная непредвзятая оценка). Аргумент validation_split в fit() автоматически создаёт проверочную выборку.

# validation_split = 0.2 reserves last 20% as validation
history <- model |> fit(
  x_train, y_train,
  epochs           = 50,
  batch_size       = 32,
  validation_split = 0.2,
  verbose          = 0
)

# history contains train and val metrics per epoch
names(history$metrics)

Объект истории обучения

Объект, возвращаемый функцией fit(), содержит список $metrics с одной записью для каждой зарегистрированной метрики на каждой эпохе. Вызовите plot(history), чтобы визуализировать кривые обучения и проверки рядом. Расходящиеся кривые (ошибка на обучении уменьшается, а на проверке выходит на плато) указывают на переобучение.

# Training loss and accuracy over epochs
head(history$metrics$loss)
head(history$metrics$val_loss)

# Plot training curves
plot(history)

# Or create a custom ggplot
library(ggplot2)
df <- data.frame(
  epoch    = seq_along(history$metrics$loss),
  train    = history$metrics$loss,
  val      = history$metrics$val_loss
)
ggplot(df, aes(epoch)) +
  geom_line(aes(y = train, colour = 'Train')) +
  geom_line(aes(y = val,   colour = 'Validation')) +
  labs(y = 'Loss', title = 'Training Curves')

Выявление переобучения

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

# Overfitting is visible in the history
# Example of overfitting signatures:
cat('Epoch 5  — Train loss: 0.12, Val loss: 0.18\n')
cat('Epoch 10 — Train loss: 0.06, Val loss: 0.21\n')
cat('Epoch 20 — Train loss: 0.02, Val loss: 0.31\n')

# The model should have stopped at epoch 5!
# Strategies: early stopping, dropout, regularisation, more data

callback_early_stopping()

callback_early_stopping(monitor, patience, restore_best_weights) останавливает обучение, когда отслеживаемая метрика перестаёт улучшаться. patience — число эпох ожидания после последнего улучшения. Установите restore_best_weights = TRUE, чтобы автоматически вернуть веса эпохи с лучшим результатом.

early_stop <- callback_early_stopping(
  monitor              = 'val_loss',
  patience             = 10,        # wait 10 epochs
  restore_best_weights = TRUE       # rollback to best
)

history <- model |> fit(
  x_train, y_train,
  epochs           = 200,
  batch_size       = 32,
  validation_split = 0.2,
  callbacks        = list(early_stop),
  verbose          = 0
)

cat('Stopped at epoch:', length(history$metrics$loss))

callback_reduce_lr_on_plateau()

Когда обучение останавливается, уменьшение скорости обучения часто возобновляет прогресс. callback_reduce_lr_on_plateau(monitor, factor, patience) умножает текущую скорость обучения на factor, если отслеживаемая метрика не улучшалась в течение patience эпох.

reduce_lr <- callback_reduce_lr_on_plateau(
  monitor  = 'val_loss',
  factor   = 0.5,    # halve the learning rate
  patience = 5,      # after 5 stagnant epochs
  min_lr   = 1e-6    # floor for learning rate
)

history <- model |> fit(
  x_train, y_train,
  epochs           = 100,
  batch_size       = 64,
  validation_split = 0.2,
  callbacks        = list(early_stop, reduce_lr),
  verbose          = 1
)

callback_model_checkpoint()

callback_model_checkpoint(filepath, save_best_only) сохраняет веса модели на диске в конце каждой эпохи (или только при улучшении результата с параметром save_best_only = TRUE). Это защищает от сбоев во время обучения и позволяет загрузить лучшую модель, даже если обучение продолжается после оптимальной точки.

checkpoint <- callback_model_checkpoint(
  filepath       = '/tmp/best_model.h5',
  monitor        = 'val_accuracy',
  save_best_only = TRUE,
  mode           = 'max',      # higher accuracy = better
  verbose        = 1
)

history <- model |> fit(
  x_train, y_train,
  epochs           = 100,
  batch_size       = 32,
  validation_split = 0.2,
  callbacks        = list(early_stop, reduce_lr, checkpoint)
)

# Reload best model
best_model <- load_model_hdf5('/tmp/best_model.h5')

validation_data и validation_split

validation_split берёт последние N% обучающих данных. Если данные упорядочены (например, это временной ряд), результат будет смещённым. Вместо этого используйте validation_data = list(x_val, y_val), чтобы передать заранее созданную проверочную выборку из случайного стратифицированного разбиения.

# Manually create a random validation split
set.seed(42)
val_idx  <- sample(nrow(x_train), size = 0.2 * nrow(x_train))
x_val    <- x_train[val_idx, ]
y_val    <- y_train[val_idx, ]
x_tr     <- x_train[-val_idx, ]
y_tr     <- y_train[-val_idx, ]

history <- model |> fit(
  x_tr, y_tr,
  epochs         = 50,
  batch_size     = 32,
  validation_data = list(x_val, y_val),  # explicit val set
  callbacks      = list(early_stop)
)

Влияние размера пакета

Размер пакета — важный гиперпараметр обучения. Маленькие пакеты вносят больше шума в оценки градиента (это действует как регуляризация) и помогают обобщению. Большие пакеты работают быстрее, но могут привести к более острым и менее обобщаемым минимумам. Типичные значения: 32, 64, 128. Сначала попробуйте 32.

# Compare training with different batch sizes
for (bs in c(32, 128, 512)) {
  set_weights(model, init_weights)  # reset
  h <- model |> fit(
    x_train, y_train,
    epochs           = 20,
    batch_size       = bs,
    validation_split = 0.2,
    verbose          = 0
  )
  cat('Batch:', bs, '| Val Acc:',
      tail(h$metrics$val_accuracy, 1), '\n')
}

Разогрев скорости обучения

Начало с очень маленькой скоростью обучения и её постепенное увеличение в течение первых нескольких эпох (разогрев) может стабилизировать обучение, особенно для больших моделей или небольших наборов данных. Пользовательский обратный вызов LearningRateScheduler позволяет реализовать такой подход.

# Custom learning rate schedule with warmup
lr_schedule <- function(epoch, lr) {
  if (epoch < 5) {
    return(lr * (epoch + 1) / 5)  # warmup
  } else if (epoch < 30) {
    return(lr)                     # constant
  } else {
    return(lr * 0.95)              # decay
  }
}

lr_callback <- callback_learning_rate_scheduler(lr_schedule)

history <- model |> fit(
  x_train, y_train,
  epochs     = 50,
  callbacks  = list(lr_callback, early_stop),
  validation_split = 0.2
)

Итоги регуляризации

Для надёжного глубокого обучения следует сочетать несколько методов регуляризации:

  • Прореживание: случайное обнуление нейронов во время обучения.
  • Убывание весов (L2): штраф за большие веса в функции потерь.
  • Раннее прекращение: остановка до того, как модель переобучится.
  • Расширение данных: искусственное увеличение размера обучающей выборки.
  • Нормализация по пакетам: стабилизация активаций и уменьшение сдвига ковариат.
model <- keras_model_sequential(input_shape = c(784)) |>
  layer_dense(512, use_bias = FALSE,
              kernel_regularizer = regularizer_l2(1e-4)) |>
  layer_batch_normalization() |>
  layer_activation('relu') |>
  layer_dropout(0.4) |>
  layer_dense(256, kernel_regularizer = regularizer_l2(1e-4)) |>
  layer_batch_normalization() |>
  layer_activation('relu') |>
  layer_dropout(0.3) |>
  layer_dense(10, activation = 'softmax')

model |> compile('adam', 'categorical_crossentropy', 'accuracy')

Построение кривых обучения

Всегда визуализируйте метрики обучения и проверки рядом. У хорошо обученной модели обе кривые должны сходиться и оставаться близкими. Если они расходятся, добавьте регуляризацию или уменьшите сложность модели. Если обе кривые выходят на плато при высокой ошибке, модель недообучена.

# Detailed training curve plot
df <- data.frame(
  epoch = seq_along(history$metrics$loss),
  train_loss = history$metrics$loss,
  val_loss   = history$metrics$val_loss,
  train_acc  = history$metrics$accuracy,
  val_acc    = history$metrics$val_accuracy
)

par(mfrow = c(1, 2))
plot(df$epoch, df$train_loss, type = 'l', col = 'blue',
     xlab = 'Epoch', ylab = 'Loss', main = 'Loss')
lines(df$epoch, df$val_loss, col = 'red')
legend('topright', c('Train', 'Val'), col = c('blue','red'), lty=1)

plot(df$epoch, df$train_acc, type = 'l', col = 'blue',
     xlab = 'Epoch', ylab = 'Accuracy', main = 'Accuracy')
lines(df$epoch, df$val_acc, col = 'red')

Быстрая проверка

Что делает установка restore_best_weights = TRUE в callback_early_stopping()?

Повторение: обучение и переобучение

Главные выводы из темы «Обучение, проверка и предотвращение переобучения»:

  • Используйте validation_split или validation_data, чтобы контролировать обобщающую способность во время обучения.
  • plot(history) визуализирует кривые обучения — их расхождение указывает на переобучение.
  • callback_early_stopping(patience, restore_best_weights=TRUE) останавливает обучение на оптимальной эпохе.
  • callback_reduce_lr_on_plateau() уменьшает скорость обучения, когда прогресс останавливается.
  • callback_model_checkpoint(save_best_only=TRUE) сохраняет лучшую модель на диске.
  • Сочетайте прореживание, L2-регуляризацию, нормализацию по пакетам и расширение данных для надёжного обучения.
# Best practice training setup
callbacks <- list(
  callback_early_stopping(
    monitor = 'val_loss', patience = 15,
    restore_best_weights = TRUE
  ),
  callback_reduce_lr_on_plateau(
    monitor = 'val_loss', factor = 0.5, patience = 5
  ),
  callback_model_checkpoint(
    '/tmp/best.h5', monitor = 'val_accuracy',
    save_best_only = TRUE
  )
)

model |> fit(
  x_train, y_train,
  epochs = 200, batch_size = 64,
  validation_split = 0.2,
  callbacks = callbacks, verbose = 0
)
Можно начать бесплатно

Изучай R с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
43
Уроки
159

Часто задаваемые вопросы

Урок «Обучение, проверка и предотвращение переобучения» бесплатный?

Да — полный текст урока «Обучение, проверка и предотвращение переобучения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс R Academy, подпишись на CoddyKit PRO. Курс R Academy содержит 4 уроков всего.

Чему я научусь в уроке «Обучение, проверка и предотвращение переобучения»?

Отслеживайте val_loss, применяйте Dropout и используйте обратные вызовы для ранней остановки Ты практикуешь R Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать R Academy?

Предыдущий опыт не требуется. R Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.

Сколько времени занимает урок «Обучение, проверка и предотвращение переобучения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке R Academy?

Да. Каждый урок R Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Настройка Keras и TensorFlow в R
  2. Создание последовательных моделей
  3. Основы свёрточных нейронных сетей
  4. Обучение, проверка и предотвращение переобучения
← Назад к R Academy