未知度量函数:请确保将此对象传递给“custom_objects”参数

Unknown metric function: Please ensure this object is passed to the `custom_objects` argument

我已经使用迁移学习用 keras 训练了一个模型。由于整个代码几乎很大,我只带了重要的部分。

对于学习率,我从 github 克隆了一些能够使用循环学习率的代码。并将其作为回调传递给模型。

这是我定义学习率的方式。

from tensorflow.keras.optimizers import RMSprop

opt = RMSprop()
def get_lr_metric(optimizer):
    def lr(y_true, y_pred):
        return optimizer.lr
    return lr

lr_track = get_lr_metric(opt)

MIN_LR = 1e-7
MAX_LR = 1e-3
CLR_METHOD = "triangular"

clr = CyclicLR(
    mode= CLR_METHOD,
    base_lr= MIN_LR,
    max_lr= MAX_LR,
    step_size= steps_per_epoch)

和我的模特:

def vgg16_fine_tune():
    vgg16_model = VGG16(weights='imagenet', include_top=False)
    x = vgg16_model.output
    x = GlobalAveragePooling2D()(x)
    x = Dense(256, activation='relu')(x)
    x = Dropout(0.3)(x)
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.3)(x)
    x = Dense(128, activation='relu')(x)
    x = Dropout(0.3)(x)

    predictions = Dense(3, activation='softmax')(x)

    model = Model(inputs=vgg16_model.input, outputs=predictions)
    for layer in vgg16_model.layers:
        layer.trainable = False
        
    return model

model = vgg16_fine_tune()

我编译了我的代码:

import keras
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy' , lr_track, keras.metrics.Precision(), keras.metrics.Recall()])
history_2 = model.fit(datagen.flow(x_train, y_train),
                    epochs=20,
                    shuffle=True,
                    validation_data=(x_val, y_val),
                    callbacks=[chkpt, clr, es])


Epoch 1/20
188/188 [==============================] - 80s 416ms/step - loss: 0.5007 - accuracy: 0.8038 - lr: 4.4728e-06 - precision: 0.8275 - recall: 0.7711 - val_loss: 0.3959 - val_accuracy: 0.8560 - val_lr: 8.7048e-07 - val_precision: 0.8833 - val_recall: 0.8227
Epoch 2/20
188/188 [==============================] - 79s 423ms/step - loss: 0.4116 - accuracy: 0.8442 - lr: 4.8224e-06 - precision: 0.8660 - recall: 0.8215 - val_loss: 0.3621 - val_accuracy: 0.8700 - val_lr: 1.7400e-06 - val_precision: 0.8923 - val_recall: 0.8393
Epoch 3/20
188/188 [==============================] - 79s 421ms/step - loss: 0.3884 - accuracy: 0.8535 - lr: 5.1341e-06 - precision: 0.8775 - recall: 0.8331 - val_loss: 0.3529 - val_accuracy: 0.8767 - val_lr: 2.6094e-06 - val_precision: 0.8953 - val_recall: 0.8547
Epoch 4/20
188/188 [==============================] - 80s 423ms/step - loss: 0.3836 - accuracy: 0.8599 - lr: 5.4058e-06 - precision: 0.8809 - recall: 0.8407 - val_loss: 0.3452 - val_accuracy: 0.8767 - val_lr: 3.4789e-06 - val_precision: 0.8962 - val_recall: 0.8580
Epoch 5/20
188/188 [==============================] - 79s 419ms/step - loss: 0.3516 - accuracy: 0.8662 - lr: 5.6348e-06 - precision: 0.8857 - recall: 0.8448 - val_loss: 0.3324 - val_accuracy: 0.8780 - val_lr: 4.3484e-06 - val_precision: 0.8923 - val_recall: 0.8613
Epoch 6/20
188/188 [==============================] - 79s 422ms/step - loss: 0.3518 - accuracy: 0.8726 - lr: 5.8182e-06 - precision: 0.8905 - recall: 0.8487 - val_loss: 0.3378 - val_accuracy: 0.8733 - val_lr: 5.2179e-06 - val_precision: 0.8952 - val_recall: 0.8540
Epoch 7/20
188/188 [==============================] - 78s 413ms/step - loss: 0.3324 - accuracy: 0.8799 - lr: 5.9525e-06 - precision: 0.8955 - recall: 0.8649 - val_loss: 0.3393 - val_accuracy: 0.8740 - val_lr: 6.0873e-06 - val_precision: 0.8944 - val_recall: 0.8527
Epoch 8/20
188/188 [==============================] - 78s 417ms/step - loss: 0.3312 - accuracy: 0.8759 - lr: 6.0333e-06 - precision: 0.8936 - recall: 0.8549 - val_loss: 0.3149 - val_accuracy: 0.8920 - val_lr: 6.9568e-06 - val_precision: 0.9109 - val_recall: 0.8653

然后在拟合后我保存了它:

model.save_weights('model_weight.h5')
model.save('model_keras.h5')

但是当我需要加载我的模型并使用它时,我收到有关自定义对象的错误。

from tensorflow import keras
import os

model_dir = 'My Directory'
model1 = os.path.join(model_dir, "DenseNet_model_keras.h5")

Vgg16 = keras.models.load_model(model1)

这是我的错误:

ValueError: Unknown metric function: lr. Please ensure this object is passed to the custom_objects argument. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details.

我什至试过这段代码。

Vgg16 = keras.models.load_model(model1 , custom_objects={"lr": lr})

但我得到的只是

Vgg16 = keras.models.load_model(model1 , custom_objects={"lr": lr}) Traceback (most recent call last):

File "", line 1, in Vgg16 = keras.models.load_model(model1 , custom_objects={"lr": lr})

NameError: name 'lr' is not defined

有人可以帮我解决我的问题吗?

因为错误说你没有调用它lr,你调用了它

lr_tracklr_track = get_lr_metric(opt) 中,您从未定义 lr.

你需要这样称呼它:

Vgg16 = keras.models.load_model(model1 , custom_objects={"lr": lr_track })

您需要为自定义对象(此处为指标)使用与 model.compile() 中使用的关键字相同的关键字。

在这种情况下,你需要这样写:

keras.models.load_model(model1 , custom_objects={"lr_track": lr_track })