1

Ich benutze ein AlexNet mit vortrainierten Gewichten (Heuritech/Convnets-Keras) für ein Klassifikationsproblem mit 8 Klassen statt 1000. Nach der Initialisierung des Netzwerks mit Model(input=..,output=..) und dem Laden der Anfangsgewichte, lasse ich die Letzte zwei Schichten, Dichte (1000) und Aktivierung (Softmax), und füge meine eigenen zwei Schichten hinzu: Dichte (8) und Aktivierung (Softmax). Aber dann, nach dem Laufen bekomme ich einen FehlerVoreingebaute AlexNet-Klassifizierung in Keras ändern

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

Die 32 ist die Losgröße vom Generator ich denke, aber ich verstehe nicht, warum die softmax noch 1000 Dimensionen von der vorherige Schicht erwartet.

Kann mir jemand helfen? Ich denke, es hat etwas mit dem Ausgabeparameter des Modells zu tun, aber das ist nur ein halb wildes Raten, nachdem ich es versucht und gegoogelt habe. Danke!

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') 

Antwort

3

Ok, scheint es, dass ich nicht nur die Netzwerk-Definition ändern, denn auch nach popping/Putting neuen Schichten in, nichts zu ändern scheint. Also tat ich dies:

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! 

Obwohl würde ich noch gerne wissen, wie ein geladenes Netzwerk durch die funktionale api eingestellt worden ist.