Skip to content

← Model Architectures step 3 of 9

Easy End-to-End

Multi-Class Classifier

Evaluate a classifier that assigns each example to one of C classes. The supplied weights and bias produce one score, or logit, per class. Softmax converts each row of scores into probabilities that sum to one. This is a forward pass and loss calculation; do not update the parameters.

Your task

Implement multi_class_classifier(x, W, b, y):

  • x has shape (N, features), with N >= 1.
  • W has shape (features, C) and b has shape (C,), with C >= 1.
  • y has shape (N,) and contains class indices from 0 through C - 1.

Compute z = x @ W + b. Apply softmax across classes within each row, not across examples. Return a dictionary with "probabilities" of shape (N, C) and "loss" as a Python float. Preserve the inputs.

The loss is the mean negative log probability of the correct class. Use each example's own label to select its class, casting labels to integer indices as needed. Do not average across all classes or return argmax labels.

Stable computation

Subtract each row's largest logit before exponentiating. This leaves the probabilities unchanged while avoiding overflow:

shifted = z - row_max(z)
normalizer = row_sum(exp(shifted))
probabilities = exp(shifted) / normalizer
log_probabilities = shifted - log(normalizer)
loss = -mean(log_probabilities[i, y[i]])

Keep the row maximum and normalizer shaped (N, 1) for broadcasting. Compute log probabilities from shifted logits as shown. Taking log of an already rounded probability can give negative infinity when that probability underflows to zero. No epsilon or clipping is needed here.

Example

With x = [[0]], W = [[0, 0]], b = [0, 0] and y = [1], both logits are zero. Return probabilities [[0.5, 0.5]] and loss approximately 0.693147.

For logits [1000, -1000] and target class 1, floating-point probabilities can round to [1, 0], but the loss is still finite, approximately 2000. The stable log-probability calculation preserves that information.