Вопрос или проблема
Я использую 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 массивом такого же размера (ширина и высота), как входное изображение. Каждый элемент в массиве представляет собой степень уверенности в предсказании каждого соответствующего пикселя во входном изображении. Пиксели обнаруженного объекта будут иметь высокие предсказания уверенности.
Вы можете создать бинарную маску выходных данных, используя порог уверенности предсказания. Например:
- confidence_th = 0.8
- Y_pred_test = seg_model.predict(test_image)
- Y_pred_test = Y_pred_test > confidence_th
Ответ или решение
Ошибка при генерации матрицы путаницы в задаче сегментации изображений
При работе с задачами сегментации изображений с использованием Keras и U-Net, вы столкнулись с проблемой при генерации матрицы путаницы. Давайте рассмотрим ваш код, определим потенциальные проблемы и предложим решения.
Контекст проблемы
Вы используете генераторы изображений и масок, создаваемые с помощью ImageDataGenerator
, для тренировки и тестирования вашей модели. После предсказания результатов на тестовом наборе вы пытаетесь сгенерировать матрицу путаницы с использованием функции confusion_matrix
из библиотеки sklearn, но вам выдается ошибка:
ValueError: unknown is not supported
Этот сбой возникает, когда целевые метки и предсказанные метки не соответствуют ожидаемому формату.
Причины возникновения ошибки
-
Неверный формат меток: Для семантической сегментации, такой как ваша, результаты предсказания представляют собой 2D массивы (или тензоры) размером (ширина, высота) с вероятностями для каждого пикселя, что отличается от классических задач классификации, где используются одномерные массивы.
-
Необходимый формат для функции
confusion_matrix
: Эта функция требует, чтобыy_true
иy_pred
имели одинаковое количество элементов и были одномерными массивами меток классов, а не пикселей.
Решение проблемы
Чтобы суммировать результаты на пиксельном уровне и создать матрицу путаницы, вам необходимо преобразовать предсказания модели и фактические маски в одномерные массивы меток. Для этого выполните следующие шаги:
- Преобразуйте прогнозы и истинные значения: Вам нужно оценить уверенность предсказаний и применить пороговую функцию для получения бинарных масок.
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) # Аналогично для истинных значений
- Создайте матрицу путаницы: Теперь, когда у вас есть один массив меток для предсказанных и истинных значений, вы можете вызвать функцию
confusion_matrix
:
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_actual_test, y_pred_test)
print(cm)
Заключение
Работа с семантической сегментацией требует особого подхода к обработке выходных данных модели и целевых меток. Убедитесь, что вы преобразуете данные масок в нужный формат перед тем, как передавать их в функции, такие как confusion_matrix
. Основные проблемы могли возникать из-за несовпадения форматов данных. Следуя указанным шагам, вы должны быть в состоянии успешно сгенерировать матрицу путаницы для вашей модели сегментации.