Epoch vs Batch Size vs Iteration in Machine Learning

эпоха итерации батчи (batch size)

If you have trained a neural network, you have written something like model.fit(X, y, epochs=10, batch_size=32) and wondered what exactly the numbers mean and how they relate to the “steps” or “iterations” in the training log. The three terms look similar, but they measure different things. An epoch is one complete pass of the whole training dataset through the model. The batch size is how many training examples the model looks at before it updates its weights once. An iteration, or step, is one such update, so the number of iterations in an epoch equals the number of batches.

This guide explains the three terms through gradient descent, shows how to calculate them, and runs two experiments in PyTorch: one shows how the number of epochs leads from underfitting to overfitting and how early stopping picks the right moment, the other shows what the batch size changes in training.

Key takeaways

  • Epoch: the model has seen every training example once.
  • Batch size: the number of examples used to compute one gradient and make one weight update.
  • Iteration (step): one weight update on one batch. iterations per epoch = ceil(training examples / batch size).
  • Example: 2,000 examples with a batch size of 500 give 4 iterations per epoch; 10 epochs give 40 weight updates.
  • Choosing them: use early stopping on a validation set instead of guessing the number of epochs; start with a batch size of 32 to 256 and adjust it to your memory and learning rate.

Epoch, Batch Size and Iteration at a Glance

Term Meaning Example: 2,000 examples, batch size 500, 10 epochs
Epoch One full pass over the training dataset 10 epochs
Batch A subset of the training data processed together Each epoch is split into 4 batches
Batch size The number of examples in one batch 500
Iteration (step) One forward and backward pass on one batch, followed by one weight update 4 per epoch, 40 in total

Note that the batch size and the number of batches are two different numbers: the batch size is how big each batch is, the number of batches is how many of them make up an epoch. For one epoch, the number of batches equals the number of iterations.

Why We Need Them: Gradient Descent

To see why training is organized into epochs and batches, recall how neural networks learn. Gradient descent is an iterative optimization algorithm: it computes the gradient of the loss function with respect to the model’s weights, which shows the direction in which the loss grows fastest, and takes a small step in the opposite direction. The size of the step is controlled by the learning rate. Repeating this many times moves the model to a point where the loss, also called the cost, is low:

Gradient descent animation: points step down a parabolic cost curve towards its minimum while a fitted line converges to the labeled data
Gradient descent takes many small steps towards the minimum of the cost function

The animation shows exactly this: each step moves the parameter towards the minimum of the cost function, the steps get smaller as the slope flattens, and the fitted regression line on the right gets closer to the data. One step is never enough; training needs many of them. The question is how much data to use to compute each step:

Variant Batch size Iterations per epoch Properties
Batch gradient descent The whole dataset 1 Exact gradient, but slow updates and the whole dataset must fit in memory
Stochastic gradient descent (SGD) 1 Number of examples Very frequent, very noisy updates; cannot use the parallelism of GPUs
Mini-batch gradient descent Usually 16 to a few thousand Examples / batch size The standard in deep learning: fits in memory, uses GPUs well, reasonably accurate gradients

Real datasets are far too large to push through a network at once, so the data is divided into batches, loaded one after another, and the weights are updated after each one. In deep learning, “SGD” in practice almost always means mini-batch gradient descent, and the optimizers you use, such as SGD with momentum or Adam, all work on mini-batches. The gradients themselves are computed with backpropagation.

What Is an Epoch in Machine Learning?

An epoch is complete when the entire training dataset has passed forward and backward through the neural network once. Because one epoch is usually too big to process at once, it is divided into batches, and the epoch consists of as many iterations as there are batches. Before each epoch, the training examples are usually shuffled, so that the batches are different every time.

Why use more than one epoch? At first it may seem strange that passing the whole dataset through the network once is not enough. But gradient descent is an iterative process, and one pass gives only a limited number of small steps, typically too few to reach a good minimum. As the number of epochs grows, the weights are updated more times, and the model moves from underfitting, where it has not yet learned the patterns in the data, to an optimal fit. If training continues too long, it moves on to overfitting: the model fits the training examples, including their noise, so closely that it loses the ability to generalize to new data.

Three curves fitted to the same points: an overfitting curve that passes through every point, an optimal smooth curve and an underfitting straight line
Too many epochs lead to overfitting, too few to underfitting

How Many Epochs? Overfitting and Early Stopping

