Epoch
An epoch is one full pass of a model through its training data. See how epochs relate to batches and iterations, and how many to train for.
An epoch is one complete pass of a machine learning model through its entire training dataset. During an epoch, every training example contributes to the updates of the model weights exactly once. Deep learning models rarely learn enough from a single pass, so training runs for many epochs, and the error on the training data typically falls with each one as the network refines its predictions.
Epoch vs. Batch vs. Iteration#
Three terms describe the structure of a training run, and each one nests inside the one before it:
- Epoch: One full pass over the training dataset.
- Batch: The group of examples processed together in one step. Datasets rarely fit in GPU memory at once, so each epoch is split into batches, usually after shuffling the data.
- Iteration: One weight update, made after the loss function is computed on a batch and its gradients flow back through backpropagation. "Step" is a synonym.
The number of iterations per epoch equals the dataset size divided by the batch size, rounded up. A dataset of 1,000 images with a batch size of 100 takes 10 iterations per epoch, so 50 epochs make 500 weight updates. In PyTorch, this structure appears as two nested loops: an outer loop over epochs and an inner loop over the batches that a DataLoader serves.
import torch
from torch.utils.data import DataLoader, TensorDataset
torch.manual_seed(0)
# 1,000 noisy samples of the line y = 3x + 2, served in shuffled batches of 100
x = torch.rand(1000, 1)
y = 3 * x + 2 + 0.1 * torch.randn(1000, 1)
loader = DataLoader(TensorDataset(x, y), batch_size=100, shuffle=True)
model = torch.nn.Linear(1, 1)
optimizer = torch.optim.SGD(model.parameters(), lr=0.5)
for epoch in range(5): # one epoch = one full pass over all 1,000 samples
for xb, yb in loader: # 1,000 / 100 = 10 iterations per epoch
loss = torch.nn.functional.mse_loss(model(xb), yb)
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"Epoch {epoch + 1}: {len(loader)} iterations, last batch loss {loss.item():.4f}")Every epoch runs 10 iterations, and the loss on the final batch falls from 0.1096 after the first epoch to 0.0088 after the fifth as the model converges on the true line. When training uses data augmentation, each epoch sees a freshly transformed version of every image, so later epochs add variety instead of exact repeats.
Choosing the Number of Epochs#
The epoch count is one of the main settings in hyperparameter tuning. Too few epochs leave a model underfitting, with high error on both training and validation data. Too many push it toward overfitting, where training loss keeps falling while the validation score stalls or drops because the model has started to memorize its training examples. The right count depends on dataset size, model size, the learning rate schedule, and whether training starts from pretrained weights through transfer learning. Scale changes the answer too: small vision datasets often train for hundreds of epochs, while large language models see much of their data less than once, and GPT-3 completed 0.44 epochs over its filtered Common Crawl data.
Early stopping automates the choice. The model is evaluated on validation data after every epoch, the best checkpoint is kept, and training ends once the validation score has not improved for a set number of epochs, called the patience.
Epoch-Based Training Schedules#
Beyond the stopping point, many training settings change on an epoch schedule, such as learning-rate warmup and decay or augmentation strength. In Ultralytics YOLO training, epochs and patience both default to 100, the learning rate warms up over the first 3 epochs, and mosaic augmentation switches off for the final 10 epochs (close_mosaic=10) so the model finishes on images that look like real inputs. The YOLO26 training recipe shows how much the count varies with model size: after 150 epochs of pretraining on Objects365, COCO fine-tuning ran for 245 epochs for YOLO26n and 40 epochs for YOLO26x.
from ultralytics import YOLO
# Load a pretrained YOLO26n model
model = YOLO("yolo26n.pt")
# Train for 50 epochs: 50 full passes over the COCO8 training images
results = model.train(data="coco8.yaml", epochs=50, imgsz=640)During this run, the trainer validates the YOLO26 model after every epoch, overwrites last.pt each time, and saves best.pt whenever the validation fitness, which is mAP50-95 for detection, reaches a new high.










