Skip to content

← Classifiers from Scratch step 4 of 5

Medium End-to-End

Train Binary Classifier End-to-End

Implement train_binary_classifier to train a linear model for two classes. Use the supplied initial weights and take n_epochs full-batch gradient steps. Return the final weights, not the predicted probabilities or class labels.

Inputs and output

  • x: (N, d), with one example per row and one feature per column.
  • y: (N,), labels equal to 0.0 or 1.0.
  • w0: (d,), the initial weights.
  • lr: a finite, nonnegative learning rate.
  • n_epochs: a nonnegative integer, the number of updates to perform.

N and d are positive. Tensor values are finite, and x, y and w0 share a floating-point dtype and device. Return a vector of shape (d,), preserving dtype and device. Leave all inputs unchanged.

There is no separate bias parameter. If x includes a column of ones, its weight acts as a bias. Do not add a bias or initialize new random weights.

Model and loss

For each example, the model computes a score z and a probability p of class 1:

z = x @ w
p = sigmoid(z) = 1 / (1 + exp(-z))

Use mean binary cross-entropy:

loss = -sum(y[i]*log(p[i]) + (1-y[i])*log(1-p[i]) for i in range(N)) / N

Its weight gradient simplifies to:

grad = x.T @ (p - y) / N

Each example contributes its features multiplied by its prediction error p[i]-y[i]. Average these contributions over the N examples, not the d features. This formula already includes the derivative of sigmoid; do not multiply by p*(1-p) again.

You only need the gradient to update the weights. You do not need to evaluate the logarithmic loss expression, which can encounter log(0) when probabilities round to zero or one. A framework sigmoid helper is allowed.

Training loop

Start from w0. At each step, compute probabilities using the current weights, compute the gradient above, then set w = w - lr * grad. Use all examples for every step. Carry updated weights into the next step, without shuffling, mini-batches, regularization or early stopping.

Perform exactly n_epochs updates. A fixed step count does not guarantee convergence or perfect classification. If lr=0, n_epochs=0, or every feature is zero, the returned weights have the same values as w0.

Worked example

For x=[[1.0]], y=[1.0], w0=[0.0], lr=0.1 and n_epochs=1:

z = 0
p = 0.5
grad = 1 * (0.5 - 1) = -0.5
w = 0 - 0.1 * (-0.5) = 0.05

Return [0.05]. On a second step, recompute the probability using 0.05 rather than reusing the initial probability.