There is no universal right number of epochs: it depends on the size and diversity of the dataset, the model and the learning rate. A dataset with only black cats needs fewer epochs to learn than one with every kind of cat. The reliable way to decide is to measure: keep a validation set that the model does not train on, check its loss after every epoch, and stop when it stops improving. This is called early stopping.

The experiment below trains a small multilayer perceptron on just 300 handwritten digits, so that overfitting shows up quickly, and evaluates it on 500 other digits after every epoch. It also counts iterations: with 300 examples and a batch size of 32, each epoch has 10 of them:

import torch
import torch.nn as nn
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from torch.utils.data import DataLoader, TensorDataset

torch.manual_seed(0)
X, y = load_digits(return_X_y=True)
X = torch.tensor(X / 16, dtype=torch.float32)
y = torch.tensor(y)
# a deliberately small training set, so that overfitting shows up quickly
X_train, X_val, y_train, y_val = train_test_split(X, y, train_size=300, test_size=500, random_state=0, stratify=y)
loader = DataLoader(TensorDataset(X_train, y_train), batch_size=32, shuffle=True)

model = nn.Sequential(nn.Linear(64, 256), nn.ReLU(), nn.Linear(256, 256), nn.ReLU(), nn.Linear(256, 10))
opt = torch.optim.Adam(model.parameters(), lr=1e-3)
loss_fn = nn.CrossEntropyLoss()

best_val, best_epoch, patience, iteration = float("inf"), 0, 15, 0
for epoch in range(1, 201):                       # one epoch = one pass over all 300 training examples
    model.train()
    for xb, yb in loader:                         # one iteration = one batch of 32 = one weight update
        loss = loss_fn(model(xb), yb)
        opt.zero_grad()
        loss.backward()
        opt.step()
        iteration += 1
    model.eval()
    with torch.no_grad():
        train_loss = loss_fn(model(X_train), y_train).item()
        val_loss = loss_fn(model(X_val), y_val).item()
        val_acc = (model(X_val).argmax(1) == y_val).float().mean().item()
    if epoch in (1, 5, 10, 20, 50, 100, 200) or epoch == best_epoch + patience:
        print(f"epoch {epoch:3d} (iteration {iteration:4d}): train loss {train_loss:.4f}, "
              f"val loss {val_loss:.4f}, val accuracy {val_acc:.3f}")
    if val_loss < best_val:
        best_val, best_epoch = val_loss, epoch
    elif epoch == best_epoch + patience:
        print(f"early stopping would stop here; best epoch was {best_epoch} (val loss {best_val:.4f})")
epoch   1 (iteration   10): train loss 2.1173, val loss 2.1250, val accuracy 0.642
epoch   5 (iteration   50): train loss 0.5194, val loss 0.5886, val accuracy 0.880
epoch  10 (iteration  100): train loss 0.1504, val loss 0.2733, val accuracy 0.940
epoch  20 (iteration  200): train loss 0.0475, val loss 0.2133, val accuracy 0.942
epoch  41 (iteration  410): train loss 0.0101, val loss 0.2232, val accuracy 0.950
early stopping would stop here; best epoch was 26 (val loss 0.2053)
epoch  50 (iteration  500): train loss 0.0061, val loss 0.2339, val accuracy 0.948
epoch 100 (iteration 1000): train loss 0.0013, val loss 0.2816, val accuracy 0.950
epoch 200 (iteration 2000): train loss 0.0003, val loss 0.3338, val accuracy 0.948
Line chart of training and validation loss over 200 epochs: training loss falls toward zero, validation loss reaches its minimum at epoch 26 and then rises, showing overfitting and the early stopping point
Training and validation loss by epoch: the best model is at epoch 26

For the first 10 to 20 epochs both losses fall quickly: the model is underfitting and every epoch helps. The validation loss reaches its minimum at epoch 26. After that, the training loss keeps falling towards zero, but the validation loss rises by more than 60% by epoch 200: the model is memorizing the training examples and becoming overconfident on new ones. Accuracy hardly changes here, but the growing loss shows that its predictions are getting worse calibrated. With a patience of 15 epochs, early stopping would end training at epoch 41 and keep the weights from epoch 26, saving about 80% of the training time.

Typical numbers of epochs in practice:

  • Small datasets and models, such as tabular data or the example above: tens to hundreds of epochs, controlled by early stopping.
  • Image classification from scratch, for example ResNets on ImageNet: roughly 90 to a few hundred epochs, with a learning rate schedule.
  • Fine-tuning a pretrained model: often 1 to 5 epochs, because the model already knows most of what it needs.
  • Large language models: pretraining datasets are so large that models usually see most of the data only once, about one epoch, and training length is measured in tokens or steps instead.

