警告:自定义遮罩层需要配置,并且在 keras 中保存模型时必须覆盖

use*_*123 12 python keras tensorflow

我从顺序创建了一个模型。当我保存它时,我收到了这条警告消息

home/anaconda3/lib/python3.8/site-packages/tensorflow/python/keras/utils/generic_utils.py:494: CustomMaskWarning: Custom mask layers require a config and must override get_config. When loading, the custom mask layer must be passed to the custom_objects argument.
  warnings.warn('Custom mask layers require a config and must override 
Run Code Online (Sandbox Code Playgroud)

我测试了一张图像,预测结果很好,当我再次加载模型时,它开始给我错误的值,并且预测全部错误。模型和加载的正确方法是什么

import numpy as np 
import matplotlib.pyplot as plt
import glob
import cv2
import os
from tensorflow import keras

from tensorflow.keras.layers import Conv2D, MaxPooling2D
from tensorflow.keras.layers import Input, Dropout, Flatten, Dense

from tensorflow.keras.layers import UpSampling2D
from tensorflow.keras.models import Model
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.models import Sequential

input_shape = (3,1134,1134,3)
base_model = tf.keras.applications.ResNet50(
include_top=False,
weights="imagenet",
input_shape=(1134,1134,3),
pooling=max,  
)
for layer in base_model.layers[:-4]:
    layer.trainable = False
model = Sequential()
model.add(Conv2D(3,(3,3),activation='relu',padding='same'))
model.add(base_model)
model.add(Conv2D(3,(3,3),activation='relu',padding='same'))
# model.add(Convolution2D(3,(4,4),activation='relu',padding='same'))
model.add(UpSampling2D(size =(16,16)))
model.add(UpSampling2D())
model.add(BatchNormalization())
model.add(Conv2D(3,(3,3),activation='relu',padding='same'))
model.build(input_shape)
model.summary()
Run Code Online (Sandbox Code Playgroud)

这就是我保存它的方式

model.save("/media/TOSHIBA EXT/trained_model/UAV_01.h5")

enter code here

model=keras.models.load_model(
    "/media/TOSHIBA EXT/trained_model/UAV_01.h5")
Run Code Online (Sandbox Code Playgroud)

小智 5

@user123 同意你的观点,这是旧版本(TF2.5、TF2.6 和 TF2.7)的问题。

这个问题在最近的 tf-nightly 中得到了解决。这里有一个要点供参考。如果你想使用稳定版本,那么不久的将来将在即将发布的 TF2.8 中提供。谢谢!


Mik*_*omb 2

另外两种可以尝试的方法:

  1. 使用目录路径而不是以扩展名结尾的路径保存模型.h5。在幕后,save如果您发送以 结尾的路径,则会执行不同的操作.h5。如果您发送目录,它将使用较新的 SavedModel 格式。然后您可以直接加载模型:
from tensorflow.keras.models import load_model


new_model = load_model('<path to directory used in save>')
Run Code Online (Sandbox Code Playgroud)

https://www.tensorflow.org/guide/saved_model#the_savedmodel_format_on_disk

  1. 只保存权重。要加载模型,请使用当前的模型创建代码实例化该对象,然后将权重加载到空模型对象中。这曾经是唯一的办法!
from tensorflow.keras.models import load_model


new_model = load_model('<path to directory used in save>')
Run Code Online (Sandbox Code Playgroud)

参考: https: //keras.io/getting_started/faq/。仅节省重量

在常见问题解答中,还有一些关于如何处理它的其他建议,但对于您的情况,这两个可能会涵盖它。


这是一个很好的代码片段,可以在训练代码后添加,以确保导出有效并且不会导致推理时出现性能问题:

# From: https://www.tensorflow.org/guide/keras/save_and_serialize#whole-model_saving_loading
# Train the model.
test_input = np.random.random((128, 32))
test_target = np.random.random((128, 1))
model.fit(test_input, test_target)

# Calling `save('my_model')` creates a SavedModel folder `my_model`.
model.save("my_model")

# It can be used to reconstruct the model identically.
reconstructed_model = keras.models.load_model("my_model")

# Let's check:
np.testing.assert_allclose(
    model.predict(test_input), reconstructed_model.predict(test_input)
)

# The reconstructed model is already compiled and has retained the optimizer
# state, so training can resume:
reconstructed_model.fit(test_input, test_target)
Run Code Online (Sandbox Code Playgroud)