Я использую AlexNet с предварительно обученными весами (heuritech / convnets-keras) для задачи классификации с 8 классами вместо 1000. После инициализации сети с помощью Model(input=..,output=..) и загрузки начальных весов я отбрасываю последние два слоя, Dense (1000) и Activation (softmax) и добавляю два моих собственных слоя: Dense (8) и Activation (softmax). Но потом после запуска выдает ошибку

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

Я предполагаю, что 32 - это размер пакета от генератора, но я не понимаю, почему softmax все еще ожидает 1000 измерений от предыдущего слоя.

Кто-нибудь может мне помочь? Я думаю, что у него есть что-то, что связано с выходным параметром модели, но это только полудикие догадки после попыток и поиска в Google. Спасибо!

Код:

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')
1
Rikku Porta 26 Июн 2016 в 22:53

1 ответ

Лучший ответ

Хорошо, похоже, я не могу просто изменить определение сети, потому что даже после добавления / добавления новых слоев ничего не меняется. Итак, я сделал это:

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!

Хотя мне все же хотелось бы знать, как изменить загруженную сеть, определяемую функциональным api.

3
Rikku Porta 27 Июн 2016 в 11:38
Возможно, мой ответ здесь может вам помочь :)
 – 
Joel Carneiro
9 Янв 2019 в 17:01