Besides early stopping, overfitting is fought with more data, data augmentation, dropout, weight decay and smaller models.

What Is Batch Size?

The batch size is the number of training examples in one batch, and therefore the number of examples used to compute one gradient. It works like splitting a long article into sections: the content stays the same, but it is easier to process piece by piece. The gradient of a batch is an estimate of the gradient over the whole dataset; the bigger the batch, the more accurate the estimate, and the more memory and computation each step needs.

Choosing the batch size is a trade-off:

  • Memory. The batch has to fit into GPU memory together with the model and its activations. This is often the hard upper limit. When a larger batch does not fit, gradient accumulation sums the gradients of several smaller batches before making one update, which gives almost the same result as a larger batch.
  • Speed per epoch. GPUs process many examples in parallel, so larger batches finish an epoch faster, up to the point where the hardware is saturated.
  • Number of updates. Larger batches mean fewer weight updates per epoch. With the same number of epochs and the same learning rate, a model trained with large batches learns less.
  • Noise and generalization. Small batches give noisy gradients, which acts as a regularizer and can help the model find solutions that generalize well. Nitish Keskar and colleagues showed in 2017 that very large batches tend to converge to “sharp” minima that generalize worse.

Batch size and learning rate are linked. A common rule of thumb, the linear scaling rule from the 2017 paper “Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour” by Priya Goyal and colleagues at Facebook, says: when you multiply the batch size by k, multiply the learning rate by k too, and warm it up over the first few epochs. With this rule they trained a ResNet-50 on ImageNet with batches of 8,192 images without losing accuracy. Powers of two such as 32, 64 or 128 are traditional, but there is nothing magical about them.

How Batch Size Affects Training

Here the same network is trained for exactly 20 epochs on 1,257 digits with six different batch sizes, from a single example to the whole training set, keeping everything else the same:

import time
import torch
import torch.nn as nn
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from torch.utils.data import DataLoader, TensorDataset

X, y = load_digits(return_X_y=True)
X, y = torch.tensor(X / 16, dtype=torch.float32), torch.tensor(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0, stratify=y)

def run(batch_size, epochs=20):
    torch.manual_seed(0)
    model = nn.Sequential(nn.Linear(64, 128), nn.ReLU(), nn.Linear(128, 10))
    opt = torch.optim.Adam(model.parameters(), lr=1e-3)
    loader = DataLoader(TensorDataset(X_train, y_train), batch_size=batch_size, shuffle=True)
    start = time.perf_counter()
    for epoch in range(epochs):
        for xb, yb in loader:
            loss = nn.functional.cross_entropy(model(xb), yb)
            opt.zero_grad()
            loss.backward()
            opt.step()
    seconds = time.perf_counter() - start
    with torch.no_grad():
        acc = (model(X_test).argmax(1) == y_test).float().mean().item()
    return len(loader) * epochs, seconds, acc

print(f"{len(X_train)} training examples, 20 epochs, Adam with learning rate 0.001")
for batch_size in (1, 8, 32, 128, 512, len(X_train)):
    updates, seconds, acc = run(batch_size)
    print(f"batch size {batch_size:4d}: {updates:5d} updates, {seconds:5.1f} s, test accuracy {acc:.3f}")
1257 training examples, 20 epochs, Adam with learning rate 0.001
batch size    1: 25140 updates,  16.6 s, test accuracy 0.976
batch size    8:  3160 updates,   2.4 s, test accuracy 0.978
batch size   32:   800 updates,   0.6 s, test accuracy 0.963
batch size  128:   200 updates,   0.3 s, test accuracy 0.939
batch size  512:    60 updates,   0.2 s, test accuracy 0.885
batch size 1257:    20 updates,   0.4 s, test accuracy 0.793
Horizontal bar chart: after 20 epochs, test accuracy falls from about 98% with batch sizes 1 and 8 to 79% with full-batch training, because larger batches mean fewer weight updates
Test accuracy after 20 epochs with different batch sizes

Twenty epochs mean very different amounts of training. With a batch size of 1, the model makes 25,140 updates; with the full batch, only 20, and it is still far from trained, with 79% accuracy. Small batches reach about 98% but take much longer: processing examples one at a time is almost 30 times slower than in batches of 32, even on a CPU. The times were measured on a CPU and will differ on your machine, but the pattern is general. Large batches are not worse in themselves: given more epochs or a larger learning rate, they catch up. The lesson is that the number of epochs alone does not tell you how much a model has been trained; the number of iterations does.

