Вы пробовали использовать мягкие кубики?
В последних работах по компьютерному зрению предложены мягкие суррогаты для смягчения расхождений и прямой оптимизации желаемого показателя c, либо с помощью релаксации (soft-Dice, soft-Jaccard).
Есть и другие Функция потери, популярная для сегментации изображения:
Наиболее часто используемая функция потери для задачи сегментации изображения - это кросс-энтропийная потеря по пикселям , Эта потеря анализирует каждый пиксель индивидуально, сравнивая предсказания класса (вектор пикселей по глубине) с нашим целевым вектором, закодированным в горячем виде.
Другая популярная функция потерь для задач сегментации изображения основана на Коэффициент кости (который вы уже пробовали), который по сути является мерой перекрытия между двумя выборками. Эта мера варьируется от 0 до 1, где коэффициент Кости 1 означает идеальное и полное перекрытие.
Если вам интересно, в числителе есть 2 в расчете коэффициента кости, потому что наш знаменатель "дважды считает" общие элементы между двумя наборами. Чтобы сформулировать функцию потерь, которую можно минимизировать, мы просто используем 1-Dice.
Эта функция потерь известна как потеря мягких костей , потому что мы напрямую используем прогнозируемые вероятности вместо того, чтобы делать пороговые значения и преобразовывать их в двоичную маску.
A мягкая потеря кубиков рассчитывается для каждого класса отдельно и затем усредняется для получения окончательного результата. Пример реализации представлен ниже.
def soft_dice_loss(y_true, y_pred, epsilon=1e-6):
Soft dice loss calculation for arbitrary batch size, number of classes, and number of spatial dimensions.
Assumes the `channels_last` format.
# Arguments
y_true: b x X x Y( x Z...) x c One hot encoding of ground truth
y_pred: b x X x Y( x Z...) x c Network output, must sum to 1 over c channel (such as after softmax)
epsilon: Used for numerical stability to avoid divide by zero errors
# skip the batch and class axis for calculating Dice score
axes = tuple(range(1, len(y_pred.shape)-1))
numerator = 2. * np.sum(y_pred * y_true, axes)
denominator = np.sum(np.square(y_pred) + np.square(y_true), axes)
return 1 - np.mean(numerator / (denominator + epsilon)) # average over classes and batch
Вы можете попробовать эту функцию и выяснить, что лучше всего подходит для вашей модели.