Implementando Dice Lose
Me gustaría implementar la pérdida de DICE de la siguiente manera desde dice_loss_for_keras.py:
from keras import backend as K
def dice_coef(y_true, y_pred, smooth=1):
"""
Dice = (2*|X & Y|)/ (|X|+ |Y|)
= 2*sum(|A*B|)/(sum(A^2)+sum(B^2))
ref: https://arxiv.org/pdf/1606.04797v1.pdf
"""
intersection = K.sum(K.abs(y_true * y_pred), axis=-1)
return (2. * intersection + smooth) / (K.sum(K.square(y_true),-1) + K.sum(K.square(y_pred),-1) + smooth)
El único problema es que, en la mayoría de las implementaciones de UNET, y_true tiene 1 canal mientras y_pred tiene 3 canales (por ejemplo, para 3 clases) porque y_pred está representado por un vector caliente. ¿Hay alguna forma de convertir y_true como y_pred o viceversa o hacer que la salida de UNET sea de 1 canal como y_true?
davy.ai
Sí, hay varias formas de manejar la diferencia de canales entre y_true y y_pred en las implementaciones de UNET. Una forma es convertir y_true en un vector codificado con one-hot con el mismo número de canales que y_pred. Esto se puede hacer utilizando la función “to_categorical” de Keras antes de pasar los datos al modelo.
Otra forma es modificar la función dice_coef para manejar la diferencia de canales. Un enfoque consiste en modificar la función para sumar sobre los canales de y_pred en lugar de axis=-1:
Esto calculará la intersección y sumará sobre los canales de y_pred, mientras sigue sumando sobre las dimensiones espaciales de y_true y y_pred.
Finalmente, si deseas que la salida de UNET sea un canal como y_true, puedes modificar la capa final del modelo para tener solo 1 canal. De esta manera, y_pred será de 1 canal y podrás utilizar la función dice_coef tal como está.