AnyLearn
All lessons
AIintermediate

Training: Optimization and Regularization

Go from a raw neural network to one that actually generalizes. Covers loss functions (MSE, cross-entropy), gradient descent variants (SGD, momentum, Adam), learning-rate effects, overfitting vs underfitting, and the regularization toolkit (L2/dropout/early stopping/batch norm).

Not signed in โ€” your progress and quiz score won't be saved.
Lesson progress1 / 9

Loss functions: what you're actually minimizing

The loss is the single number that training minimizes. Choosing the wrong one silently cripples your model.

  • Mean Squared Error (MSE): L=1Nโˆ‘i(yiโˆ’y^i)2\mathcal{L} = \frac{1}{N}\sum_i (y_i - \hat{y}_i)^2. Use for regression. Penalizes large errors quadratically โ€” outliers dominate.
  • Binary Cross-Entropy: L=โˆ’1Nโˆ‘i[yilogโกp^i+(1โˆ’yi)logโก(1โˆ’p^i)]\mathcal{L} = -\frac{1}{N}\sum_i [y_i \log \hat{p}_i + (1-y_i)\log(1-\hat{p}_i)]. Use for binary classification with a sigmoid output.
  • Categorical Cross-Entropy: L=โˆ’1Nโˆ‘iโˆ‘kyiklogโกp^ik\mathcal{L} = -\frac{1}{N}\sum_i \sum_k y_{ik} \log \hat{p}_{ik}. Use for multiclass with softmax output.

Cross-entropy is preferred over MSE for classification because it is derived from maximum likelihood, produces sharper gradients near decision boundaries, and avoids the flat gradient saturation problem of MSE + sigmoid.

Full lesson text

All 9 steps on one page โ€” for reading, reference, and search.

Show

1. Loss functions: what you're actually minimizing

The loss is the single number that training minimizes. Choosing the wrong one silently cripples your model.

  • Mean Squared Error (MSE): L=1Nโˆ‘i(yiโˆ’y^i)2\mathcal{L} = \frac{1}{N}\sum_i (y_i - \hat{y}_i)^2. Use for regression. Penalizes large errors quadratically โ€” outliers dominate.
  • Binary Cross-Entropy: L=โˆ’1Nโˆ‘i[yilogโกp^i+(1โˆ’yi)logโก(1โˆ’p^i)]\mathcal{L} = -\frac{1}{N}\sum_i [y_i \log \hat{p}_i + (1-y_i)\log(1-\hat{p}_i)]. Use for binary classification with a sigmoid output.
  • Categorical Cross-Entropy: L=โˆ’1Nโˆ‘iโˆ‘kyiklogโกp^ik\mathcal{L} = -\frac{1}{N}\sum_i \sum_k y_{ik} \log \hat{p}_{ik}. Use for multiclass with softmax output.

Cross-entropy is preferred over MSE for classification because it is derived from maximum likelihood, produces sharper gradients near decision boundaries, and avoids the flat gradient saturation problem of MSE + sigmoid.

2. Gradient descent: the core update rule

All neural network optimizers are variants of gradient descent:

ฮธโ†ฮธโˆ’ฮทโˆ‡ฮธL\theta \leftarrow \theta - \eta \nabla_\theta \mathcal{L}

where ฮท>0\eta > 0 is the learning rate and โˆ‡ฮธL\nabla_\theta \mathcal{L} is the gradient of the loss with respect to parameters ฮธ\theta.

Full-batch gradient descent computes the gradient over the entire dataset โ€” exact but slow for large data. Stochastic gradient descent (SGD) uses a single example per step โ€” noisy but fast. Mini-batch SGD (the standard) uses a batch of BB examples, balancing signal quality and compute:

for epoch in range(num_epochs):
    for X_batch, y_batch in dataloader:  # batch size B
        loss = compute_loss(model(X_batch), y_batch)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

The noise in SGD is actually beneficial: it acts as an implicit regularizer and helps escape sharp local minima.

3. Momentum and Adam: going beyond vanilla SGD

Vanilla SGD oscillates in ravines and crawls on flat plateaus. Modern optimizers fix this.

OptimizerKey ideaExtra cost
SGDFollow negative gradientNone
SGD + MomentumAccumulate velocity: vโ†ฮฒvโˆ’ฮทgv \leftarrow \beta v - \eta g, ฮธโ†ฮธ+v\theta \leftarrow \theta + v1 momentum buffer
RMSPropScale ฮท\eta by running average of g2g^2; large gradients get smaller steps1 variance buffer
AdamMomentum + RMSProp + bias correction2 buffers

