Recommended resources
The freely available resources this lesson will direct you to.
Introduction
In our last lesson, we equipped ourselves with the fundamental building blocks of modern neural networks: differentiable activation functions like Sigmoid, Tanh, and ReLU. We established that these non-linear functions are the crucial ingredient that allows a model to learn patterns beyond the simple linear boundaries of the perceptron. We now have two primary components at our disposal:
- Affine Transformation: A linear operation on an input defined by , where is a matrix of weights and is a vector of biases. Geometrically, this corresponds to a rotation, scaling, and shear followed by a translation.
- Non-linear Activation: An element-wise function that "warps" or "squashes" the transformed space, introducing the complexity needed to model real-world data.
This lesson is about putting these two pieces together. We will construct a complete, multi-layer feedforward neural network by treating it as a composition of functions. We will explore how organizing neurons into layers allows for highly efficient, vectorized computation, and we will develop a geometric intuition for what the network is actually learning. This step moves us from isolated components to a complete, expressive model, setting the stage for understanding how information flows through it.
From Pixels to Concepts: A High-Level View
Before diving into the mathematical formalism, it's helpful to build an intuitive picture of what we're aiming for. A neural network is designed to learn hierarchical features from data. For a task like recognizing handwritten digits, the first layer might learn to detect simple edges from raw pixels. The next layer might combine these edges to form loops and lines. A final layer could then combine these more abstract components to recognize a "9" (a loop on top of a line) or an "8" (two loops).
The following video from 3Blue1Brown provides an excellent visualization of this concept.
But what is a neural network? Chapter 1, Deep learning
This video, "But what is a neural network?", offers a brilliant and intuitive explanation of a network's structure and purpose.
Watch the first two main segments: The initial explanation of layers and neurons as "things that hold a number." The discussion on how activations propagate and how hidden layers might learn to detect hierarchical features like edges and loops.
The Anatomy of a Layer
As the video illustrates, a neural network is composed of layers of neurons. Let's formalize this. A single neuron, as depicted below, takes multiple inputs, computes a weighted sum, adds a bias, and then applies a non-linear activation function.
While we could model a network as a collection of individual neurons, this is computationally inefficient. Your background in performance-oriented programming will appreciate that we can achieve massive speedups by processing all neurons in a layer simultaneously using vectorized operations.
A fully-connected layer (or dense layer) is a set of neurons where every neuron receives the same input vector. If we have an input vector and a layer with neurons, we can represent the weights for the entire layer as a matrix and the biases as a vector .
The computation for the entire layer then becomes:
- Affine Transformation:
- Non-linear Activation:
Here, is the vector of "pre-activation" values, and is the vector of "activations" or outputs from the layer. The activation function is applied element-wise to the vector . This matrix-vector multiplication is far more efficient than iterating through separate dot products, especially on hardware like GPUs that are optimized for linear algebra.
The article below provides a clear definition of these core components.
Continuous Classification using Deep Neural Networks - Nick Strayer
This section from Nick Strayer's blog provides clear definitions for the terminology we use.
Focus on the definitions under the "Terminology" section. You'll see precise descriptions for each of the terms we've just discussed: Neuron, Affine Transformation, Bias Term, Activation Function, Layer, and Hidden Layer.
Stacking Layers: Function Composition
A "deep" neural network is created by stacking these layers, where the output of one layer, , becomes the input to the next layer, . This is a direct application of function composition.
Consider a simple two-layer network (one hidden layer, one output layer). Let's trace the flow of data:
- The input to the network is .
- The first hidden layer, with weights and bias , computes its output:
- This output, , becomes the input to the second (output) layer, which has its own weights and bias :
By substituting the first equation into the second, we can see the entire network as a single, complex composite function:
This brings us to a critical "first principles" question. In the previous lesson, we established the need for non-linear activation functions. What would happen if we decided to use a simple linear activation, , in our hidden layers? What would the two-layer network above simplify to?
Hint
Substitute $g^{[1]}(\mathbf{z}) = \mathbf{z}$ into the composite function and expand the expression. What form does the final equation take?The answer reveals a fundamental truth about neural networks. The following reading walks through the exact algebra.
SorawitChok/Neural-Network-from-scratch-in-Cpp - GitHub
This document provides a concise mathematical demonstration of why non-linearity is essential.
Read the section on the "Fully-connected layer". Follow the derivation that shows how a network with only affine transformations collapses into a single affine transformation.
As you've seen, a stack of linear layers is mathematically equivalent to a single linear layer. The composition of two affine transformations is just another affine transformation. Without non-linearity, a "deep" linear network has no more expressive power than a shallow one. The non-linear activation function is what allows each layer to add a new level of complexity to the representation.
A Geometric View: Warping Space
For someone with an interest in computer graphics, there is a powerful geometric interpretation of what a neural network does. Each layer applies a transformation to the space its input data lives in.
- The affine transformation () performs a linear transformation (rotation, scaling, shearing) and a translation of the space.
- The non-linear activation () then "warps" and "folds" this transformed space.
A deep neural network learns a sequence of these transformations to morph the initial data distribution into one that is more easily handled by the final layer. For a classification problem, the network tries to warp the space until the different classes are linearly separable.

This space-warping behavior is beautifully demonstrated in the interactive visualization from Andrej Karpathy's lecture.
CS231n Winter 2016: Lecture 4: Backpropagation, Neural Networks 1
The demo at the end of this classic lecture from CS231n provides a dynamic visualization of a neural network learning to classify data by warping the input space.
Watch the segment from the demo. Observe how the network, through training, alters the grid to separate the red and green data points. This is a visual confirmation of the geometric transformations we've been discussing.
The Computation Graph
As our networks grow more complex, representing them with a single nested mathematical equation becomes unwieldy. A more structured and computationally-minded approach is to represent the network as a computation graph. This is a directed acyclic graph (DAG) where nodes represent either variables (inputs, parameters) or operations (matrix multiplication, addition, activation functions).
This perspective is essential for two reasons:
- Modularity: It allows us to think of the network as a set of connected, reusable modules (layers). Deep learning frameworks are built around this idea.
- Gradient Flow: It provides the structure needed to systematically compute gradients for all parameters using the chain rule. This process, called backpropagation, involves passing gradients backward through the graph.
CS231n Winter 2016: Lecture 4: Backpropagation, Neural Networks 1
In the same lecture, Andrej Karpathy motivates the need for computation graphs.
Watch the introductory segment from the start. He explains why thinking in terms of graphs is more scalable than writing out enormous symbolic expressions, especially for the complex architectures used in modern deep learning.
We will explore backpropagation in great detail in a future lesson, but it is crucial to understand now that the computation graph is the data structure that makes it possible.
Conclusion
In this lesson, we have assembled our building blocks into a complete feedforward neural network. We have formally defined the network as a composition of functions, each corresponding to a layer that performs an affine transformation followed by a non-linear activation.
Key Takeaways:
- A feedforward neural network is a composite function built by stacking layers.
- Each layer's computation, , can be efficiently implemented using vectorized operations.
- Non-linearity is essential. Without it, a deep network collapses into a single, shallow linear model, losing its expressive power.
- Geometrically, a network learns to warp the input space through a series of transformations, aiming to make the data more easily separable.
- The computation graph is a powerful formalism for representing networks that is crucial for both conceptual clarity and the practical implementation of training algorithms.
Preview of the Next Lesson:
We now understand the structure of a neural network. The next logical step is to understand its operation. In the next lesson, we will perform a forward pass: taking a concrete input vector and propagating it through the layers of the network to produce a final prediction. This is the first of the two key processes in a neural network's life cycle, the second being the backward pass for learning.