Не удалось сгенерировать матрицу неточностей

Вопрос или проблема

Я использую keras flow from directory для сегментации изображений. Ниже приведен мой код

import os
import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator 
from tensorflow import keras
from sklearn.metrics import classification_report, confusion_matrix
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
from skimage import data, img_as_float
from skimage import exposure
SEED = 909
BATCH_SIZE_TRAIN = 8
BATCH_SIZE_TEST = 8

IMAGE_HEIGHT = 200
IMAGE_WIDTH = 200
IMG_SIZE = (IMAGE_HEIGHT, IMAGE_WIDTH)

NUM_TRAIN = 1320
NUM_TEST = 440

NUM_OF_EPOCHS = 50
def create_segmentation_generator_train(img_path, msk_path, BATCH_SIZE):
    data_gen_args = dict(rescale=1./255,
                         featurewise_center=False,
                         featurewise_std_normalization=False,
                         rotation_range=0,
                         width_shift_range=0.0,
                         height_shift_range=0.0,
                         zoom_range=0.0
                         )

    datagen = ImageDataGenerator(**data_gen_args)
    datagen1 = ImageDataGenerator(rescale=1./255)      

    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode="grayscale", batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen1.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode="grayscale", batch_size=BATCH_SIZE, seed=SEED)
    return zip(img_generator, msk_generator)

def create_segmentation_generator_test(img_path, msk_path, BATCH_SIZE):
    data_gen_args = dict(rescale=1./255)

    datagen = ImageDataGenerator(**data_gen_args)

    img_generator = datagen.flow_from_directory(img_path, target_size=IMG_SIZE, class_mode=None, color_mode="grayscale", batch_size=BATCH_SIZE, seed=SEED)
    msk_generator = datagen.flow_from_directory(msk_path, target_size=IMG_SIZE, class_mode=None, color_mode="grayscale", batch_size=BATCH_SIZE, seed=SEED)
    return zip(img_generator, msk_generator)
train_generator = create_segmentation_generator_train(data_dir_train_image,data_dir_train_mask,BATCH_SIZE_TRAIN)
test_generator  = create_segmentation_generator_test(data_dir_test_image,data_dir_test_mask, BATCH_SIZE_TEST)

При запуске модели глубокого обучения U-net я использовал следующий код для создания матрицы замешательства

