首页 文章

使用Keras微调ResNet50 - val_loss不断增加

提问于
浏览
2

我正在尝试使用具有张量流后端的keras来自定义resnet50 . 然而,在转换我的val_loss不断增加 . 尝试不同的学习率和批量大小并不能解决问题 .

在ImageDataGenerator中使用不同的预处理方法(如重新缩放或使用resnet50的preprocess_input函数)也无法解决问题 .

这是我正在使用的代码

导入和预处理数据:

from keras.preprocessing.image import ImageDataGenerator
from keras.applications.resnet50 import preprocess_input, decode_predictions

IMAGE_SIZE = 224
BATCH_SIZE = 32

num_classes = 27

main_path = "C:/Users/aaron/Desktop/DATEN/data"

gesamt_path = os.path.join(main_path, "ML_DATA")
labels = listdir(gesamt_path)

data_generator = ImageDataGenerator(#rescale=1./255, 
                                    validation_split=0.20,
                                   preprocessing_function=preprocess_input)

train_generator = data_generator.flow_from_directory(gesamt_path, target_size=(IMAGE_SIZE, IMAGE_SIZE), shuffle=True, seed=13,
                                                     class_mode='categorical', batch_size=BATCH_SIZE, subset="training")

validation_generator = data_generator.flow_from_directory(gesamt_path, target_size=(IMAGE_SIZE, IMAGE_SIZE), shuffle=False, seed=13,
                                                     class_mode='categorical', batch_size=BATCH_SIZE, subset="validation")

定义和训练模型

img_width = 224
img_height = 224 

model = keras.applications.resnet50.ResNet50()

classes = list(iter(train_generator.class_indices))
model.layers.pop()
for layer in model.layers:
    layer.trainable=False
last = model.layers[-1].output
x = Dense(len(classes), activation="softmax")(last)
finetuned_model = Model(model.input, x)
finetuned_model.compile(optimizer=Adam(lr=0.001), loss='categorical_crossentropy', metrics=['accuracy'])
for c in train_generator.class_indices:
    classes[train_generator.class_indices[c]] = c
finetuned_model.classes = classes



earlystopCallback = keras.callbacks.EarlyStopping(monitor='val_loss', min_delta=0, patience=8, verbose=1, mode='auto')
tbCallBack = keras.callbacks.TensorBoard(log_dir='./Graph', histogram_freq=0, write_graph=True, write_images=True)

history = finetuned_model.fit_generator(train_generator,
                    validation_data=validation_generator, 
                    epochs=85, verbose=1,callbacks=[tbCallBack,earlystopCallback])

3 回答

  • 0

    在您的训练中,您使用的是预训练模型( resnet50 ),仅更改最后一层,因为您只想预测几个类而不是预训练模型训练的1000个类(这就是转移学习的含义) .

    你冻结所有重量,你不会让你的模型训练 . 尝试:

    model = keras.applications.resnet50.ResNet50(include_top=False, pooling='avg')
    
    for layer in model.layers:
        layer.trainable=False
    last = model.output
    x = Dense(512, activation='relu')(last)
    x = Dropout(0.5)(x)
    #x = BatchNormalization()(x)
    x = Dense(512, activation='relu')(x)
    x = Dropout(0.5)(x)
    #x = BatchNormalization()(x)
    x = Dense(len(classes), activation="softmax")(x)
    

    您可以修改上面的代码,更改512个神经元,添加或不删除/ batchnormalization,使用尽可能多的密集层....

  • 0

    在Keras中有关于BN的“"problem"”(奇怪的设计),你的不良结果可能与this issue.有关

  • 1
    • 您需要匹配用于预训练网络的预处理,而不是您自己的预处理 . 仔细检查网络输入张量,即输入的通道平均值是否与用于预训练网络的数据的平均值相匹配 .

    • 可能是您的新数据与预训练网络使用的数据非常不同 . 在这种情况下,所有BN层都会将其预训练平均值/ var迁移到新值,因此也可能增加损失(但最终损失应该减少) .

相关问题