Dont understand how a for loop is working

Hello, everyone.

On this lesson

It is asked to create a loop that improves the values of b and m (exercise 4)
The correct answer is the following:

def gradient_descent(x, y, learning_rate, num_iterations):
  b = 0
  m = 0
  for i in range(num_iterations): # loop that runs num_iter times
    b, m = step_gradient(b, m, x, y, learning_rate)
  return b, m

But i dont understand this for loop inside the function, shouldnt it have a

b +=  b
m += m

inside the for loop or something to sum the iterations to b and m? It seems to me that i didnt have to define b and m before the for loop at all, but it is asked for me to do so. It also seems to run fine if i take b = 0 \ m = 0 off, so i’m confused.

If you don’t need them comment them out. Maybe you’ll find you’re using them.

Did you run it? Or did you just create the function and then never call it? Because that would be not running it.
Looking at the instructions asking you to do this, they do say why you would do it.

Your code says to double b

b += b

Not sure that’d help, maybe you mean something like,

b_, m_ = step_gradient( ... )
b += b_
m += m_

and whether that should be done would depend on what step_gradient promises to return, does it return something that you would want to add to the old value, or no?

2 Likes

gradient_descent is supposed to return values for b and m that minimizes the loss of a linear regression model.
So, starting from b = 0 and m = 0, gradient_descent will run a loop that, for every iteration on the loop, it is getting closer to the values of b and m that minimizes the loss.
The purpose of step_gradient function is to set how large and direction (adding or subtracting from 0) of those steps towards minimum value

So I thought the values for b and m would gradually change with every for loop iteration. Like, for every iteration they would add 1 to b and 2 to m, until they reach minimum model loss at b = 3 and m = 6 (not the actual results, just an example). So thats why i coded

def gradient_descent(x, y, learning_rate, num_iterations):
  b = 0
  m = 0
  for i in range(num_iterations): # loop that runs num_iter times
    b, m = step_gradient(b, m, x, y, learning_rate)
    b += b
    m += m
  return b, m

but it actually seems that this for loop just does that without me telling him to do that, it just go straight to the best values for b and m as one big step, not step by step. I dont understand why this is happening, is it changing b and m gradually by itself?

About that, i tried to re run the whole thing and if i take m = 0 and b=0 off it runs a completly wrong answer, i could see it by plotting the graph. So the thing is that it was running without them, but running an wrong answer, i just couldnt see that it was wrong because i didnt check.
Thank you for that, one of my questions are clarified, b=0 and m=0 are essential for running the code correctly. Which makes me think the for loop really is going step by step, but why dont i have to put the b += and m+= to do so? i tried this one you said

and it doesnt return the correct answer

I think it is best that i post my whole code, so here it is:

import codecademylib3_seaborn
import matplotlib.pyplot as plt

def get_gradient_at_b(x, y, b, m):
  N = len(x)
  diff = 0
  for i in range(N):
    x_val = x[i]
    y_val = y[i]
    diff += (y_val - ((m * x_val) + b))
  b_gradient = -(2/N) * diff  
  return b_gradient

def get_gradient_at_m(x, y, b, m):
  N = len(x)
  diff = 0
  for i in range(N):
      x_val = x[i]
      y_val = y[i]
      diff += x_val * (y_val - ((m * x_val) + b))
  m_gradient = -(2/N) * diff  
  return m_gradient

#Your step_gradient function here
def step_gradient(b_current, m_current, x, y, learning_rate):
    b_gradient = get_gradient_at_b(x, y, b_current, m_current)
    m_gradient = get_gradient_at_m(x, y, b_current, m_current)
    b = b_current - (learning_rate * b_gradient)
    m = m_current - (learning_rate * m_gradient)
    return b, m
  
#Your gradient_descent function here:  
def gradient_descent(x, y, learning_rate, num_iterations):
  b = 0
  m = 0
  for i in range(num_iterations): # loop that runs num_iter times
    b, m = step_gradient(b, m, x, y, learning_rate)
  return b, m

months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
revenue = [52, 74, 79, 95, 115, 110, 129, 126, 147, 146, 156, 184]

#Uncomment the line below to run your gradient_descent function
b, m = gradient_descent(months, revenue, 0.01, 1000)

#Uncomment the lines below to see the line you've settled upon!
y = [m*x + b for x in months]

plt.plot(months, revenue, "o")
plt.plot(months, y)
plt.show()

You’re calling another function which returns two values. What did it do to obtain those two values? Until you know what it returns you can’t say it should be one way or another.

If you comment out the initiations to 0 it SHOULD crash, because you’re sending the initial guesses to that function. If you haven’t defined your initial guess and use your initial guess… that’s impossible. The instructions do say that 0, 0 is used as the initial guess.

1 Like

Ohhhhhhh i see now!
The function i’m calling already does the change in b and m, ■■■■, rookie mistake…

Thank you so much for your time, you helped me a lot.