Modularizing Training Components: Losses and Optimizers
Introduction
Welcome back to lesson 2 of "Building and Applying Your Neural Network Library"! You've made excellent progress in this course. In our previous lesson, we successfully transformed our neural network code into a well-structured Python package by modularizing our core components — dense layers and activation functions. We created clean import paths and established the foundation for a professional-grade neural network library.
Now we're ready to take the next crucial step: modularizing our training components. As you may recall from our previous courses, training a neural network involves two key components beyond the layers themselves: loss functions (which measure how well our network is performing) and optimizers (which update the network's weights based on the gradients we compute). Currently, these components are scattered throughout our training scripts, making them difficult to reuse and maintain.
In this lesson, we'll organize these training components into dedicated modules within our neuralnets package. We'll create a losses submodule to house our Mean Squared Error (MSE) loss function and an optimizers submodule for our Stochastic Gradient Descent (SGD) optimizer. By the end of this lesson, you'll have a complete, modular training pipeline that demonstrates the power of good software architecture in machine learning projects.
Our Test Dataset: The XOR Problem
Before we dive into modularizing our training components, let's take a moment to understand the dataset we'll be using to test our library: the XOR (exclusive OR) problem. This is a classic toy problem in machine learning that serves as an excellent test case for neural networks because it's non-linearly separable — meaning a single linear classifier cannot solve it, but a simple multi-layer neural network can.
The XOR problem consists of four data points with two binary inputs and one binary output. The output is 1 when exactly one of the inputs is 1, and 0 otherwise. This creates the pattern: [0,0] → 0, [0,1] → 1, [1,0] → 1, [1,1] → 0. This is tipically treated as a classification problem, but we can frame it as a regression task as well, which is what we'll do by using our mse loss. Despite its simplicity, if our network can learn XOR then we know our forward pass, backward pass, loss calculation, and optimization code are all functioning properly.

While we're using XOR for rapid development and testing in this lesson, later in the course we'll apply our complete neural network library to a real-world dataset — the California Housing dataset — where we'll predict house prices based on various features like location, population, and median income.
