web-dev-qa-db-fra.com

Comment ajouter et supprimer de nouvelles couches dans keras après le chargement de poids?

J'essaie de faire un apprentissage par transfert; à cette fin, je souhaite supprimer les deux dernières couches du réseau de neurones et en ajouter deux autres. Ceci est un exemple de code qui génère également la même erreur.

from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model

in_img = Input(shape=(3, 32, 32))
x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
x = Activation('relu', name='relu_conv2')(x)
x = GlobalAveragePooling2D()(x)
o = Activation('softmax', name='loss')(x)
model = Model(input=in_img, output=[o])
model.compile(loss="categorical_crossentropy", optimizer="adam")
#model.load_weights('model_weights.h5', by_name=True)
model.summary()

model.layers.pop()
model.layers.pop()
model.summary()
model.add(MaxPooling2D())
model.add(Activation('sigmoid', name='loss'))

J'ai enlevé le calque en utilisant pop() mais quand j'ai essayé d'ajouter sa sortie cette erreur

AttributeError: l'objet 'Model' n'a pas d'attribut 'add'

Je sais que la raison la plus probable de l'erreur est l'utilisation incorrecte de model.add(). Quelle autre syntaxe dois-je utiliser?

EDIT:

J'ai essayé de supprimer/ajouter des couches dans keras mais cela ne lui permet pas d'être ajouté après le chargement de poids externes.

from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model
in_img = Input(shape=(3, 32, 32))

def gen_model():
    in_img = Input(shape=(3, 32, 32))
    x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
    x = Activation('relu', name='relu_conv1')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
    x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
    x = Activation('relu', name='relu_conv2')(x)
    x = GlobalAveragePooling2D()(x)
    o = Activation('softmax', name='loss')(x)
    model = Model(input=in_img, output=[o])
    return model

#parent model
model=gen_model()
model.compile(loss="categorical_crossentropy", optimizer="adam")
model.summary()

#saving model weights
model.save('model_weights.h5')

#loading weights to second model
model2=gen_model()
model2.compile(loss="categorical_crossentropy", optimizer="adam")
model2.load_weights('model_weights.h5', by_name=True)

model2.layers.pop()
model2.layers.pop()
model2.summary()

#editing layers in the second model and saving as third model
x = MaxPooling2D()(model2.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)
model3 = Model(input=in_img, output=[o])

sa montrant cette erreur

RuntimeError: Graph disconnected: cannot obtain value for tensor input_4 at layer "input_4". The following previous layers were accessed without issue: []
32
Eka

Vous pouvez prendre le output du dernier modèle et créer un nouveau modèle. Les couches inférieures restent les mêmes.

model.summary()
model.layers.pop()
model.layers.pop()
model.summary()

x = MaxPooling2D()(model.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)

model2 = Model(input=in_img, output=[o])
model2.summary()

Vérifier Comment utiliser les modèles de keras.applications pour un transfert d’apprentissage?

Mise à jour sur Edit:

La nouvelle erreur est due au fait que vous essayez de créer le nouveau modèle sur le global in_img Qui n’est en fait pas utilisé lors de la création du modèle précédent. Vous définissez donc un in_img Local. Donc le global in_img N'est évidemment pas connecté aux couches supérieures du graphe symbolique. Et cela n’a rien à voir avec le chargement de poids.

Pour mieux résoudre ce problème, utilisez plutôt model.input Pour faire référence à l'entrée.

model3 = Model(input=model2.input, output=[o])

43
indraforyou

Une autre façon de le faire

from keras.models import Model

layer_name = 'relu_conv2'
model2= Model(inputs=model1.input, outputs=model1.get_layer(layer_name).output)
9
Wesam Na