Python isinstance () проверки утверждения с ошибкой с плавающей запятой

Задний план:
Я прошел курс машинного обучения и нейронных сетей, и в следующих случаях, когда я столкнулся с проблемой, нам требовалось вычислить функцию стоимости. Есть два способа сделать это, применив np.multiply и np.sum ИЛИ к np.dot. В этом примере я назвал их cost1 и cost2 соответственно. Они дают тот же результат.

Вопрос:
Моя проблема в том, что функция (которая для меня уже завершена) утверждает, что стоимость является плавающей, используя isinstance (). Первый метод выдает значение, которое проходит этот тест, а второй - нет. Однако, когда я печатаю оба значения и связанные с ними dtypes, они оба кажутся числами с плавающей запятой, хотя cost2 имеет большую точность. Почему cost2 не проходит тест на утверждение?

Код:

def compute_cost(A2, Y, parameters):
    """ 
    Computes the cross-entropy cost given in equation (13)

    Arguments:
    A2 -- The sigmoid output of the second activation, of shape (1, number of examples)
    Y -- "true" labels vector of shape (1, number of examples)
    parameters -- python dictionary containing your parameters W1, b1, W2 and b2

    Returns:
    cost -- cross-entropy cost given equation (13)
    """

    m = Y.shape[1] # number of example

    # Compute the cross-entropy cost
    ### START CODE HERE ### (≈ 2 lines of code)
    logprobs = np.multiply(np.log(A2), Y)
    cost1 = -np.sum(logprobs)
    cost2 = -np.dot(np.log(A2), Y.T)
    ### END CODE HERE ###

    cost1 = np.squeeze(cost1)     # makes sure cost is the dimension we expect. 
    cost2 = np.squeeze(cost2)     # E.g., turns [[17]] into 17 


    # Troubleshooting
    print(cost1.dtype,cost2.dtype)
    print(cost1,cost2)

    assert(isinstance(cost1, float))
    assert(isinstance(cost2, float))

    return cost1


A2, Y_assess, parameters = compute_cost_test_case()
print("cost = " + str(compute_cost(A2, Y_assess, parameters)))

Выход:

float64 float64
0.692685886972 0.6926858869721941
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
<ipython-input-84-92a25de13cb3> in <module>()
  1 A2, Y_assess, parameters = compute_cost_test_case()
  2 
----> 3 print("cost = " + str(compute_cost(A2, Y_assess, parameters)))

<ipython-input-83-411aa6cb57b7> in compute_cost(A2, Y, parameters)
 30 
 31     assert(isinstance(cost1, float))
---> 32     assert(isinstance(cost2, float))
 33 
 34     return cost1

AssertionError: 

Показать вывод print(type(cost1), type(cost2))

pault 20.03.2018 20:15

Числовые числа с плавающей запятой не являются подклассами Python с плавающей запятой.

hpaulj 20.03.2018 20:20

np.squeeze вернет массив из многомерного массива. Таким образом, ваш cost2.dtype по-прежнему будет возвращать dtype членов массива, isinstance по-прежнему будет видеть его как массив.

Brian 20.03.2018 20:20

Если cost1 - это массив с одним элементом или np.float64, то cost1.item() будет Python с плавающей запятой.

hpaulj 20.03.2018 20:23
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
4
2 609
1

Ответы 1

Хорошо, позвольте мне начать с самого начала.

Первый, и это касается не вопроса, который вы задали, а научного секретариата. np.dot() не всегда равен np.sum and np.multiply, теоретически они равны, но что касается расчета функции затрат, они не будут одинаковыми, так как расчеты np.dot будут отличаться от матрицы к вектору, не говоря уже о том, что это выдаст вам ошибку из-за несоответствия размеров. Поэтому на всякий случай используйте функции умножения и суммирования, и вы можете проверить этот пост для получения дополнительной информации по этому поводу. Реализация функции стоимости в логистической регрессии в Python: почему умножение точек в одном выражении, а поэлементное умножение в другом

Второй, и это ваш исходный вопрос, чтобы разобраться в проблеме, вы должны распечатать всю информацию о cost1 и cost2. Например, после расчета уравнения стоимости с keepdims = True вы обнаружите, что cost.shape = (), cost.dtype = float64 и type(cost) = numpy.ndarray, которые являются scalar и это твоя проблема здесь.
Функция squeeze может успешно выполнить уменьшение размеров до точки, например, [[.364]] будет .364. Однако .364 будет иметь тип numpy.ndarray.

Итак, чтобы преобразовать scalar в float, вы можете просто сделать это

Решение:

cost = np.asscalar(cost)    # make sure to convert scalar with shape () to normal float

Следовательно, ваше утверждение наверняка будет работать нормально.

Вы можете проверить этот вопрос Как преобразовать одноэлементный массив в скалярное значение в Python? и этот тоже Что такое ndarray shape (), возвращаемый после np.squeeze из shape (1,1)?

Другие вопросы по теме