web-dev-qa-db-fra.com

Comment obtenir correctement les poids de couche de Conv2D en keras?

J'ai couche Conv2D définit comme:

Conv2D(96, kernel_size=(5, 5),
             activation='relu',
             input_shape=(image_rows, image_cols, 1),
             kernel_initializer=initializers.glorot_normal(seed),
             bias_initializer=initializers.glorot_uniform(seed),
             padding='same',
             name='conv_1')

C'est la première couche de mon réseau.
Les dimensions d'entrée sont de 64 par 160, l'image est de 1 canal.
J'essaie de visualiser les poids de cette couche convolutionnelle mais je ne sais pas comment les obtenir.
Voici comment je le fais maintenant:

1.Appel

layer.get_weights()[0]

Ceci reprend un tableau de forme (5, 5, 1, 96). 1 est parce que les images sont 1 canal.

2.Prendre 5 par 5 filtres par

layer.get_weights()[0][:,:,:,j][:,:,0]

Très moche mais je ne sais pas comment simplifier cela, tous les commentaires sont très appréciés.

Je ne suis pas sûr dans ces 5 par 5 carrés. Sont-ils des filtres en réalité?
Sinon, veuillez vous indiquer comment récupérer correctement les filtres du modèle.

7

J'ai essayé d'afficher les poids comme si seulement les 25 premiers. J'ai la même question que vous posez est-ce le filtre ou autre chose. Il ne semble pas que ce soit les mêmes filtres que ceux dérivés de réseaux de croyance profonds ou de RBM empilés.

Voici les poids visualisés non entraînés:  untrained weights

et voici les poids entraînés:

 trained weights

Étrangement, il n'y a pas de changement après l'entraînement! Si vous les comparez, ils sont identiques.

puis le RBN DBN filtre la couche 1 en haut et la couche 2 en bas:  DBM RBM filters

Si je mets kernel_intialization = "ones", les filtres paraissent bien mais la perte nette ne diminue jamais avec de nombreux changements d'essai et d'erreur:  enter image description here

Voici le code pour afficher les poids/filtres de conv en 2D.

  ann = Sequential()
  x = Conv2D(filters=64,kernel_size=(5,5),input_shape=(32,32,3))
  ann.add(x)
  ann.add(Activation("relu"))

...

  x1w = x.get_weights()[0][:,:,0,:]
  for i in range(1,26):
      plt.subplot(5,5,i)
      plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
  plt.show()

  ann.fit(Xtrain, ytrain_indicator, epochs=5, batch_size=32)

  x1w = x.get_weights()[0][:,:,0,:]
  for i in range(1,26):
      plt.subplot(5,5,i)
      plt.imshow(x1w[:,:,i],interpolation="nearest",cmap="gray")
  plt.show()

---------------------------METTRE À JOUR---------------------- -

Je l'ai donc réessayé avec un taux d'apprentissage de 0,01 au lieu de 1e-6 et ai utilisé les images normalisées entre 0 et 1 au lieu de 0 et 255 en divisant les images par 255,0. Maintenant, les filtres de convolution changent et la sortie du premier filtre de convolution ressemble à ceci:  Untrained Weights

Le filtre qualifié que vous remarquerez est modifié (pas beaucoup) avec un taux d’apprentissage raisonnable:  Trained Convolution Filter

Voici la septième image de l’ensemble de tests de l’ICRA-10:  Image 7 CIFAR-10 Car

Et voici la sortie de la première couche de convolution:  Convolution Layer Output

Et si je prends la dernière couche de convolution (aucune couche dense entre les deux) et que je la transmets à un classifieur non entraîné, cela revient à classer les images brutes en termes de précision, mais si j'entraîne les couches de convolution, la dernière sortie de couche de convolution augmente classificateur (forêt aléatoire).

Je conclurais donc que les couches de convolution sont des filtres et des poids.

10
John

Dans layer.get_weights () [0] [:,:,::::], les dimensions entre [:,:,:,:] sont x la position du poids, la position y du poids, la n e entrée dans le couche conv correspondante (provenant de la couche précédente, notez que si vous essayez d'obtenir les poids de la première couche conv, ce nombre est égal à 1 car une seule entrée est pilotée vers la première couche conv) et k-filtre ou noyau dans la couche correspondante. , respectivement. Ainsi, la forme de tableau renvoyée par layer.get_weights () [0] peut être interprétée comme si une seule entrée était dirigée vers la couche et que 96 filtres de taille 5x5 étaient générés. Si vous voulez atteindre l'un des filtres, vous pouvez taper, disons le 6ème filtre Print (layer.get_weights () [0] [:,:,:, 6] .squeeze ()). Cependant, si vous avez besoin des filtres de la deuxième couche de conv (voir le lien image modèle ci-joint), alors notez que pour chacune des 32 images ou matrices d’entrée, vous aurez 64 filtres. Si vous souhaitez obtenir les poids de l'un d'eux, par exemple les poids du 4ème filtre généré pour la 8ème image d'entrée, vous devez taper Print (layer.get_weights () [0] [:,::, 8 , 4] .squeeze ()). entrez la description de l'image ici

0
Cagri Kaplan