【问题标题】:How to fix the loss of transfer learning with Keras如何使用 Keras 修复迁移学习的损失
【发布时间】:2019-08-24 09:16:18
【问题描述】:

我正在使用自己的数据集对预训练模型进行迁移学习。 不久,我使用了具有 224x224 输入形状的预训练 resnet50 模型。我正在加载模型:

  train_datagen = ImageDataGenerator(validation_split=0.1,rescale=1./255,preprocessing_function=preprocess_input) # set validation split

    img_size = 224

    batch_size = 32

    train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_size, img_size),
        batch_size=batch_size,
        color_mode='rgb',
        subset='training') # set as training data

    validation_generator = train_datagen.flow_from_directory(
        train_data_dir, # same directory as training data
        target_size=(img_size, img_size),
        batch_size=batch_size,
        color_mode='rgb',
        subset='validation') # set as validation data


model = ResNet50(include_top=False, weights=None, input_shape=(224,224,3))
model.load_weights("a trained model weights on 224x224")

model.layers.pop()

for layer in model.layers:
   layer.trainable = False

x = model.layers[-1].output

x = Flatten(name='flatten')(x)
x = Dropout(0.2)(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(101, activation='softmax', name='pred_age')(x)

top_model = Model(inputs=model.input, outputs=predictions)

top_model.compile(loss='categorical_crossentropy',
        optimizer=adam,
        metrics=[accuracy])

EPOCHS = 100
BATCH_SIZE = 32
STEPS_PER_EPOCH = 4424 // BATCH_SIZE
VALIDATION_STEPS = 466 // BATCH_SIZE

callbacks = [LearningRateScheduler(schedule=Schedule(EPOCHS, initial_lr=lr_rate)),
                ModelCheckpoint(str(output_dir) + "/weights.{epoch:03d}-{val_loss:.3f}-{val_age_mae:.3f}.hdf5",
                                 monitor="val_age_mae",
                                 verbose=1,
                                 save_best_only=False,
                                 mode="min")
                 ]

hist = top_model.fit_generator(generator=train_set,
                               epochs=100,
                               steps_per_epoch = 4424//32,
                               validation_data=val_set,
                               validation_steps = 466//32,
                               verbose=1,
                               callbacks=callbacks)    

总参数:75,020,261 可训练参数:51,432,549 不可训练参数:23,587,712

纪元 1/100 140/140 [===============================] - 1033s 7s/步 - 损失:> 14.5776 - age_mae: 12.2994 - val_loss:15.6144 - val_age_mae:24.8527

Epoch 00001:val_age_mae 从 inf 提高到 24.85268,保存模型 > 纪元 2/100 140/140 [===============================] - 969s 7s/step - loss: 14.7104 - age_mae: 11.2545 - val_loss : 15.6462 - val_age_mae: 25.1104

TEpoch 00002:val_age_mae 没有从 24.85268 改进 TEpoch 3/100 T140/140 [===============================] - 769s 5s/step - loss: >T14.6159 - age_mae: 13.5181 - val_loss:15.7551 - val_age_mae:29.4640

Epoch 00003:val_age_mae 没有从 24.85268 改进 纪元 4/100 140/140 [===============================] - 815s 6s/步 - 损失:> 14.6509 - age_mae: 13.0087 - val_loss:15.9366 - val_age_mae:18.3581 纪元 00004:val_age_mae 从 24.85268 提高到 18.35811 纪元 5/100 140/140 [===============================] - 1059s 8s/步 - 损失:> > 14.3882 - age_mae: 11.8039 - val_loss:15.6825 - val_age_mae:24.6937

Epoch 00005:val_age_mae 没有从 18.35811 改进 时代 6/100 140/140 [===============================] - 1052s 8s/步 - 损失:> 14.4496 - age_mae: 13.6652 - val_loss:15.4278 - val_age_mae:24.5045 纪元 00006:val_age_mae 没有从 18.35811 改进

我已经运行了几次,在 epoch 4 之后它不再改进了。该数据集还包含大约 5000 张图像。 4511 幅图像属于训练集。 476 张图片属于验证集。

我得到以下损失图

【问题讨论】:

  • 很难说没有能够运行它。可能是您的验证数据集不代表您实际训练的样本(不平衡分类问题、训练集中存在的类而不是验证集中等)。也可能是您的模型过于复杂,并且以泛化为代价太适合训练数据集。如果是这种情况,您将需要降低模型复杂性。甚至可能是因为您忘记在将训练数据划分为验证集之前对其进行洗牌。我需要一个minimal reproducible example,但希望这会有所帮助。
  • 我在上面添加了如何将数据拆分为训练和验证集的部分。我的数据只是 101 个类别的图像。

标签: python keras neural-network conv-neural-network resnet


【解决方案1】:

这个问题发生在具有 BatchNormalization() 的预训练网络中,压力很大。相信我!逻辑是如果模型没有正确训练,BatchNormalization() 将破坏所有训练的权重,它会在反向传播过程中丢失所有内容。 我建议您尝试以这种方式加载模型:

model = ResNet50(include_top=False, weights=None, input_shape=(224,224,3))
model.trainable = False
inputs = keras.Input(shape=(224,224,3))
x = model(inputs, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dropout(0.5)(x) #if your model requires one.
outputs = keras.layers.Dense(num_classes, activation='softmax')(x)

然后你可以添加你选择的全连接层,然后收集整个模型的输出如下:

model = keras.Model(inputs,outputs)

如果你正在寻找进一步的解释,我建议你通过这个link.

然后,根据数据集,您可以通过冻结或解冻您想要的层数来继续训练模型。希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2020-05-13
    • 2018-05-11
    • 1970-01-01
    • 2021-01-23
    • 2018-11-13
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 2019-09-19
    相关资源
    最近更新 更多