ML Models From Scratch ยท Hard
Two-Layer Neural Network Trainer
Implement forward propagation, manual backpropagation, and prediction for a small MLP.
Exercise
Task
Implement class TwoLayerNetwork(initial_parameters: dict[str, np.ndarray | float], learning_rate: float). Implement a two-layer binary classifier with ReLU, sigmoid probabilities, manual backpropagation through both affine layers, and full-batch gradient descent.
Requirements
- Copy W1, b1, W2, and b2 from initial_parameters so caller-owned values are not mutated.
- forward(x) computes affine -> ReLU -> affine -> sigmoid, caches the intermediates required by backward, and returns probabilities.
- loss(predictions, targets) returns mean binary cross-entropy with probabilities clipped to [1e-12, 1 - 1e-12].
- backward(x, targets) stores dW1, db1, dW2, and db2 using the latest forward cache.
- Use a zero ReLU derivative for hidden pre-activations less than or equal to zero.
- step() updates every parameter from its matching gradient and learning_rate.
- fit(x, targets, epochs) records the loss before each update in loss_history.
- predict(x) returns 1 where the forward probability is at least 0.5, otherwise 0.
- Do not call an autograd backward API in the core implementation.
Example
model = TwoLayerNetwork(
{
"W1": np.eye(2),
"b1": np.zeros(2),
"W2": np.array([0.5, -0.5]),
"b2": 0.0,
},
learning_rate=0.2,
)
model.fit(
np.array([[1.0, 0.0], [0.0, 1.0]]),
np.array([1.0, 0.0]),
epochs=2,
)
model.predict(np.array([[1.0, 0.0], [0.0, 1.0]]))
# array([1, 0])