Функция потерь, которую вы пытаетесь построить, должна иметь два свойства:
- Ошибка в каждом небелом пикселе должна иметь больший вес, чем в белых
- Темнеев пикселе большая ошибка должна быть
Поэтому, чтобы упростить ее, вы хотите, чтобы ваша ошибка была больше, если вы классифицируете темный пиксель как белый, но на самом деле не слишком беспокоитесь о случаях, когда вы классифицируетебелые пиксели как темные, но вы все еще хотите, чтобы они вносили свой вклад в вашу функцию потерь.Кроме того, вы хотите убедиться, что ваша потеря пропорциональна интенсивности пикселя (чем темнее пиксель, тем больше ошибка).
Я придумал следующую функцию потерь, которая подчиняется этим двум свойствам:
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
.
Надеюсь, это поможет!