W2_Ex-8_Problems with costs

As suggested, I started a new thread on this. Exercise 1-7 have had all tests passed. Yet in trying to implement Ex. 8 I am getting the following error(s) related to costs (and my cost does not match the expected cost):


AssertionError Traceback (most recent call last)
in
1 from public_tests import *
2
----> 3 model_test(model)

~/work/release/W2A2/public_tests.py in model_test(target)
125 d = target(X, Y, x_test, y_test, num_iterations=50, learning_rate=0.01)
126
→ 127 assert type(d[‘costs’]) == list, f"Wrong type for d[‘costs’]. {type(d[‘costs’])} != list"
128 assert len(d[‘costs’]) == 1, f"Wrong length for d[‘costs’]. {len(d[‘costs’])} != 1"
129 assert np.allclose(d[‘costs’], expected_output[‘costs’]), f"Wrong values for d[‘costs’]. {d[‘costs’]} != {expected_output[‘costs’]}"

AssertionError: Wrong type for d[‘costs’]. <class ‘numpy.ndarray’> != list

Not sure how to proceed in the debugging process.

Hello @Richard_Rasiej,

You may begin with inspecting the error message:

d['costs'] is required to be type list, but the requirement isn’t satisfied. Would you make sure it is a list?

Raymond

Right! As Raymond says, the first rule of debugging is “Believe the error message!” If you don’t understand what it means, then the first step is to investigate that. Note the return value of model is a dictionary, which contains lots of objects, one of which is the costs value. Where did that come from? It was returned by the call from model to optimize, right? Did your optimize function pass its test cases earlier in the notebook?

Put a print statement in your model function after the loop that calls optimize:

print(type(costs))

What does that show? As the error message showed us, it is supposed to be a python list. How could it end up as a numpy array instead?

Hi Raymond,

I added a print(type(costs)) in the definition of the optimize function just before the return statement. Running the validation which showed all tests passed also had a value returned for type(costs) as <class ‘list’>. There is no occurrence of costs in the predict function. The next occurrence of costs occurs in the definition of the model function, after the call to propagate (which returns cost, not costs). I put in a line to print(type(costs)) here and got <class ‘numpy.ndarray’>

So does that mean I made an error in the propagate function, even though all tests were passed?

There is no reason to call propagate directly from model, right? If you’re doing that, that is the cause of the problem. You only need to call optimize from model.

I called propagate because I thought I was correctly following the suggestions:

(≈ 1 line of code)

# initialize parameters with zeros 
# w, b = ...

#(≈ 1 line of code)
# Gradient descent 
# params, grads, costs = ...

# Retrieve parameters w and b from dictionary "params"
# w = ...
# b = ...

Sorry, but that is a mistake. Notice that it talks about gradient descent there. Where does that happen? propagate returns the gradients, but the gradient descent happens in optimize, right? The other clue is what are the return values of propagate?

OK. I should have called optimize, not propagate (which returns “cost” not “costs”). However now I am getting a wrong value for w. I made the call right after initializing the parameters w and b to 0.

Ok, one step at a time. There are right and wrong ways to call optimize. Did you “hard-wire” any of the parameters or omit them and thus end up using their defaults? E.g. number of iterations and learning rate?

Here’s how optimize is originally set up:

def optimize(w, b, X, Y, num_iterations=100, learning_rate=0.009, print_cost=False)

and here is how I called it:

{moderator edit - solution code removed}

Are you familiar with how “named” parameters work in python? Think about what your code means: no matter what values are passed in to model at the top level, optimize will always run 100 iterations. That will not end well, of course.

Calling a function is an entirely different thing than defining a function, right? You can’t just “copy/paste” the definition as the invocation.

OK, I thought what I needed to do was to replace the “generic” X and Y with the _train. I left the other stuff alone because that’s what was there in the original definition. Although I see your point - why would you hardcode 100 iterations into a definition? Does that mean, that is a default value and I should have made my call with a different value?

I guess my biggest problem at the moment is being a Python newb. The math is relatively easy.

Understanding the meaning of the code you are writing is pretty fundamental. If you are new to python, I suggest you google “python named parameters” and spend 20 or 30 minutes reading the tutorials that will get you.

The point is by specifying num_iterations = 100 on the function call, means that the value is fixed. It should be obvious that is not what you want. When you write that in the definition of the function, what you are saying is that parameter is optional and if not passed, it has a default value of 100.

The other high level point here is that this course is not intended as an “intro to python”. We’ll try to help, but if python is new to you, you need to fix that first. If you are very experienced in other languages like c, C++, JavaScript or … then you can probably wing it and just look things up when you hit something new. But if you’re relatively new to programming in general, the better approach might be to pause this course and take a real python course first.

OK. I see that num_iterations, learning_rate, and print_cost are optional variables, with default values 100, .009, and False for optimize and 2000, 0.5, and False for model (and 50, .01, are used in the test for model).

So it would appear that the required named parameters are w, b, X, and Y. But if I only pass w, b, X_train, and Y_train, I am still getting a “wrong value” error for w.

I need to look someplace else, I suppose?

I just explained that. If you omit the named parameters, then that means you get the default values. That is wrong. You want the actual values that were passed, right?

I have programmed before: Fortran, APL, some VisualBasic. I can also understand Wolfram (Mathematica)

Ok, that’s good. But python has it’s own quirks. There are zillions of websites out there with good educational material on python. python.org has copious documentation and tutorials. I suggest you do what I said a few posts ago: google “python named parameters” and then spend 30 minutes reading what you find.

You mean the

num_iterations=50, learning_rate=0.01

that’s in the test?

How would I know that those are the values to pass without peeking at the public_tests code?

Or were the values I need created someplace else which I have overlooked?

One other thing to watch out for is that none of the languages you know have the concept of “pointers”. There are some big landmines to do with the way object references work in python. Have a look at this post and this one.