使用 Resnet152 训练模型,保存权重,加载它们并添加更多层问题

Training a model with Resnet152, saving the weights, loading them and adding more layers issue

我的目标是首先仅使用 ResNet152 进行训练,然后保存学习到的权重。然后我想将这些权重用作具有附加层的更复杂模型的基础,我最终想对其进行超参数调整。采用这种方法的原因是一次完成所有操作需要很长时间。我遇到的问题是我的代码似乎不起作用。我没有收到错误消息,但是当我开始训练更复杂的模型时,它似乎又从 0 开始并且没有使用学习的 ResNet152 权重。

代码如下:

首先我只使用 ResNet152 和输出层

input_tensor = Input(shape=train_generator.image_shape)

base_model = applications.ResNet152(weights='imagenet', include_top=False, input_tensor=input_tensor)

for layer in base_model.layers[:]:
   layer.trainable = True¨

x = Flatten()(base_model.output)
  
predictions = Dense(num_classes, activation= 'softmax')(x)

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

model.compile(
  loss='sparse_categorical_crossentropy',
  optimizer=opt,
  metrics=['accuracy'])

model.fit(
  train_generator,
  validation_data=valid_generator,
  epochs=epochs,
  steps_per_epoch=len_train // batch_size,
  validation_steps=len_val // batch_size,
  callbacks=[earlyStopping, reduce_lr]
)

那我在保存权重:

model.save_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights.h5')

添加更多层。


input_tensor = Input(shape=train_generator.image_shape)

base_model = applications.ResNet152(weights='imagenet', include_top=False, input_tensor=input_tensor)

for layer in base_model.layers[:]:
    layer.trainable = False 

x = Flatten()(base_model.output)
 
x = Dense(1024, kernel_regularizer=tf.keras.regularizers.L2(l2=0.01), 
          kernel_initializer=tf.keras.initializers.HeNormal(), 
          kernel_constraint=tf.keras.constraints.UnitNorm(axis=0))(x)
x = LeakyReLU()(x)
x = BatchNormalization()(x)
x = Dropout(rate=0.1)(x)
x = Dense(512, kernel_regularizer=tf.keras.regularizers.L2(l2=0.01), 
          kernel_initializer=tf.keras.initializers.HeNormal(), 
          kernel_constraint=tf.keras.constraints.UnitNorm(axis=0))(x)
x = LeakyReLU()(x)
x = BatchNormalization()(x)
  
predictions = Dense(num_classes, activation= 'softmax')(x)
model = Model(inputs = base_model.input, outputs = predictions)

根据 keras 教程,在添加层后加载权重并使用 by_name=True。

model.load_weights('/content/drive/MyDrive/MODELS_SAVED/model_RESNET152/model_weights.h5', by_name=True)

那我又开始训练了

model.compile(
    loss='sparse_categorical_crossentropy',
    optimizer=opt,
    metrics=['accuracy']
    )

model.fit(
  train_generator,
  validation_data=valid_generator,
  epochs=epochs,
  steps_per_epoch=len_train // batch_size,
  validation_steps=len_val  // batch_size,
  callbacks=[earlyStopping, reduce_lr]
)

但它的开始精度非常低,基本上又是从 0 开始,所以我猜这里有问题。关于如何解决这个问题有什么想法吗?

当您使用 adam 并仅保存模型权重时 - 您还必须 save/load 优化器权重:

  weight_values = model.optimizer.get_weights()
  with open(output_path+'optimizer.pkl', 'wb') as f:
      pickle.dump(weight_values, f)

  dummy_input = tf.random.uniform(inp_shape) # create a tensor of input shape
  dummy_label = tf.random.uniform(label_shape) # create a tensor of label shape
  hist = model.fit(dummy_input, dummy_label)
  with open(path_to_saved_model+'optimizer.pkl', 'rb') as f:
      weight_values = pickle.load(f)
  optimizer.set_weights(weight_values)