InterviewPrepKit

Home / Coding / Machine Learning Coding / Neural Net Internals / Batch Normalization Forward Pass

Batch Normalization Forward Pass

hard 00:00
Solving tips
  • Reduce over axis=0 (the batch axis) so mean and variance are per-feature, shape (d,); reducing over the wrong axis is the classic mistake.
  • The eps inside the square root is not optional decoration: it keeps sqrt(var + eps) from dividing by zero when a feature is constant across the batch.
  • Use the biased variance (divide by n, matching np.var's default ddof=0); this is what training-time batch norm uses, not the n-1 sample variance.

Implement the training-time forward pass of batch normalization, the layer that stabilizes deep-network training by keeping each feature’s activations centered and scaled. Given a batch X of shape (n, d), you normalize every feature using statistics computed across the n samples in the batch, then apply a learnable scale gamma and shift beta. Interviewers use this to check that you know which axis the statistics come from, why the eps term exists, and how the affine gamma/beta step restores representational power after normalization.

Definition

For each feature column j, compute the mean and (biased) variance across the batch, standardize, then scale and shift:

mu[j]    = (1/n) * sum_i X[i, j]
var[j]   = (1/n) * sum_i (X[i, j] - mu[j])^2
xhat[i, j] = (X[i, j] - mu[j]) / sqrt(var[j] + eps)
out[i, j]  = gamma[j] * xhat[i, j] + beta[j]

The statistics mu and var are per-feature, so both have shape (d,). At training time these come from the current batch (this is what you implement here). At inference time a real layer instead uses a running mean and variance accumulated during training, so predictions do not depend on how the eval batch happens to be grouped.

Task

Complete batchnorm_forward(X, gamma, beta, eps=1e-5) so it returns the (n, d) output. Take the mean and variance over axis=0 (across samples) to get per-feature statistics of shape (d,), normalize with (X - mu) / sqrt(var + eps), then apply gamma * xhat + beta, letting NumPy broadcast the (d,) parameters across all n rows. Use the biased variance (divide by n, i.e. np.var’s default ddof=0). Do not call any deep-learning framework; use plain NumPy only.

Example

X = np.array([[1.0, 2.0],
              [3.0, 6.0]])
gamma = np.array([1.0, 2.0])
beta = np.array([0.0, 1.0])
batchnorm_forward(X, gamma, beta, eps=0.0)
# -> array([[-1.,  -1.],
#           [ 1.,   3.]])

Feature 0 has mean 2 and std 1, so its column normalizes to [-1, 1]; feature 1 has mean 4 and std 2, so it normalizes to [-1, 1], then gamma=2, beta=1 maps it to [-1, 3].

Constraints

  • 1 <= n <= 10^4, 1 <= d <= 10^3; use vectorized NumPy with reductions over axis=0, no Python loop over samples or features.
  • gamma.shape == beta.shape == (d,) and X.shape[1] == d.
  • eps is a small positive float (default 1e-5); it must be added inside the square root so a constant feature (var == 0) does not divide by zero.
  • Use the biased variance (ddof=0), matching training-time batch norm; values fit in float64.

Write your solution, then hit Run tests to check it — or get a mock grade from the AI coach.

The coach remembers this session — revise your code and ask again, and it grades your progress. It gives hints, not the answer.
Report a bug