В рамках проекта классификации изображений (кошки и собаки) я пытаюсь удалить последние слои предварительно обученной сети и заменить их слоем xgboost. Точнее, объекты извлекаются из предварительно обученной модели без последних слоев, а затем эти объекты отправляются в слой xgboost. Проблема в том, что эта новая модель дает точность не более 50%, в то время как первоначальная предварительно обученная модель дает точность 88%. Я хотел бы знать, что я делаю не так?
def load_pretrained_model(image_size=(IMG_HEIGHT,IMG_WIDTH,3)):
# generate VGG16 with all layers, without top (no classifier, meaning include_top equals to False), and also set the weights equal to 'imagenet'
pre_trained_model = VGG16(weights='imagenet', include_top=False, input_shape=(IMG_HEIGHT,IMG_WIDTH,3))
# freeze the layers except the last 2 layers (re-train the last two), meaning that you want to keep all the layers of the pretrained model except the last two
for layer in pre_trained_model.layers[:-3]:
layer.trainable = False
# check the trainable status of the individual layers
for layer in pre_trained_model.layers:
print(layer,layer.trainable)
# create a sequential model
pre_trained_model.summary()
model = Sequential()
# add the model you just transferred
model.add(pre_trained_model)
# add new layers (flatten, dense, dropout and then again, dense)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
# show a summary of the model. Check the number of trainable parameters
model.summary()
# use the params of the former model
model.compile(# set the loss to binary_crossentropy
loss='binary_crossentropy',
# set the optimizer to the one you import
optimizer=RMSprop(lr=1e-4),
# set the metrics to accuracy ('acc')
metrics=['acc'])
return model
new_vggmodel = load_pretrained_model(image_size=(IMG_HEIGHT,IMG_WIDTH,3))
history = new_vggmodel.fit_generator(
# set the generator to the train_data_generator
train_data_generator,
# as a rule of thumb, you can use the total number of pictures in the train test and doing a floor division with the batch size
steps_per_epoch= total_train // batch_size,
epochs=epochs,
# set the generator to the test_data_generator
validation_data=test_data_generator,
# same as above, but replace the train set by the test set
validation_steps= total_test // batch_size)
layer_name = 'dense'
FC_layer_model = Model(inputs=new_vggmodel.input,
outputs=new_vggmodel.get_layer(layer_name).output)
FC_layer_model.summary()
FC_layer_model.compile(# set the loss to binary_crossentropy
loss='binary_crossentropy',
# set the optimizer to the one you import
optimizer=RMSprop(lr=1e-4),
# set the metrics to accuracy ('acc')
metrics=['acc'])
train_features=np.zeros(shape=(total_train,256))
train_data_generator.reset() # reset the generator before predict
FC_output = FC_layer_model.predict_generator(train_data_generator,verbose=1)
train_features=FC_output
test_features=np.zeros(shape=(total_test,256))
test_data_generator.reset() # reset the generator before predict
FC_output = FC_layer_model.predict_generator(test_data_generator,verbose=1)
test_features=FC_output
params = {"objective":"binary:logistic", "max_depth":5,"learning_rate":0.1, "min_child_weight":1,"gamma":0,"subsample":0.8,"colsample_bytree":0.8,
"nthread":4,"scale_pos_weight":1}
dtrain = xgb.DMatrix(data=train_features, label=train_data_generator.labels)
cv_results = xgb.cv(dtrain=dtrain, params=params, nfold=3, num_boost_round=20, metrics="error", as_pandas=True, seed=123) #verbose ne marche pas
print(cv_results)
xg_cl=xgb.XGBClassifier(learning_rate =0.1,n_estimators=20,max_depth=5,min_child_weight=1,gamma=0,subsample=0.8,colsample_bytree=0.8,objective= 'binary:logistic',
nthread=4,scale_pos_weight=1,seed=27)
xg_cl.fit(train_features, train_data_generator.labels)
preds=xg_cl.predict(test_features)
accuracy = float(np.sum(preds==test_data_generator.labels))/test_data_generator.labels.shape[0]
print("accuracy: %f" % (accuracy))