Hello! Welcome back to our hands-on exploration of deep learning.
Introduction
In our last lesson, we constructed our first multi-layer neural network in PyTorch. We saw how to define a NeuralNet class by stacking nn.Linear layers. You may have noticed that we also added an nn.ReLU() layer between them, with a promise to explain it later. Today is that day.
This lesson addresses a fundamental question: Why are non-linear activation functions like ReLU essential for a neural network? You will learn why a network made of only linear layers has major limitations and how the simple yet powerful ReLU function enables your network to learn the complex patterns required for tasks like image classification.
This directly addresses our learning goal: to explain the role of non-linear activation functions (e.g., ReLU) in enabling a network to learn complex patterns.
The Problem: Why Linearity Isn't Enough
A neural network's job is to learn the relationship between inputs (like an image) and outputs (like a class label). Often, this relationship is highly complex and non-linear. For example, the pixels that make up the digit '2' don't follow a simple straight-line pattern.
You might think that by stacking many nn.Linear layers, you can create a more powerful model. However, a sequence of linear operations can always be simplified into a single, equivalent linear operation.
Let's see why this is the case.
Why Do We Need Activation Functions in Neural Networks?
The video 'Why Do We Need Activation Functions in Neural Networks?' from the NeuralNine channel provides an excellent mathematical and visual demonstration of this limitation.
Watch the segment from 05:14 to 08:56. The presenter shows how a multi-layer network with only linear operations mathematically collapses into a single linear equation, making it no more powerful than a single neuron.
As the video demonstrates, no matter how many layers you add, a network without non-linearities can only learn linear relationships. It's like trying to draw a curve using only a straight ruler.
The Solution: Introducing Non-Linearity with ReLU
To overcome this limitation, we introduce a non-linear activation function after each linear layer. This function takes the output of the linear layer and transforms it non-linearly.
There are many activation functions (Sigmoid, Tanh), but the most popular and effective choice in modern deep learning is the Rectified Linear Unit (ReLU).
The function is surprisingly simple: it returns the input if it's positive, and zero otherwise.
Despite its simplicity, the "kink" at zero is a non-linear transformation. This single change is what gives the network its power.
Understanding ReLU: The Activation Function Driving Deep Learning Success
Let's read a brief introduction to ReLU from the article 'Understanding ReLU' on Medium. This will solidify its definition and significance.
Read the sections 'Introduction to ReLU and Its Significance in Deep Learning' and the first point under it, '1. Non-Linearity'. This will give you the formal definition and a clear explanation of why its non-linearity is crucial.
How ReLU Builds Complex Patterns
So, how does this simple max(0, x) operation allow a network to model something as complex as the boundary between a '7' and a '9'?
Think of each ReLU unit as a switch. It can either be "off" (outputting zero) or "on" (outputting a linear value). By combining thousands of these simple switches across multiple layers, the network can create incredibly complex, high-dimensional, piecewise-linear functions.
Each ReLU contributes a "hinge" or a "bend." The network learns to position these hinges in just the right places to approximate the complex decision boundary needed to separate different classes.
The following video from StatQuest provides a fantastic, animated intuition for this process.
Neural Networks Pt. 3: ReLU In Action!!!
In 'ReLU In Action!!!', Josh Starmer visualizes how a network uses ReLU to transform data. You'll see how simple 'bent lines' are combined to create more complex shapes.
Watch from 02:27 to 07:42. Focus on how the ReLU function creates a 'bent blue line' (a piecewise linear function). Then, see how adding multiple such transformations together results in a 'green pointy thing'—a more complex shape that would be impossible with linear functions alone.
This ability to approximate any continuous function by combining many simple pieces is a cornerstone of deep learning, known as the Universal Approximation Theorem. While the theory is deep, the intuition from the video is what's most important for a practitioner: ReLUs give your network the flexibility to bend and shape its internal representation of the data to fit the problem.
The Payoff: Seeing it in PyTorch
Let's tie this back to the practical PyTorch example from the NeuralNine video. Having established that a linear network fails and that ReLU introduces non-linearity, we can now appreciate the final result.
Why Do We Need Activation Functions in Neural Networks?
Let's revisit the NeuralNine video to see the dramatic difference in performance between a network with and without ReLU on a non-linear task.
Watch the final segment from 12:04 to 13:56. This is the payoff. Observe how the network without activation can only produce a straight line, while the network with ReLU activation perfectly models the complex, cubic function.
This is precisely why we placed nn.ReLU() between the nn.Linear layers in our model from the last lesson. It unlocks the network's potential to move beyond simple lines and learn the rich patterns in your data.
In PyTorch, you can use it as a layer (nn.ReLU()) or as a function (F.relu()), as shown below. The former is common when defining architectures in __init__.
import torch
import torch.nn as nn
import torch.nn.functional as F
# Using nn.ReLU as a layer (common in __init__)
relu_layer = nn.ReLU()
input_tensor = torch.tensor([-2.0, -0.5, 0.0, 1.0, 3.0])
output = relu_layer(input_tensor)
# output is now: tensor([0., 0., 0., 1., 3.])
# Using F.relu as a function (common in forward method)
output_functional = F.relu(input_tensor)
# output_functional is also: tensor([0., 0., 0., 1., 3.])
Conclusion
In this lesson, we uncovered the critical role of non-linear activation functions. You learned that without them, even a deep neural network is fundamentally limited to learning simple linear patterns.
Key Takeaways:
- Stacking linear layers is not enough; the result is still just a linear function.
- Non-linear activation functions like ReLU are required to enable a network to learn complex, non-linear relationships in data.
- ReLU's simple rule, , introduces a "kink" that, when combined across many neurons and layers, allows the network to approximate any continuous function.
- Practically, this means placing an activation function (like
nn.ReLU()) after eachnn.Linearlayer (except, typically, the final output layer).
Preview of the Next Lesson
We've now built the main body of our network and understand why each component is there. However, the raw numbers coming out of the final linear layer are not probabilities. In our next lesson, we will explore the softmax function, which takes these raw outputs (logits) and elegantly converts them into class probabilities, the final piece needed for multiclass classification.