使用isinstance()判断float类型失败的Python断言测试问题
Hey there! I ran into this exact same confusion when I was learning ML cost functions too—let's figure out why cost1 isn't passing that isinstance() check even though its value matches cost2.
The Root Cause
When you use np.sum() (after np.multiply()), the result is a numpy-specific floating-point type (usually numpy.float64), not Python's native float type. The isinstance(cost, float) assertion only checks for the native Python class, so it rejects the numpy float even though the number itself is correct.
On the other hand, np.dot() might be returning a native float in your case (this can depend on the shapes of your arrays and your numpy version), which is why cost2 passes the check.
Simple Fixes
Here are a couple of ways to resolve this:
1. Convert the Numpy Float to a Native Python Float
Just wrap your np.sum() result in float() to convert it explicitly:
# Your original cost1 calculation cost1 = np.sum(np.multiply(y, np.log(y_hat)) + np.multiply((1 - y), np.log(1 - y_hat))) * (-1/m) # Fixed version cost1 = float(np.sum(np.multiply(y, np.log(y_hat)) + np.multiply((1 - y), np.log(1 - y_hat))) * (-1/m))
Now isinstance(cost1, float) will return True.
2. Update the Assertion to Accept Numpy Floats
If you don't mind keeping the numpy type (it works fine in most ML calculations), modify the assertion to check for both native and numpy floating types:
import numpy as np assert isinstance(cost, (float, np.floating)), "Cost must be a floating-point number"
This way both cost1 and cost2 will pass the check without converting anything.
3. Verify with Value Equality (Bonus)
If the type check feels too strict, you could also verify that the cost is a scalar with the correct value instead:
assert np.isscalar(cost) and isinstance(cost, (float, np.floating)), "Cost must be a scalar float"
Quick Example to Prove It
Let's test this with dummy values:
import numpy as np y = np.array([1, 0]) y_hat = np.array([0.7, 0.2]) m = len(y) # Method 1: multiply + sum cost1 = np.sum(np.multiply(y, np.log(y_hat)) + np.multiply(1 - y, np.log(1 - y_hat))) * (-1/m) print(type(cost1)) # <class 'numpy.float64'> print(isinstance(cost1, float)) # False # Method 2: dot cost2 = (-1/m) * (np.dot(y, np.log(y_hat)) + np.dot(1 - y, np.log(1 - y_hat))) print(type(cost2)) # Might be <class 'float'> or <class 'numpy.float64'> depending on setup print(isinstance(cost2, float)) # True in your case # Fixed cost1 cost1_fixed = float(cost1) print(isinstance(cost1_fixed, float)) # True
The key takeaway is that numpy's numeric types are compatible with Python's, but they're not the same class—so strict type checks will fail unless you account for both.
内容的提问来源于stack exchange,提问作者Mika