A practical recipe: start with a batch size between 32 and 256, the largest that fits comfortably in memory, tune the learning rate for it, and if you change the batch size later, scale the learning rate with it.

What Is an Iteration?

An iteration, also called a step or an update, is one pass of one batch forward and backward through the network followed by one update of the weights. The number of iterations needed to complete one epoch is:

iterations per epoch = ceil(number of training examples / batch size)
total iterations = epochs × iterations per epoch

For example, if we have 2,000 training examples and divide them into batches of 500, one epoch takes 4 iterations. If the dataset does not divide evenly, the last batch is smaller, unless you drop it, for example with drop_last=True in PyTorch. In PyTorch, len(loader) gives the number of iterations per epoch:

import math
import torch
from torch.utils.data import DataLoader, TensorDataset

dataset = TensorDataset(torch.randn(2000, 10), torch.randint(0, 2, (2000,)))   # 2,000 training examples
epochs = 10
for batch_size in (500, 64, 1):
    loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
    iterations = len(loader)                              # batches per epoch = ceil(2000 / batch_size)
    print(f"batch size {batch_size:3d}: {iterations:4d} iterations per epoch, "
          f"{iterations * epochs:5d} weight updates in {epochs} epochs")

loader = DataLoader(dataset, batch_size=64, shuffle=True)
sizes = [len(x) for x, y in loader]
print("batch sizes in one epoch:", sizes[:3], "...", sizes[-2:], "| ceil(2000 / 64) =", math.ceil(2000 / 64))
batch size 500:    4 iterations per epoch,    40 weight updates in 10 epochs
batch size  64:   32 iterations per epoch,   320 weight updates in 10 epochs
batch size   1: 2000 iterations per epoch, 20000 weight updates in 10 epochs
batch sizes in one epoch: [64, 64, 64] ... [64, 16] | ceil(2000 / 64) = 32

With a batch size of 64, the epoch has 31 full batches and a last one of 16 examples, 32 iterations in total. In Keras, the same quantity is called steps_per_epoch; when you train on an endless data stream, you set it yourself to define how many steps count as an epoch. Learning rate schedules, logging and checkpoints are often defined in steps rather than epochs, especially for large models.

Epoch vs Batch vs Iteration

Epoch Batch size Iteration
What it counts Passes over the whole dataset Examples per update Weight updates
Set by You, or early stopping You, limited by memory Follows from the other two
Too small Underfitting Slow, noisy training Model not trained enough
Too large Overfitting, wasted compute Out of memory, fewer updates, possibly worse generalization Overfitting, wasted compute
In Keras epochs batch_size steps_per_epoch
In PyTorch Outer training loop DataLoader(batch_size=...) Inner loop over the DataLoader

In short: the batch size decides how many examples go into one step, an iteration is one step, and an epoch is as many steps as it takes to see all the data once.

FAQ

What is an epoch in machine learning?

An epoch is one complete pass of the entire training dataset through the model. If a model is trained for 10 epochs, it has seen every training example 10 times.

What is the difference between an epoch and a batch?

A batch is a subset of the training data used for one weight update; an epoch is a full pass over all the data, which consists of all the batches. With 1,000 examples and a batch size of 100, one epoch contains 10 batches.

What is the difference between an epoch and an iteration?

An iteration is one weight update on one batch. An epoch is completed after as many iterations as there are batches in the dataset. Iterations count updates, epochs count passes over the data.

How many epochs should I train for?

There is no fixed number. Monitor the loss on a validation set and use early stopping: stop when the validation loss has not improved for a number of epochs, and keep the best weights. Small datasets often need tens to hundreds of epochs; fine-tuning pretrained models usually needs only a few.

What is a good batch size?

Values between 32 and 256 are a common starting point. Use the largest batch that fits in memory without hurting results, and when you change it, adjust the learning rate proportionally. Very small batches are slow; very large ones need more epochs or a larger learning rate and may generalize slightly worse.

Does a larger batch size train faster?

A larger batch processes an epoch faster on a GPU, but it makes fewer updates per epoch, so it may need more epochs to reach the same accuracy. Whether total training time goes down depends on the hardware and on adjusting the learning rate.

Can the batch size be 1?

Yes. This is stochastic gradient descent in its original form. It works, but it is slow because it does not use parallel hardware, and its updates are very noisy.

See also: our guides to gradient descent, which explains the optimization behind epochs and batches, and to backpropagation, which computes the gradient in every iteration.


bnr2mob
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted