Welcome again!
our journey of understanding backpropagation intimately.
Let’s briefly recall what we lined in Half 1 to date.
A Fast Recap
We first began making an attempt to grasp neural networks utilizing a easy dataset.
In that course of, we first constructed a small neural community and understood the way it makes predictions via the method of ahead propagation.

We then noticed that the expected values had been nowhere near the precise values, leading to a big error.
Now, we needed to coach this neural community to carry out higher.
By evaluating it with easy linear regression, we noticed that, in our neural community, the loss is determined by seven parameters.
[w_1,w_2,w_3,w_4,b_1,b_2,b_3]
Our full loss perform appeared like this:
[
L(w_1,w_2,w_3,w_4,b_1,b_2,b_3)=frac{1}{n}sum_{i=1}^{n}left(y_i-left(w_3mathrm{ReLU}(w_1x_i+b_1)+w_4mathrm{ReLU}(w_2x_i+b_2)+b_3right)right)^2
]
Subsequent, simply as we did in easy linear regression, we needed to distinguish the loss with respect to every parameter.
We began with and used the classical differentiation technique. Finally, we arrived on the following consequence:
[
frac{partial L}{partial w_1}
=
-frac{2}{n}
sum_{i=1}^{n}
(y_i-hat{y}_i)
w_3
mathrm{ReLU}'(w_1x_i+b_1)
x_i
]
Do We Actually Need to Repeat This?
Now it’s time to suppose.
We differentiated the loss with respect to , which suggests we had been looking for how the loss modifications as modifications.
We used the classical differentiation technique right here.
We now have six extra parameters to distinguish the loss with respect to.
What do you suppose?
Do we have to proceed with the identical technique?
No.
The Chain Rule to the Rescue
In case you keep in mind, we mentioned the chain rule in Half 1.
We used a easy instance.
We thought of
[
y=x^2
]
and
[
z=y^3
]
We observed that (z) doesn’t rely straight on (x).
As an alternative, the connection appears like
[
x rightarrow y rightarrow z.
]
Which means that when (x) modifications, it first modifications (y), and the change in (y) then impacts (z).
For the reason that impact of (x) reaches (z) via an intermediate variable, we can not differentiate (z) with respect to (x) straight. As an alternative, we used the chain rule.
[
frac{dz}{dx}
=
frac{dz}{dy}
cdot
frac{dy}{dx}
]
The chain rule tells us that as an alternative of taking one giant step from (x) to (z), we will break the issue into smaller steps by following the dependency path.
Following the Dependency Path
Now the query is can we apply this identical thought to our neural community.
The reply is sure.
To do this, we first want to grasp how a change in , travels via the neural community earlier than it lastly impacts the loss.
Let’s write down the equations of our neural community.
[
z_1=w_1x+b_1
]
(z_1) is determined by the load (w_1), the enter (x), and the bias (b_1).
Subsequent, we utilized the ReLU activation perform.
[
a_1=mathrm{ReLU}(z_1)
]
Right here, the activation (a_1) relies upon solely on (z_1).
The prediction of our community is
[
hat{y}=w_3a_1+w_4a_2+b_3.
]
we will see that, the prediction is determined by the activation (a_1).
Lastly, we computed the loss.
[
L=(y-hat{y})^2.
]
The loss is determined by the prediction.
If we join all these relationships collectively, we get
[
w_1
rightarrow
z_1
rightarrow
a_1
rightarrow
hat{y}
rightarrow
L.
]
Evaluating this with the straightforward instance we thought of.
Easy instance:
[
x
rightarrow
y
rightarrow
z.
]
Neural community:
[
w_1
rightarrow
z_1
rightarrow
a_1
rightarrow
hat{y}
rightarrow
L
]
As we already stated partially 1, the one distinction is that the neural community has an extended dependency chain, however the underlying thought stays the identical.
Partial Derivatives vs. the Chain Rule
At this level, we might get confused between partial derivatives and the chain rule.
Let’s make clear each concepts earlier than shifting ahead.
Within the easy instance,
[
y=x^2
]
(y) is just trusted enter variable, (x). So, to search out change in (y) w.r.t (x), atypical derivatives are adequate, and we write
[
frac{dy}{dx}
]
However, think about the equation
[
z_1=w_1x+b_1
]
Right here (z_1) is determined by three variables: (w_1), (x), and (b_1).
Now, we need to understand how (z_1) modifications when solely (w_1) modifications.
For this, we quickly preserve (x) and (b_1) fastened.
Due to this fact, we write
[
frac{partial z_1}{partial w_1}
]
The image (partial) tells us that we’re altering just one variable whereas preserving the remaining variables as constants throughout that specific calculation.
That is what we learn about partial derivatives.
Now, coming to the chain rule, it’s a completely different idea.
Let’s watch out to not confuse these two completely different ideas.
A partial by-product solutions the query:
Which variable are we altering?
For instance,
[
frac{partial z_1}{partial w_1}
]
which suggests solely (w_1) is allowed to alter.
The chain rule solutions a special query:
How does the impact of 1 variable journey via a number of intermediate computations?
In our neural community,
[
w_1
rightarrow
z_1
rightarrow
a_1
rightarrow
hat{y}
rightarrow
L
]
Because the impact of fixing , reaches the loss via each intermediate parameter, we multiply the derivatives alongside this path.
Due to this fact,
[
frac{partial L}{partial w_1}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_1}
cdot
frac{partial a_1}{partial z_1}
cdot
frac{partial z_1}{partial w_1}
]
We will observe that nothing new has occurred.
We’re nonetheless making use of the identical chain rule that we realized in Half 1.
The one distinction is that the chain is now longer and the features contain a number of variables, which is why we use partial derivatives as an alternative of atypical derivatives.
Making use of the Chain Rule to Our Neural Community
Step 1:
We now know that
[
frac{partial L}{partial w_1}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_1}
cdot
frac{partial a_1}{partial z_1}
cdot
frac{partial z_1}{partial w_1}
]
To compute this gradient, we first have to calculate every partial by-product one after the other.
To maintain the chain rule straightforward to observe, we’ll derive the gradient for one knowledge level.
In different phrases, for this derivation we think about the case the place
[
n=1.
]
Due to this fact, the Imply Squared Error (MSE) loss
[
L=frac{1}{n}sum_{i=1}^{n}(y_i-hat{y}_i)^2
]
simplifies to
[
L=(y-hat{y})^2.
]
As soon as we get an thought of methods to compute the gradient for a single knowledge level, extending it to the whole dataset is simple.
We merely common the gradients over all knowledge factors, simply as we did in Half 1.
The primary by-product we have to compute is
[
frac{partial L}{partial hat{y}}.
]
However earlier than differentiating, let’s first perceive what this by-product tells us.
The precise worth
[
y
]
comes from our dataset, so throughout differentiation it’s thought of as a continuing.
The one amount that may change right here is the prediction
[
hat{y}
]
Due to this fact,
[
frac{partial L}{partial hat{y}}
]
tells us:
If the prediction modifications by a small quantity, how a lot does the loss change?
Now that we all know what this by-product represents, let’s compute it.
Since
[
L=(y-hat{y})^2
]
we first apply the ability rule.
Differentiate the outer sq..
[
frac{partial L}{partial hat{y}}
=
2(y-hat{y})
cdot
frac{partial (y-hat{y})}{partial hat{y}}
]
Now differentiate the expression inside.
The by-product of
[
y
]
with respect to
[
hat{y}
]
is
[
0
]
as a result of the precise worth doesn’t change.
The by-product of
[
-hat{y}
]
with respect to
[
hat{y}
]
is
[
-1
]
Due to this fact,
[
frac{partial (y-hat{y})}{partial hat{y}}
=
-1
]
Substituting this again into the earlier equation provides
[
frac{partial L}{partial hat{y}}
=
2(y-hat{y})
(-1)
]
Lastly,
[
frac{partial L}{partial hat{y}}
=
-2(y-hat{y})
]
This tells us how the loss modifications every time the prediction modifications.
Step 2:
Now the subsequent by-product we have to compute is
[
frac{partial hat{y}}{partial a_1}
]
Let’s first see what this by-product tells us.
Recall that the output neuron computes the prediction utilizing the equation
[
hat{y}=w_3a_1+w_4a_2+b_3
]
As we’re differentiating with respect to
[
a_1
]
all the opposite portions
[
w_3,;w_4,;a_2,;text{and};b_3
]
are handled as constants.
Due to this fact,
[
frac{partial hat{y}}{partial a_1}
]
tells us
If the activation [a_1] modifications by a small quantity, how a lot does the prediction [hat{y}] change?
Now let’s calculate.
Beginning with
[
hat{y}=w_3a_1+w_4a_2+b_3
]
the by-product of
[
w_3a_1
]
with respect to
[
a_1
]
is
[
w_3
]
The by-product of
[
w_4a_2
]
is
[
0
]
as a result of it doesn’t rely on
[
a_1
]
Equally,
[
b_3
]
is a continuing, so its by-product is
[
0
]
Due to this fact,
[
frac{partial hat{y}}{partial a_1}
=
w_3
]
This tells us that for each one unit of improve in
[
a_1
]
the prediction modifications by
[
w_3
]
Step 3:
The subsequent hyperlink in our chain is
[
frac{partial a_1}{partial z_1}
]
Earlier, we computed the activation of the primary hidden neuron utilizing the ReLU activation perform.
[
a_1=mathrm{ReLU}(z_1)
]
Due to this fact,
[
frac{partial a_1}{partial z_1}
]
tells us
If the enter to the ReLU perform modifications by a small quantity, how a lot does its output change?
Since
[
a_1=mathrm{ReLU}(z_1)
]
its by-product is just the by-product of the ReLU perform.
Due to this fact,
[
frac{partial a_1}{partial z_1}
=
mathrm{ReLU}'(z_1)
]
We all know that the by-product of the ReLU perform is determined by the worth of its enter.
[
text{If } z_1 gt 0,quad mathrm{ReLU}'(z_1)=1.
]
[
text{If } z_1 lt 0,quad mathrm{ReLU}'(z_1)=0.
]
This will likely appear complicated at first, so let’s perceive it with a easy instance.
We simply stated that the by-product of the ReLU perform is determined by the worth of its enter.
If [z_1 gt 0] then [mathrm{ReLU}'(z_1)=1]
If [z_1 lt 0] then [mathrm{ReLU}'(z_1)=0]
However how?
Let’s perceive this with a easy instance.
Suppose
[
z_1=3
]
The ReLU output is
[
mathrm{ReLU}(3)=3
]
Now improve the enter barely from 3 to 4.
The brand new output turns into
[
mathrm{ReLU}(4)=4
]
Observe what occurred right here.
The enter elevated by
[
4-3=1
]
and the output additionally elevated by
[
4-3=1
]
Due to this fact, the by-product is
[
frac{d(mathrm{ReLU})}{dz}
=
frac{1}{1}
=
1
]
Now let’s say the enter is
[
z_1=10
]
Then
[
mathrm{ReLU}(10)=10
]
If we improve the enter to
[
11
]
the output turns into
[
mathrm{ReLU}(11)=11
]
Once more, the enter will increase by 1 and the output additionally will increase by 1.
Due to this fact, the by-product is
[
frac{d(mathrm{ReLU})}{dz}
=
frac{1}{1}
=
1
]
So the by-product remains to be
[
1
]
We will see that the by-product just isn’t equal to the worth of the enter.
Regardless that the enter modified from 3 to 10, the slope of the ReLU perform remained the identical.
Now think about a damaging enter.
Suppose
[
z_1=-3
]
Then
[
mathrm{ReLU}(-3)=0
]
Now, if we improve the enter barely to
[
-2
]
the output remains to be
[
mathrm{ReLU}(-2)=0
]
The enter modified, however the output didn’t.
Due to this fact,
[
frac{d(mathrm{ReLU})}{dz}
=
0
]
For this reason the by-product of the ReLU perform is
[
mathrm{ReLU}'(z_1)=1
]
for optimistic inputs, and
[
mathrm{ReLU}'(z_1)=0
]
for damaging inputs.
In different phrases, we will say that the gradient passes via with out altering every time the enter is optimistic and turns into zero every time the enter is damaging.
Step 4:
We now have now calculated all of the derivatives besides one.
The final by-product we have to calculate is
[
frac{partial z_1}{partial w_1}
]
Recall that
[
z_1=w_1x+b_1
]
Since [x] and [b_1] are constants with respect to [w_1] solely the time period [w_1x] modifications when differentiating with respect to [w_1]
Due to this fact,
[
frac{partial z_1}{partial w_1}
=
x
]
Placing It All Collectively
We now have now computed all of the partial derivatives required by the chain rule.
They’re:
[
frac{partial L}{partial hat{y}}
=
-2(y-hat{y})
]
[
frac{partial hat{y}}{partial a_1}
=
w_3
]
[
frac{partial a_1}{partial z_1}
=
mathrm{ReLU}'(z_1)
]
[
frac{partial z_1}{partial w_1}
=
x
]
We now have already seen that the chain rule tells us
[
frac{partial L}{partial w_1}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_1}
cdot
frac{partial a_1}{partial z_1}
cdot
frac{partial z_1}{partial w_1}
]
Now substitute every partial by-product into this expression.
We get
[
frac{partial L}{partial w_1}
=
-2(y-hat{y})
cdot
w_3
cdot
mathrm{ReLU}'(z_1)
cdot
x
]
Since
[
z_1=w_1x+b_1
]
we will additionally write it as
[
frac{partial L}{partial w_1}
=
-2(y-hat{y})
cdot
w_3
cdot
mathrm{ReLU}'(w_1x+b_1)
cdot
x
]
That is the gradient of the loss with respect to the load
[
w_1
]
It tells us how a lot the loss modifications once we make a really small change in
[
w_1
]
As we all know, throughout gradient descent, that is used to replace the load within the route that reduces the loss.
An Fascinating Remark
Discover one thing attention-grabbing.
We’ve arrived at precisely the identical gradient we derived in Half 1 however this time we reached it utilizing the chain rule as an alternative of classical differentiation.
We simply found a way more systematic strategy to compute gradients.
Though this derivation appears longer, observe what occurred.
Each step was easy. We by no means needed to differentiate the whole neural community directly, however we solely differentiated one small half at a time.
The Actual Problem
Now what’s subsequent?
We now have efficiently calculated the gradient for one parameter, however there are nonetheless six extra parameters left.
Ought to we repeat the identical course of for every parameter?
Let’s see what occurs once we attempt to repeat the method.
First, let’s take a look on the chain rule equations for all of the parameters.
[
frac{partial L}{partial w_1}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_1}
cdot
frac{partial a_1}{partial z_1}
cdot
frac{partial z_1}{partial w_1}
]
[
frac{partial L}{partial b_1}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_1}
cdot
frac{partial a_1}{partial z_1}
cdot
frac{partial z_1}{partial b_1}
]
[
frac{partial L}{partial w_2}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_2}
cdot
frac{partial a_2}{partial z_2}
cdot
frac{partial z_2}{partial w_2}
]
[
frac{partial L}{partial b_2}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial a_2}
cdot
frac{partial a_2}{partial z_2}
cdot
frac{partial z_2}{partial b_2}
]
[
frac{partial L}{partial w_3}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial w_3}
]
[
frac{partial L}{partial w_4}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial w_4}
]
[
frac{partial L}{partial b_3}
=
frac{partial L}{partial hat{y}}
cdot
frac{partial hat{y}}{partial b_3}
]
Now, by trying on the equations, we will observe that lots of the partial derivatives seem repeatedly.
For instance,
[
frac{partial L}{partial hat{y}}
]
seems in each single equation.
Equally,
[
frac{partial hat{y}}{partial a_1}
]
and
[
frac{partial a_1}{partial z_1}
]
seem in each the gradients of [w_1] and [b_1]
In the identical method,
[
frac{partial hat{y}}{partial a_2}
]
and
[
frac{partial a_2}{partial z_2}
]
seem in each the gradients of [w_2] and [b_2]
Which means that if we calculate the gradient for every parameter individually, we are going to repeatedly compute lots of the identical partial derivatives time and again.
Because the variety of parameters in a neural community grows, repeating these calculations shortly turns into computationally costly.
Whereas this will not appear to be an issue in a small neural community, fashionable neural networks typically include hundreds and even hundreds of thousands of parameters.
Repeating the identical calculations would require considerably extra computational assets, and it will increase the coaching time.
There Has to Be a Higher Manner
So, is there a greater strategy to compute all these gradients with out repeating the identical calculations?
Sure.
However we don’t want a brand new mathematical idea. The identical chain rule is sufficient.
What modifications is how we apply it.
As an alternative of repeating the identical computations for each parameter, we arrange them in a method that it reuses intermediate outcomes.
This concept is the muse of backpropagation.
However figuring out that repeated computations might be reused is just the start.
The actual query is: how does a neural community know what to compute first, what to compute subsequent, and the way are all of the gradients obtained in a single environment friendly backward move?
That’s precisely what we’ll discover in Half 3.
Conclusion
We’ve now constructed all of the instinct we want.
We perceive how gradients stream via a neural community, why the chain rule is crucial, and why repeated computations grow to be an issue as neural networks develop.
The one query left is that how can the identical chain rule compute gradients for hundreds of thousands of parameters with out repeating the identical calculations?
Within the subsequent half, we’ll see how this works and step by step construct an understanding for backpropagation.
I hope you discovered this weblog useful.
In case you’re new to this collection and wish to learn the earlier articles, you’ll find them right here.
I’d love to listen to your ideas. In case you have any questions or suggestions, be happy to depart a touch upon LinkedIn.
Studying by no means exhausts the thoughts.
— Leonardo da Vinci
Thanks for studying!

