web-dev-qa-db-fra.com

Remodelage des couches Keras

J'ai une image d'entrée 416x416. Comment puis-je créer une sortie de 4 x 10, où 4 est le nombre de colonnes et 10 le nombre de lignes?

Mes données d'étiquette sont un tableau 2D avec 4 colonnes et 10 lignes.

Je connais la méthode reshape() mais elle nécessite que la forme résultante ait le même nombre d'éléments que l'entrée.

Avec une taille d'entrée de 416 x 416 et des couches de pools maximum, je peux obtenir un maximum de 13 x 13 sortie.

Existe-t-il un moyen d'atteindre 4x10 sortie sans perte de données?

Mes données d'étiquette d'entrée ressemblent par exemple à

[[  0   0   0   0]
 [  0   0   0   0]
 [  0   0   0   0]
 [  0   0   0   0]
 [  0   0   0   0]
 [  0   0   0   0]
 [  0   0   0   0]
 [116  16 128  51]
 [132  16 149  52]
 [ 68  31  77  88]
 [ 79  34  96  92]
 [126  37 147 112]
 [100  41 126 116]]

Ce qui indique qu'il y a 6 objets sur mes images que je veux détecter, la première valeur est xmin, deuxième ymin, troisième xmax, quatrième ymax.

La dernière couche de mes réseaux ressemble

(None, 13, 13, 1024)
7
Darlyn

Je pense que le moyen le plus simple de conformer la forme de vos prédictions à la sortie souhaitée est la solution proposée par @Darlyn. En supposant que le réseau que vous avez jusqu'à présent a été déclaré (qui génère des tenseurs de forme (13, 13, 1024)) comme ceci:

x = Input(shape=(416, 416, 3))
y = Conv2D(32, activation='relu')(x)
...
y = Conv2D(1024, activation='relu')(y)

Il vous suffit d'ajouter une couche de régression qui tentera de prédire les cases, puis de les remodeler en (10, 4):

from keras.layers import Flatten, Dense, Reshape

samples = 1
boxes = 10

y = Flatten(name='flatten')(model.outputs)
y = Dense(boxes * 4, activation='relu')(y)
y = Reshape((boxes, 4), name='predictions')(y)
model = Model(inputs=model.inputs, outputs=y)

x_train = np.random.randn(samples, 416, 416, 3)

p = model.predict(x_train)
print(p.shape)

(1, 10, 4)

Cela fonctionne, mais je ne suis pas sûr que la régression directe de ces valeurs produira de bons résultats. Je vois généralement des modèles de détection d'objets utilisant l'attention, la région ou la saillance pour déterminer la position des objets. Il existe quelques implémentations de kéros de détection d'objets que vous pouvez essayer:

keras-rcnn

classes = ["dog", "cat", "hooman"]

backbone = keras_rcnn.models.backbone.VGG16
model = keras_rcnn.models.RCNN((416, 416, 3), classes, backbone)
boxes, predictions = model.predict(x)

keras-retinanet

from keras_retinanet.models.resnet import resnet_retinanet

x = Input(shape=(416, 416, 3))
model = resnet_retinanet(len(classes), inputs=x)
_, _, boxes, _ = model.predict_on_batch(inputs)
1
ldavid

Aplatissez d'abord le calque (None, 13, 13, 1024)

model.add(Flatten())

cela donnera 13*13*1024=173056

Tenseur 1 dimensionnel

Ajoutez ensuite une couche dense

model.add(Dense(4*10)) il sortira à 40

cela transformera votre forme 3D en 1D

puis redimensionnez simplement selon vos besoins

model.add(Reshape(4,10))

Cela fonctionnera mais détruira absolument la nature spatiale de vos données

1
Atta Jutt