Adam update (ฮฒ1=0.9\beta_1 = 0.9, ฮฒ2=0.999\beta_2 = 0.999, ฯต=10โˆ’8\epsilon = 10^{-8} are standard defaults):

mt=ฮฒ1mtโˆ’1+(1โˆ’ฮฒ1)gt,vt=ฮฒ2vtโˆ’1+(1โˆ’ฮฒ2)gt2m_t = \beta_1 m_{t-1} + (1-\beta_1)g_t, \quad v_t = \beta_2 v_{t-1} + (1-\beta_2)g_t^2 m^t=mt/(1โˆ’ฮฒ1t),v^t=vt/(1โˆ’ฮฒ2t)\hat{m}_t = m_t/(1-\beta_1^t), \quad \hat{v}_t = v_t/(1-\beta_2^t) ฮธt=ฮธtโˆ’1โˆ’ฮทโ€‰m^t/(v^t+ฯต)\theta_t = \theta_{t-1} - \eta\, \hat{m}_t / (\sqrt{\hat{v}_t} + \epsilon)

Adam is robust to learning-rate choice and converges fast. SGD + momentum often wins at convergence quality with careful tuning โ€” many large-scale vision papers still use it.

4. Learning rate: the most important hyperparameter

The learning rate ฮท\eta controls how large each step is. Get it wrong and nothing else matters.

  • Too large: loss oscillates or diverges. Weights overshoot the minimum.
  • Too small: training is painfully slow and may stall in flat regions.
  • Just right: loss decreases smoothly and plateaus at a good value.

Learning rate schedules help:

  • Step decay: halve ฮท\eta every kk epochs.
  • Cosine annealing: ฮทt=ฮทminโก+12(ฮทmaxโกโˆ’ฮทminโก)(1+cosโก(ฯ€t/T))\eta_t = \eta_{\min} + \frac{1}{2}(\eta_{\max} - \eta_{\min})(1 + \cos(\pi t/T)).
  • Warmup: start tiny, ramp up over first few epochs, then decay. Critical for large batch training and transformers.
# PyTorch cosine annealing
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(
    optimizer, T_max=num_epochs, eta_min=1e-6
)
for epoch in range(num_epochs):
    train_one_epoch()
    scheduler.step()

5. Overfitting, underfitting, and the bias-variance trade-off

Every training run lives somewhere on this spectrum:

  • Underfitting (high bias): training loss is high. Model too simple, or training stopped too early, or learning rate too small.
  • Overfitting (high variance): training loss is low, validation loss is high. Model memorized training data instead of generalizing.
  • Good fit: both training and validation loss are low and close.

Diagnose by watching the validation loss curve. If it stops falling and starts rising while training loss keeps falling โ€” you're overfitting.

Four levers to fight overfitting:

  1. More data (most effective).
  2. Simpler model (fewer parameters).
  3. Regularization (keep the model but constrain it).
  4. Early stopping (stop before the gap grows).

The bias-variance decomposition: expected test error = (bias)2^2 + variance + irreducible noise. Regularization trades a small increase in bias for a large drop in variance.

6. L2 regularization and dropout

L2 regularization (weight decay) adds a penalty to the loss:

Lreg=L+ฮป2โˆฅฮธโˆฅ22\mathcal{L}_{\text{reg}} = \mathcal{L} + \frac{\lambda}{2} \|\theta\|_2^2

The gradient update becomes ฮธโ†ฮธ(1โˆ’ฮทฮป)โˆ’ฮทโˆ‡L\theta \leftarrow \theta(1 - \eta\lambda) - \eta \nabla \mathcal{L}. Weights shrink toward zero each step. In Adam, weight decay is applied separately from the adaptive scaling (AdamW) โ€” this distinction matters in practice and AdamW is the preferred implementation.

Dropout randomly zeroes each neuron's output with probability pp during training:

import torch.nn as nn
# During training, 50% of activations zeroed; outputs scaled by 1/(1-p)
self.dropout = nn.Dropout(p=0.5)
x = self.dropout(self.relu(self.linear(x)))

At inference, dropout is disabled and all neurons contribute. Effect: the network can't rely on any single neuron โ€” it must learn distributed, redundant representations. This reduces co-adaptation and acts like an ensemble of 2n2^n thinned networks.

7. Batch normalization

Batch normalization (BatchNorm) normalizes the pre-activations within each mini-batch, then applies a learned scale ฮณ\gamma and shift ฮฒ\beta:

z^i=ziโˆ’ฮผBฯƒB2+ฯต,yi=ฮณz^i+ฮฒ\hat{z}_i = \frac{z_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}}, \qquad y_i = \gamma \hat{z}_i + \beta