Y_pred_test = model.predict_generator(test_generator, NUM_TEST // BATCH_SIZE_TEST+1)
y_pred_test = np.argmax(Y_pred_test, axis=1)
Y_actual_test = test_generator
y_actual_test = np.argmax(Y_pred_test,axis=1)
confusion_matrix(y_actual_test,y_pred_test)

Я получаю следующую ошибку

ValueError                                Traceback (most recent call last)
<ipython-input-58-5316d65a4c5b> in <module>
----> 1 confusion_matrix(y_actual_test,y_pred_test)

~\Anaconda3\envs\tf-gpu1\lib\site-packages\sklearn\utils\validation.py in inner_f(*args, **kwargs)
     61             extra_args = len(args) - len(all_args)
     62             if extra_args <= 0:
---> 63                 return f(*args, **kwargs)
     64 
     65             # extra_args > 0

~\Anaconda3\envs\tf-gpu1\lib\site-packages\sklearn\metrics\_classification.py in confusion_matrix(y_true, y_pred, labels, sample_weight, normalize)
    297 
    298     """
--> 299     y_type, y_true, y_pred = _check_targets(y_true, y_pred)
    300     if y_type not in ("binary", "multiclass"):
    301         raise ValueError("%s is not supported" % y_type)

~\Anaconda3\envs\tf-gpu1\lib\site-packages\sklearn\metrics\_classification.py in _check_targets(y_true, y_pred)
     98     # Нет метрик, которые поддерживают формат "multiclass-multioutput"
     99     если (y_type not in ["binary", "multiclass", "multilabel-indicator"]):
--> 100         raise ValueError("{0} не поддерживается".format(y_type))
    101 
    102     если y_type в ["binary", "multiclass"]:

ValueError: unknown не поддерживается

Я выполняю задачу сегментации изображений одного класса и использовал архитектуру U-net с использованием библиотеки keras. Я также проверил типы y_actual_test и y_pred_test и вижу их как numpy.ndarray. Что я делаю не так?

Пожалуйста, помогите.

Семантическая сегментация изображений — это классификация на уровне пикселей.
Если это бинарная сегментация (фон и объект), выход обученной модели будет 2D массивом такого же размера (ширина и высота), как входное изображение. Каждый элемент в массиве представляет собой степень уверенности в предсказании каждого соответствующего пикселя во входном изображении. Пиксели обнаруженного объекта будут иметь высокие предсказания уверенности.

Вы можете создать бинарную маску выходных данных, используя порог уверенности предсказания. Например:

  1. confidence_th = 0.8
  2. Y_pred_test = seg_model.predict(test_image)
  3. Y_pred_test = Y_pred_test > confidence_th

Ответ или решение

Ошибка при генерации матрицы путаницы в задаче сегментации изображений

При работе с задачами сегментации изображений с использованием Keras и U-Net, вы столкнулись с проблемой при генерации матрицы путаницы. Давайте рассмотрим ваш код, определим потенциальные проблемы и предложим решения.

Контекст проблемы

Вы используете генераторы изображений и масок, создаваемые с помощью ImageDataGenerator, для тренировки и тестирования вашей модели. После предсказания результатов на тестовом наборе вы пытаетесь сгенерировать матрицу путаницы с использованием функции confusion_matrix из библиотеки sklearn, но вам выдается ошибка:

ValueError: unknown is not supported

Этот сбой возникает, когда целевые метки и предсказанные метки не соответствуют ожидаемому формату.

Причины возникновения ошибки

  1. Неверный формат меток: Для семантической сегментации, такой как ваша, результаты предсказания представляют собой 2D массивы (или тензоры) размером (ширина, высота) с вероятностями для каждого пикселя, что отличается от классических задач классификации, где используются одномерные массивы.

  2. Необходимый формат для функции confusion_matrix: Эта функция требует, чтобы y_true и y_pred имели одинаковое количество элементов и были одномерными массивами меток классов, а не пикселей.

Решение проблемы

Чтобы суммировать результаты на пиксельном уровне и создать матрицу путаницы, вам необходимо преобразовать предсказания модели и фактические маски в одномерные массивы меток. Для этого выполните следующие шаги:

  1. Преобразуйте прогнозы и истинные значения: Вам нужно оценить уверенность предсказаний и применить пороговую функцию для получения бинарных масок.
confidence_threshold = 0.5  # Порог уверенности
Y_pred_test = model.predict_generator(test_generator, NUM_TEST // BATCH_SIZE_TEST + 1)
# Применение порога
Y_pred_test_binary = (Y_pred_test > confidence_threshold).astype(np.uint8)

# Преобразование 2D-предсказаний и истинных масок в 1D
y_pred_test = Y_pred_test_binary.flatten()  # Переводим 2D в 1D для предсказаний
Y_actual_test = np.concatenate([m for _, m in test_generator], axis=0)  # Объединяем маски из генератора
y_actual_test = Y_actual_test.flatten().astype(np.uint8)  # Аналогично для истинных значений
  1. Создайте матрицу путаницы: Теперь, когда у вас есть один массив меток для предсказанных и истинных значений, вы можете вызвать функцию confusion_matrix:
from sklearn.metrics import confusion_matrix

cm = confusion_matrix(y_actual_test, y_pred_test)
print(cm)

Заключение

Работа с семантической сегментацией требует особого подхода к обработке выходных данных модели и целевых меток. Убедитесь, что вы преобразуете данные масок в нужный формат перед тем, как передавать их в функции, такие как confusion_matrix. Основные проблемы могли возникать из-за несовпадения форматов данных. Следуя указанным шагам, вы должны быть в состоянии успешно сгенерировать матрицу путаницы для вашей модели сегментации.

Оцените материал
Добавить комментарий

Капча загружается...