Keras — Модель обнаружения объектов — Xception против VGG

Я тренирую модель обнаружения объектов, используя предварительно обученные модели от Keras (VGG16, VGG19, Xception,...) на наборе данных из более чем 4000 изображений с координатами YOLO, ниже приведена часть, отвечающая за предварительную обработку данных для обучения и проверки данных. а также составление моделей и обучение.

Для VGG16 и VGG19 я изменяю размер изображений и координат YOLO до рекомендуемого размера изображения по умолчанию 224x224, тогда как для Xception и InceptionV3 я изменяю размер до 299x299.

Я замораживаю все слои приложения Keras и добавляю только 4 верхних слоя Dense, которые обучаются на моем наборе данных, чтобы использовать потенциал предварительно обученных моделей. Когда я использую VGG16 или VGG19, он работает хорошо, и я получил точность поезда и проверки более 92%, что отлично, и разделение поезд/значение кажется сбалансированным. Однако, когда я использую приложения Xception или InceptionV3, они всегда останавливаются раньше с точностью около 10%, чего я не понимаю.

      IMAGE_SIZE = (299, 299)

train_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)  # val 20%

val_datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)


train_data = train_datagen.flow_from_dataframe(
    dataframe=df_all, 
    directory=save_dir,                                               
    x_col="image_name", 
    y_col=['yolo_x', 'yolo_y', 'yolo_width', 'yolo_length'], 
    class_mode="raw", 
    target_size=IMAGE_SIZE,
    batch_size=32,
    shuffle=True,
    Subset='training'
)

val_data = val_datagen.flow_from_dataframe(
    dataframe=df_all, 
    directory=save_dir,                                               
    x_col="image_name", 
    y_col=['yolo_x', 'yolo_y', 'yolo_width', 'yolo_length'], 
    class_mode="raw", 
    target_size=IMAGE_SIZE,
    batch_size=32,
    shuffle=False,
    Subset='validation'
)

from tensorflow.keras.callbacks import ReduceLROnPlateau, EarlyStopping, ModelCheckpoint

learning_rate_reduction = ReduceLROnPlateau(monitor='loss', 
                                            patience=5, 
                                            verbose=2, 
                                            factor=0.5,                                            
                                            min_lr=0.000001)

early_stops = EarlyStopping(monitor='loss', 
                            min_delta=0, 
                            patience=10, 
                            verbose=2, 
                            mode='auto')

checkpointer = ModelCheckpoint(filepath = 'cis3115.{epoch:02d}-{accuracy:.6f}.hdf5',
                               verbose=2,
                               save_best_only=True, 
                               save_weights_only = True)


# Select a pre-trained model Xception
#pretrained_model = tf.keras.applications.VGG16(weights='imagenet', include_top=False ,input_shape=[*IMAGE_SIZE, 3])
pretrained_model = tf.keras.applications.Xception(weights='imagenet', include_top=False ,input_shape=[*IMAGE_SIZE, 3])

# Set the following to False so that the pre-trained weights are not changed 
pretrained_model.trainable = False 

model = Sequential()
model.add(pretrained_model)

# Flatten 2D images into 1D data for final layers like traditional neural network
model.add(Flatten())
model.add(Dense(128, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(32, activation='relu'))

# The final output layer
# Use Sigmoid when predicting YOLO bounding box since that output is between 0 and 1
model.add(Dense(4, activation='sigmoid'))


print ("Pretrained model used:")
pretrained_model.summary()

print ("Final model created:")
model.summary()

# Compile neural network model
model.compile(optimizer='adam', loss='mean_squared_error', metrics=['accuracy'])


# Train the model with the images in the folders
history = model.fit(
        train_data,
        validation_data=val_data,
        batch_size=16,                  # Number of image batches to process per epoch 
        epochs=100,                      # Number of epochs
        callbacks=[learning_rate_reduction, early_stops],
        )

Xception- это гораздо более сложная предварительно обученная модель, поэтому теоретически она должна быть более точной, поэтому я предполагаю, что делаю что-то неправильно при настройке CNN.

В чем причина того, что модели Xception/Inception терпят неудачу? Что мне следует изменить?

1 ответ

Проблема, похоже, в слое Flatten, и, поскольку он создавал огромное количество параметров, он постоянно терпел неудачу. Однако когда я заменил Flatten на GlobalAveragePooling2D, все заработало довольно хорошо.

Таким образом, я заменил это:

      model.add(Flatten())

Этим:

      model.add(GlobalAveragePooling2D())
Другие вопросы по тегам