Пользовательская метрика Keras возвращает ошибку «ось вне границ» - PullRequest
4 голосов
/ 21 мая 2019

Я построил мультиклассовую сеть классификации изображений с несколькими метками, используя Keras. Всего 25 классов, и в каждом изображении есть хотя бы один класс. Я хочу реализовать пользовательскую метрику точности, которая говорит мне, как часто самый высокий класс вероятности на изображении (регулярная точность менее значима, так как истинные позитивы завалены истинными негативами).

Я построил простую функцию, которая генерирует желаемую метрику точности при ручной подаче y_true и y_pred. Однако, когда я пытаюсь вставить эту функцию в процесс обучения модели, она выдает ошибку.

def customAcc(y_true, y_pred):
    classPreds = np.array([np.eye(numClasses)[x] for x in  np.argmax(y_pred, axis=1)])
    correctPreds = y_true * classPreds
    return np.mean(np.sum(correctPreds, axis=1))

model.compile(optimizer=tf.keras.optimizers.Adam(lr=0.0001), 
loss='binary_crossentropy', metrics=['accuracy', customAcc])

AxisError: ось 1 выходит за границы массива измерения 1

1 Ответ

1 голос
/ 21 мая 2019

TL; DR

y_pred - это 1D, у него только одна возможная ось.Удалите axis=1 из вашего np.argmax вызова.


Пошаговое руководство

Проблема в данном конкретном случае заключается в следующей строке:

classPreds = np.array([np.eye(numClasses)[x] for x in  np.argmax(y_pred, axis=1)])

В частности: np.argmax(y_pred, axis=1).Ваш y_pred является одномерным массивом - таким как [0.1, 0.2] - и вы говорите np.argmax искать значения по axis=1, которых не существует, если вы не передаете массивы с двумя или более измерениями - такими как[[0.1, 0.2], [0.3, 0.4]].

Пример действия:

>>> import numpy as np
>>> num_classes = 25
>>> np.argmax([0.1, 0.5, 0.9]) # max value's index on 1D array
2
>>> np.argmax([0.1, 0.5, 0.9], axis=1) # max value's index on axis 1 of 1D array
AxisError: axis 1 is out of bounds for array of dimension 1

Если бы y_pred был двумерным массивом, ошибка оси не произошла бы, но np.argmax вернул бы списокиндексы вместо скаляра , например:

>>> np.argmax([
...     [0.1, 0.5, 0.9],
...     [0.9, 0.5, 0.1]
... ], axis=1)
array([2, 0], dtype=int64) # first array's max at index 2, second array's max at index 0

Убрав axis=1 из argmax, вы получите правильный скалярный индекс для максимального значенияв пределах y_pred.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...