Hello! Welcome back.
In our last lesson, we explored the theory behind gradient descent, understanding it as an iterative process for finding a function's minimum. We established the core update rule—taking a step in the direction of the negative gradient, scaled by a learning rate.
Today, we're moving from theory to practice. This lesson is all about turning that mathematical rule into working Python code. You will learn how to implement a basic gradient descent algorithm from scratch. This is a fundamental skill that demystifies how machine learning models actually "learn" from data.
We'll tackle this in two steps:
- First, we'll implement gradient descent for a simple, single-variable function to see the core mechanics in action.
- Then, we'll apply the same principles to a foundational machine learning model: linear regression.
Let's get started and write some code!
1. Implementing Gradient Descent for a Simple Function
The best way to start coding gradient descent is to apply it to a problem where we already know the answer. Let's use the simple quadratic function . We know from basic calculus that its minimum is at . Our goal is to write a Python script that finds this minimum iteratively.
To do this, we need three key components:
- The function itself:
f(x) = x**2 - The derivative of the function:
f'(x) = 2*x - The gradient descent update rule:
x_new = x_old - learning_rate * f'(x_old)
The following video provides an excellent visual walkthrough of implementing this from scratch, using NumPy for calculations and Matplotlib for visualization.
Gradient Descent From Scratch in Python - Visual Explanation
This video from NeuralNine, titled 'Gradient Descent From Scratch in Python', will guide you through the process of implementing and visualizing gradient descent for the function f(x) = x².
Please watch from the beginning until 13:19. Focus on these parts: Conceptual Setup (01:17 - 08:18): How the derivative (slope) tells us which way to move x to decrease y. Python Implementation (08:18 - 13:19): Observe how the concepts are translated into a Python script with a for loop that iteratively updates the x position.
As you saw in the video, the core of the implementation is a loop. Inside this loop, for a given number of iterations, we repeatedly:
- Calculate the gradient (the derivative,
2*x) at the current position. - Use the update rule to compute the new position.
- Update our current position to this new value.
This simple example shows the algorithm in its purest form.
2. The Learning Rate in Practice
In the last lesson, we discussed theoretically how a learning rate that is too high can cause the algorithm to overshoot the minimum, while one that is too low can lead to painfully slow convergence. Now you can see this happen live.
The next segment of the same video demonstrates exactly this.
Gradient Descent From Scratch in Python - Visual Explanation
Let's continue with the NeuralNine video to see the practical effects of choosing a good or bad learning rate.
Watch the section from 13:19 to 16:08. Notice what happens when the learning rate is set to be very small, too large (causing oscillation and divergence), and just right.
This visualization makes it very clear why tuning the learning rate is so important. It's a hyperparameter that you, the machine learning practitioner, must choose carefully to ensure your model trains effectively.
3. Applying Gradient Descent to Linear Regression
Now that we've implemented gradient descent for a toy problem, let's use it for a real machine learning task: linear regression.
The goal of simple linear regression is to find the best-fit line through a set of data points. This line is defined by the equation , where:
mis the slopebis the y-intercept
In this context, m and b are the parameters of our model. Our goal is to use gradient descent to find the optimal values of m and b that make our line fit the data as closely as possible.
To do this, we need a cost function to minimize. For linear regression, the standard cost function is the Mean Squared Error (MSE). It measures the average of the squared differences between the actual y values and the predicted y values (from our line).
The video below introduces this setup and walks through the Python implementation.
Machine Learning Tutorial Python - 4: Gradient Descent and Cost Function
This video from the channel 'codebasics' clearly explains how gradient descent is used to find the best m and b for a linear regression model.
First, watch from 02:19 to 05:05 to understand the problem setup: fitting a line and using Mean Squared Error as the cost function. Then, watch the implementation part from 16:04 to 21:41. This shows how to write the Python code to optimize both m and b simultaneously.
The process is very similar to our simple x^2 example, but now we have two parameters to update in each iteration. This requires calculating the partial derivatives of the MSE cost function with respect to m and b. These two partial derivatives form our gradient.
The update rules become:
Both updates are performed within the same loop, using the values of m and b from the previous iteration.
4. Hands-On Implementation: Your Turn!
Now it's time to run the code yourself. Below is a complete Python script that implements gradient descent for linear regression. It's based on the examples you've just seen.
I've included detailed comments to explain each part of the code.
import numpy as np
import matplotlib.pyplot as plt
# Step 1: Generate some synthetic data for linear regression
# We create data that loosely follows the line y = 2x + 3
X = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
y = np.array([5.1, 6.9, 9.2, 11.0, 13.1, 15.3, 17.2, 18.8, 21.3, 23.5])
# Step 2: Define the gradient descent function
def gradient_descent(X, y, learning_rate, iterations):
# Initialize parameters m (slope) and b (intercept) to 0
m_current = 0
b_current = 0
n = len(X) # Number of data points
cost_history = [] # To store the cost at each iteration for plotting
# The main iterative loop
for i in range(iterations):
# Calculate predicted y values: y = mx + b
y_predicted = m_current * X + b_current
# Calculate the cost (Mean Squared Error)
cost = (1/n) * sum([val**2 for val in (y - y_predicted)])
cost_history.append(cost)
# Calculate the partial derivatives (the gradients)
# Derivative of cost w.r.t. m
md = -(2/n) * sum(X * (y - y_predicted))
# Derivative of cost w.r.t. b
bd = -(2/n) * sum(y - y_predicted)
# Update the parameters using the update rule
m_current = m_current - learning_rate * md
b_current = b_current - learning_rate * bd
# Print progress (optional)
if (i % 100 == 0):
print(f"Iteration {i}: m = {m_current:.4f}, b = {b_current:.4f}, Cost = {cost:.4f}")
return m_current, b_current, cost_history
# Step 3: Run the gradient descent algorithm
learning_rate = 0.01
iterations = 1000
m_final, b_final, cost_history = gradient_descent(X, y, learning_rate, iterations)
print("\n--- Final Results ---")
print(f"Final m: {m_final:.4f}")
print(f"Final b: {b_final:.4f}")
# Step 4: Visualize the results
plt.figure(figsize=(12, 5))
# Plot 1: The regression line
plt.subplot(1, 2, 1)
plt.scatter(X, y, color='blue', label='Actual Data')
plt.plot(X, m_final * X + b_final, color='red', label='Fitted Line')
plt.title('Linear Regression Fit')
plt.xlabel('X')
plt.ylabel('y')
plt.legend()
# Plot 2: Cost reduction over iterations
plt.subplot(1, 2, 2)
plt.plot(range(iterations), cost_history, color='green')
plt.title('Cost Function Convergence')
plt.xlabel('Iteration')
plt.ylabel('Cost (MSE)')
plt.tight_layout()
plt.show()
Test your understanding!
Run the Python script provided above.
- What are the final values of
mandbthat you get withlearning_rate = 0.01anditerations = 1000? (They should be close to 2 and 3). - Now, change the
learning_rateto0.05. What happens? Does the algorithm converge? If so, does it happen faster or slower (in terms of iterations)? - Reset the learning rate to
0.01and change theiterationsto just10. What do the finalm,b, and the fitted line plot look like? Why?
Show answer
- With
learning_rate = 0.01anditerations = 1000, the final values should be aroundm = 2.03andb = 3.01. The cost converges nicely. - With
learning_rate = 0.05, the algorithm diverges. You'll see the cost value explode toinf(infinity) and get anOverflowErrororRuntimeWarning. This is because the steps are too large, and it's overshooting the minimum dramatically at each step. - With only
10iterations, the algorithm doesn't have enough time to converge. The finalmandbwill be far from the optimal values (e.g., aroundm=1.3,b=0.3), and the fitted line will be a poor fit for the data. The cost plot will show a downward trend but will still be very high.
For a clean, text-based guide that recaps the code and concepts for linear regression with gradient descent, you can refer to the following article.
Implementing Gradient Descent from Scratch: A Step-by-Step ...
This article, 'Implementing Gradient Descent from Scratch', provides a concise, step-by-step guide to the Python code, which can serve as a great reference.
Read the section titled 'Implementing Gradient Descent from Scratch in Python'. It breaks down the implementation into clear steps: importing libraries, defining the cost function, implementing the main algorithm, and running it on data.
Conclusion
Congratulations! You have now implemented one of the most important algorithms in machine learning from scratch. By translating the mathematical formulas into Python code, you've gained a much deeper understanding of how a model can learn from data.
Key Takeaways:
- Implementing gradient descent in Python requires an iterative loop that updates model parameters.
- The core of the loop consists of calculating the predicted values, computing the cost, finding the gradient (partial derivatives), and applying the update rule.
- The same gradient descent logic applies whether you are minimizing a simple mathematical function or a complex cost function for a machine learning model like linear regression.
- Experimenting with hyperparameters like the learning rate and number of iterations is a key part of the machine learning process.
Preview of the Next Module:
This lesson concludes our module on Calculus for Machine Learning. You now have the mathematical tools to understand how models are optimized. Our next module, Probability and Statistics Essentials, will equip you with the tools to evaluate these models. You'll learn how to measure uncertainty, describe data, and formally test hypotheses about your model's performance—essential skills for any machine learning practitioner.