1

J'utilise un AlexNet avec des poids pré-élevés (heuritech/convnets-keras) pour un problème de classification avec 8 classes au lieu de 1000. Après avoir initialisé le réseau avec Model(input=..,output=..) et en chargeant les poids initiaux, je laisse tomber le deux dernières couches, Dense (1000) et Activation (softmax), et ajoutez mes deux couches: Dense (8) et Activation (softmax). Mais, après l'exécution je reçois une erreurChangement de classification AlexNet pré-entraîné dans Keras

Error when checking model target: expected softmax to have shape (None, 1000) but got array with shape (32, 8) 

Le 32 est la taille du lot du générateur, je suppose, mais je ne comprends pas pourquoi le softmax attend encore 1000 dimensions de la couche précédente.

Quelqu'un peut-il m'aider? Je pense qu'il a quelque chose à faire pour le paramètre de sortie du modèle, mais ce n'est que deviner semi-sauvage après avoir essayé et googler. Merci!

code:

import ... 

pp = os.path.dirname(os.path.abspath(__file__)) 

##### Define Model ##### 
inputs = Input(shape=(3,227,227)) 
conv_1 = Convolution2D(96, 11, 11,subsample=(4,4),activation='relu', name='conv_1')(inputs) 
... 
... 
... 
dense_1 = MaxPooling2D((3, 3), strides=(2,2),name="convpool_5")(conv_5) 
dense_1 = Flatten(name="flatten")(dense_1) 
dense_1 = Dense(4096, activation='relu',name='dense_1')(dense_1) 
dense_2 = Dropout(0.5)(dense_1) 
dense_2 = Dense(4096, activation='relu',name='dense_2')(dense_2) 
dense_3 = Dropout(0.5)(dense_2) 
dense_3 = Dense(1000,name='dense_3')(dense_3) 
prediction = Activation("softmax",name="softmax")(dense_3) 

model = Model(input=inputs, output=prediction) 

for layer in model.layers[:27]: 
    print layer.name 
    layer.trainable = False 

model.load_weights(pp+"/weights/alexnet_weights.h5") 
print model.output_shape 

print model.layers[-1] 
model.layers.pop() 
print model.output_shape 
model.layers.pop() 
print model.layers[-1] 
print model.output_shape 
model.layers.append(Dense(8, activation='softmax',name='dense_4')) 

print model.layers[-1] 
##### Get Data ##### 
train_datagen = ImageDataGenerator(
     rescale=1./255, 
     shear_range=0.2, 
     zoom_range=0.2) 

test_datagen = ImageDataGenerator(rescale=1./255) 

train_generator = train_datagen.flow_from_directory(
     pp+'/dataset/training', 
     target_size=(227,227), 
     class_mode='categorical') 

validation_generator = test_datagen.flow_from_directory(
     pp+'/dataset/test', 
     target_size=(227,227), 
     class_mode='categorical') 

##### Compile and Fit #### 
sgd = SGD(lr=1e-4, decay=1e-6, momentum=0.9, nesterov=True) 
model.compile(optimizer=sgd, loss='mse') 

model.fit_generator(
     train_generator, 
     samples_per_epoch=500, 
     nb_epoch=5, 
     validation_data=validation_generator, 
     nb_val_samples=150) 

model.save_weights('first_try.h5') 

Répondre

3

Ok, il semble que je ne peux pas changer la définition du réseau, car même après popping/mettre de nouvelles couches, rien ne semble changer. donc je l'ai fait:

1) Load the default AlexNet 

2) Load the pre-trained weights 

3) Pop the 2 top layers 

4) Add two new top layers 

5) Save the weights 

6) Change Network definition to use the two new layers 

7) Load the new AlexNet with the saved weights 

8) Profit! 

Bien que je voudrais encore savoir comment changer un réseau chargé défini par l'api fonctionnelle.