Как правильно определить функцию потерь в сети keras, которая берет изображение и выводит изображение? - PullRequest
0 голосов
/ 20 сентября 2019

Я пытаюсь построить модель, которая берет изображение в градациях серого и генерирует другое изображение в качестве вывода с помощью остаточного CNN с использованием керас.И ключевая идея здесь заключается в том, что количество небелых пикселей намного меньше, чем количество белых.Таким образом, ошибка в каждом небелом пикселе должна иметь больший вес в функции потерь, чем в белом.И чем темнее пиксель, тем больше должна быть ошибка.Вот как я это сделал сейчас.Здесь total_pred_score означает все правильно угаданные пиксели с их весами, определенными некоторым коэффициентом int, а total_true_score означает общую ожидаемую оценку для всех изображений и пикселей в наборе поездов.Но я не уверен, что это правильно. Можете ли вы помочь мне, пожалуйста?

def custom_loss(y_true, y_pred):
    y_true1, y_pred1 = (255 - y_true) / 255, (255 - y_pred) / 255
    dif = (1 - K.abs(y_true1 - y_pred1))
    weight = (coeff - 1) * y_true1 + 1 
    total_true_score = K.sum(weight, axis = [0,1,2,3])
    total_pred_score = K.sum(multiply([dif,weight]), axis = [0,1,2,3])
    return K.abs(total_true_score - total_pred_score) / total_true_score

1 Ответ

0 голосов
/ 21 сентября 2019

Функция потерь, которую вы пытаетесь построить, должна иметь два свойства:

  1. Ошибка в каждом небелом пикселе должна иметь больший вес, чем в белых
  2. Темнеев пикселе большая ошибка должна быть

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

Я придумал следующую функцию потерь, которая подчиняется этим двум свойствам:

def custom_loss(y_true, y_pred, coeff):
    y_true1, y_pred1 = (255 - y_true) / 255, (255 - y_pred) / 255
    dif = y_true1 - y_pred1
    temp1 = K.l2_normalize(K.cast(K.greater(dif, 0),"float32")*y_true1,axis=-1) * coeff
    temp2 = K.cast(K.less(dif, 0),"float32")
    weight = temp1 + temp2  
    loss = K.abs(weight*dif)
    average_loss = K.mean(loss)   ##you need to return this when you use in your code
    return K.eval(loss)

Таким образом, в основном мы находим разницу между истинным значением и прогнозируемым значением после выполнения нормализации и умножения весов, пропорциональных только положительным значениям в dif (что соответствует более темным пикселям) - temp1.А затем мы просто добавляем вес 1 к пикселям, соответствующим отрицательным значениям (что соответствует белому).

ВЫБОР ОБРАЗЦА

coeff = 5
y_t = np.array([0,250,30,0,255,160,210,0,2,4])
y_p = np.array([50,0,80,10,255,160,210,250,2,80])
custom_loss(y_t,y_p,coeff ) 

array([0.449957, 0.98039216, 0.39702088, 0.08999141, 0., 0., 0., 2.249785, 0., 0.67320627],dtype=float32)

Здесь, если вы внимательно посмотрите на пиксели в битах 2 и 8, пиксель 8 соответствует случаю, когда мыпредсказать темный пиксель в качестве временного пикселя, который в нашем случае ужасно плох, поэтому значение потерь действительно велико 2.249785, аналогично пиксель 2 соответствует случаю, когда мы прогнозируем белый пиксель как темный пиксель, что довольно хорошодля нас значение потери составляет 0.98039216, что не так высоко, как в предыдущем случае.Это соответствует свойству 1.

Аналогично, если вы смотрите как пиксели 1 и 3, то величина ошибки в обоих случаях одинакова (они отключены на 50), но пиксель1 намного темнее пикселя 3, поэтому мы хотим, чтобы ошибка на пикселе 1 была выше, чем пиксель 3, что мы и наблюдаем в векторе ошибок.

И в случаях, когда наши истинные и предсказанные значения совпадают, мы имеем ошибку 0.

Надеюсь, это поможет!

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