学習、検証、過学習の防止
val_loss を監視し、Dropout を適用して、コールバックで早期停止を行います。
「学習、検証、過学習の防止」はCoddyKit上の無料R Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはR Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 R Academyコースには全4レッスンが含まれています。
学習・検証・テストへの分割
深層学習では、データを3つに分割します。学習用(モデルがパラメータを学習する)、検証用(学習中に汎化性能を監視し、ハイパーパラメータを調整する)、テスト用(最終的に偏りなく評価する)です。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 datacallback_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
)正則化のまとめ
堅牢な深層学習のためには、複数の正則化手法を組み合わせる必要があります。
- ドロップアウト:学習中にニューロンをランダムにゼロにします。
- 重み減衰(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時間対応のAIチューター)、R Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 R Academyコースには全4レッスンが含まれています。
「学習、検証、過学習の防止」で何を学びますか?
val_loss を監視し、Dropout を適用して、コールバックで早期停止を行います。 ブラウザで直接実行するハンズオンコードでR Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
R Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのR Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「学習、検証、過学習の防止」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このR Academyレッスンでコードを書いて実行できますか?
はい。すべてのR Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。