web-dev-qa-db-fra.com

Perte d'entropie croisée pour Keras de segmentation sémantique

Je suis presque sûr que c'est une question idiote mais je ne la trouve nulle part ailleurs donc je vais la poser ici.

Je fais la segmentation d'image sémantique en utilisant un cnn (unet) en keras avec 7 étiquettes. Donc mon étiquette pour chaque image est (7, n_rows, n_cols) en utilisant le backend theano. Ainsi, sur les 7 couches pour chaque pixel, il est codé à chaud. Dans ce cas, la fonction d'erreur correcte est-elle d'utiliser une entropie croisée catégorique? Cela me semble être le cas, mais le réseau semble mieux apprendre avec la perte d'entropie croisée binaire. Quelqu'un peut-il nous expliquer pourquoi cela serait et quel est l'objectif de principe?

15
TSW

La perte d'entropie croisée binaire doit être utilisée avec l'activation de sigmod dans la dernière couche et pénalise sévèrement les prédictions opposées. Il ne tient pas compte du fait que la sortie est codée à chaud et que la somme des prédictions doit être 1. Mais comme les erreurs de prédiction pénalisent sévèrement, le modèle apprend quelque peu à se classer correctement.

Maintenant, pour appliquer la priorité du code one-hot, il faut utiliser l'activation softmax avec une entropie croisée catégorique. Voici ce que vous devez utiliser.

Le problème est maintenant d'utiliser le softmax dans votre cas car Keras ne prend pas en charge softmax sur chaque pixel.

La façon la plus simple de procéder consiste à permuter les dimensions vers (n_rows, n_cols, 7) en utilisant le calque Permute, puis de le remodeler en (n_rows * n_cols, 7) en utilisant le calque Reshape. Ensuite, vous pouvez ajouter la couche d'activation softmax et utiliser la perte de crossentopy. Les données doivent également être remodelées en conséquence.

L'autre façon de le faire sera d'implémenter depth-softmax:

def depth_softmax(matrix):
    sigmoid = lambda x: 1 / (1 + K.exp(-x))
    sigmoided_matrix = sigmoid(matrix)
    softmax_matrix = sigmoided_matrix / K.sum(sigmoided_matrix, axis=0)
    return softmax_matrix

et l'utiliser comme couche lambda:

model.add(Deconvolution2D(7, 1, 1, border_mode='same', output_shape=(7,n_rows,n_cols)))
model.add(Permute(2,3,1))
model.add(BatchNormalization())
model.add(Lambda(depth_softmax))

Si tfimage_dim_ordering est utilisé alors vous pouvez faire de la manière avec les couches Permute.

Pour plus de vérification des références ici .

15
indraforyou

J'ai testé la solution de @indraforyou et je pense que la méthode proposée comporte des erreurs. Comme la section de commentaires ne permet pas de segments de code appropriés, voici ce que je pense serait la version fixe:

def depth_softmax(matrix):

    from keras import backend as K

    exp_matrix = K.exp(matrix)
    softmax_matrix = exp_matrix / K.expand_dims(K.sum(exp_matrix, axis=-1), axis=-1)
    return softmax_matrix

Cette méthode s'attend à ce que l'ordre de la matrice soit (hauteur, largeur, canaux).

0
AljoSt