where ฮผB\mu_B and ฯƒB2\sigma_B^2 are the batch mean and variance. Benefits:

  • Allows higher learning rates without divergence.
  • Reduces sensitivity to weight initialization.
  • Acts as a mild regularizer (the batch statistics add noise).

At inference, ฮผB\mu_B and ฯƒB2\sigma_B^2 are replaced by running statistics accumulated during training. Placement: typically after the linear layer and before the activation (Linear โ†’ BN โ†’ ReLU). BatchNorm has become almost universal in CNNs; transformers use Layer Norm instead (normalizes over the feature dimension, not the batch โ€” independent of batch size).

8. Early stopping and putting it all together

Early stopping: monitor validation loss after each epoch. Stop training when validation loss stops improving for kk consecutive epochs (patience kk), and restore the best checkpoint.

best_val_loss = float('inf')
patience, epochs_no_improve = 10, 0
for epoch in range(max_epochs):
    train_loss = train_one_epoch()
    val_loss = evaluate(val_loader)
    if val_loss < best_val_loss:
        best_val_loss = val_loss
        torch.save(model.state_dict(), 'best.pt')
        epochs_no_improve = 0
    else:
        epochs_no_improve += 1
        if epochs_no_improve == patience:
            break
model.load_state_dict(torch.load('best.pt'))

A production-grade training loop stacks all of this: AdamW optimizer, cosine LR schedule with warmup, dropout and weight decay in the model, BatchNorm for stable training, early stopping to avoid overfitting. Each component fixes a specific failure mode โ€” none is optional on real problems.

9. Common gotchas in training

Things that silently wreck training runs, ranked by how often they bite:

  • Forgot optimizer.zero_grad(): gradients accumulate across batches, giving wrong updates.
  • Wrong loss for the task: MSE on a classification head (should be cross-entropy), or cross-entropy with logits passed through sigmoid first (double-applies sigmoid โ€” use BCEWithLogitsLoss).
  • Data not normalized: raw pixel values [0, 255] cause wildly different gradient scales vs. [-1, 1]. Always normalize inputs to zero mean and unit variance.
  • Learning rate too high with Adam: Adam is sensitive โ€” start with ฮท=3ร—10โˆ’4\eta = 3 \times 10^{-4} and tune from there.
  • Using weight decay with vanilla Adam instead of AdamW: in vanilla Adam, weight decay gets absorbed into the adaptive scaling and is much weaker than intended.
  • Evaluating with dropout active: always call model.eval() before validation and model.train() before training.

Check your understanding

The lesson ends with a 5-question quiz. Take it in the player above to see your score.

  1. Why is cross-entropy preferred over MSE for classification tasks?
    • Cross-entropy is computationally cheaper than MSE.
    • MSE cannot handle multi-class outputs.
    • Cross-entropy provides sharper gradients near decision boundaries and is derived from maximum likelihood, whereas MSE combined with sigmoid causes gradient saturation.
    • MSE requires the output layer to use softmax, which is numerically unstable.
  2. What is the key difference between AdamW and vanilla Adam?
    • AdamW uses a different momentum coefficient.
    • AdamW applies weight decay directly to the parameters rather than adding it to the gradient, keeping regularization decoupled from adaptive scaling.
    • AdamW uses second-order gradient information while Adam uses only first-order.
    • AdamW removes bias correction from the moment estimates.
  3. During training, dropout zeroes activations with probability $p$. What happens at inference time?
    • Dropout randomly zeroes activations with probability $p/2$ to maintain consistency.
    • Dropout is disabled and all neurons contribute; no scaling is applied.
    • Dropout is disabled and all neurons contribute; the network implicitly averages over the ensemble of thinned networks.
    • The model is re-trained without dropout for a few epochs.
  4. A training run shows training loss at 0.05 and validation loss at 0.98 after 50 epochs. What is the most likely diagnosis?
    • Underfitting: the model is too simple for the data.
    • A bug in the loss function causing incorrect gradient computation.
    • Overfitting: the model has memorized training data and fails to generalize.
    • The learning rate is too small, preventing convergence.
  5. Batch normalization uses batch statistics ($\mu_B$, $\sigma_B^2$) during training. What does it use at inference time, and why?
    • It recomputes batch statistics on each inference mini-batch for accuracy.
    • It sets both mean and variance to zero and one respectively.
    • It uses running statistics (exponential moving averages) accumulated during training, because single inference samples may lack reliable statistics.
    • It disables normalization entirely and passes raw activations through.

Related lessons