2017-10-16 4 views
1

Je veux construire un CNN en Keras avec une couche softmax comme une sortie, mais je reçois seulement cela comme une sortie:couche Softmax dans Keras retourne un vecteur de 1s

[[[[ 1.] 
    [ 1.] 
    [ 1.]]]] 

Mon modèle est construit comme celui-ci :

model = Sequential() 
model.add(Conv2D(2, (1,3), padding='valid', 
      input_shape=(3,3,50), init='normal', data_format='channels_first')) 
model.add(Activation('relu')) 
model.add(Conv2D(20, (1,48), init='normal', data_format='channels_first')) 
model.add(Activation('relu')) 
model.add(Conv2D(1, (1, 1), init='normal', data_format='channels_first', activation='softmax')) 

Je ne comprends pas vraiment, pourquoi softmax ne fonctionne pas. Est-ce peut-être à cause d'une mauvaise forme d'entrée?

Répondre

0

Vous avez un problème avec l'architecture de votre modèle. Si vous regardez quelques-uns des modèles populaires:

Vous trouverez que la structure d'un CNN ressemble généralement à ceci:

  1. Certains convolutionnel couches avec activation relu
  2. Couche de mise en commun (c.-à-d. mise en pool max, mise en pool moyenne, etc.)
  3. plat la couche de convolution
  4. Une couche dense
  5. Ensuite, un softmax

Il n'a pas de sens d'appliquer une softmax à une couche convolutionnel.

+0

Merci, j'ai essayé d'ajouter une couche dense après la couche convolutionnelle, mais sans l'aplatir. Maintenant ça marche! – Eskahndor

+1

Softmax dans les couches convolu- tionnelles (sommation des voies 1) est une bonne idée pour les tâches de segmentation d'image, où chaque canal est une classe. –

1

L'activation softmax sera appliquée au dernier axe.

En regardant votre model.summary(), votre forme de sortie est (None, 3, 3, 1).

Avec un seul élément sur le dernier axe, votre sortie softmax sera toujours égale à 1.

Vous devez sélectionner l'axe que vous voulez ajouter 1, puis reformater correctement la sortie. Par exemple, si vous voulez que le softmax à considérer les 3 canaux, vous devez déplacer ces canaux à la position finale:

#your last convolutional layer, without the activation: 
model.add(Conv2D(3, (1, 1), kernel_initializer='normal', data_format='channels_first')) 

#a permute layer to move the channels to the last position: 
model.add(Permute((2,3,1))) 

#the softmax, now considering that channels sum 1. 
model.add(Activation('softmax')) 

Mais si votre but est que tout le résultat résume 1, alors vous devriez ajouter un Flatten() au lieu d'un Permute(). Keras semble être plus approprié pour travailler avec channels_last. Dans ce cas, le softmax serait automatiquement appliqué aux canaux, sans travail supplémentaire nécessaire.