0Pricing
R Academy · 강의

학습, 검증 및 과적합 방지

val_loss를 모니터링하고 Dropout을 적용하며 조기 중단을 위해 콜백을 사용합니다.

학습, 검증 및 과적합 방지은(는) CoddyKit의 무료 R Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 R Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

훈련·검증·테스트 분할

딥러닝에는 세 가지 데이터 분할이 필요합니다. 훈련 데이터에서는 모델이 매개변수를 학습하고, 검증 데이터에서는 훈련 중 일반화 성능을 모니터링하고 하이퍼매개변수를 조정하며, 테스트 데이터에서는 최종적으로 편향 없는 평가를 수행합니다. fit()의 validation_split 인수를 사용하면 검증 세트가 자동으로 생성됩니다.

# 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)는 모니터링하는 지표가 patience 에포크 동안 향상되지 않으면 현재 학습률에 factor를 곱합니다.

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
)

정규화 요약

안정적인 딥러닝을 위해 여러 정규화 기법을 함께 사용해야 합니다.

  • 드롭아웃: 훈련 중 뉴런을 무작위로 0으로 만듭니다.
  • 가중치 감쇠(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')

빠른 확인

callback_early_stopping()에서 restore_best_weights = TRUE로 설정하면 어떤 일이 일어납니까?

훈련 및 과적합 요약

훈련, 검증 및 과적합 방지의 핵심 내용:

  • 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
)

자주 묻는 질문

“학습, 검증 및 과적합 방지” 강의는 무료인가요?

네 — “학습, 검증 및 과적합 방지” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 R Academy 강의 전체를 잠금 해제할 수 있습니다. R Academy 강의에는 총 4개의 강의가 포함되어 있습니다.

“학습, 검증 및 과적합 방지”에서 뭘 배우나요?

val_loss를 모니터링하고 Dropout을 적용하며 조기 중단을 위해 콜백을 사용합니다. 브라우저에서 직접 실행하는 실습 코드로 R Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

R Academy을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 R Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.

“학습, 검증 및 과적합 방지” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 R Academy 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 R Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. R에서 Keras와 TensorFlow 설정하기
  2. 순차 모델 구축
  3. 합성곱 신경망 기초
  4. 학습, 검증 및 과적합 방지
← R Academy(으)로 돌아가기