A training loop turns a model’s predictions into better weights. It repeatedly compares predictions with targets, measures the mismatch with a loss function, and adjusts the weights to reduce that loss. Weights usually start at random values, so learning takes many updates. section 1.6 section 2.4
Train a handwritten-digit classifier
In R with Keras, `fit()` runs the loop: ```r mnist <- dataset_mnist(convert = FALSE) train_images <- mnist$train$x$ reshape(shape(60000, 28 * 28))$astype("float32") / 255 train_labels <- mnist$train$y model <- keras_model_sequential() |> layer_dense(units = 512, activation = "relu") |> layer_dense(units = 10, activation = "softmax") model |> compile( optimizer = "adam", loss = "sparse_categorical_crossentropy", metrics = "accuracy" ) fit(model, train_images, train_labels, epochs = 5, batch_size = 128) ``` The loss supplies feedback; the optimizer determines how weights change. Here, `fit()` makes five passes through the training images, processing 128 at a time. section 2.5
For each batch, the loop:
- Takes training inputs and their corresponding targets. section 2.4
- Runs a forward pass to produce predictions, then computes their loss against the targets. section 2.4
- Computes gradients of the loss with respect to the weights and updates those weights to lower the batch loss. section 2.5
One pass through all batches is an epoch. The loop repeats epochs; in the digit example, five epochs produce 2,345 gradient updates. Loss may differ from batch to batch, so an individual update need not show a lower reported loss than the previous one. section 2.5 section 2.5.3
fit <- function(model, images, labels, epochs, batch_size = 128) {
for (epoch_counter in seq_len(epochs)) {
cat("Epoch ", epoch_counter, "\n")
batch_generator <- new_batch_generator(images, labels, batch_size)
batch_counter <- 0
repeat {
batch <- batch_generator() %||% break
batch_counter <- batch_counter + 1
loss <- one_training_step(model, batch$images, batch$labels)
if (batch_counter %% 100 == 0)
cat(sprintf("loss at batch %s: %.2f\n", batch_counter, loss))
}
}
}
The custom `fit()` listing shows the two nested repetitions: an outer epoch loop and an inner loop that calls one training step for each batch. section 2.5.3
Use Keras `fit()` for the standard workflow. When its built-in behavior is insufficient, write custom training logic—for example, to accommodate learning without explicit targets or a novel algorithm. A custom loop still needs predictions, loss, gradients, and updates; in JAX, a stateless training step returns the updated weights. section 7.4 section 3.5.4


