加载 keras 模型,TypeError:“模块”对象不可调用

Posted

技术标签:

【中文标题】加载 keras 模型,TypeError:“模块”对象不可调用【英文标题】:loading keras model, TypeError: 'module' object is not callable 【发布时间】:2021-10-24 05:42:58 【问题描述】:

我已经搜索了 *** 并阅读了文档,但不知何故我的训练模型仍然没有被加载! 我已经检查了以下链接以及更多内容,因此请不要立即将其标记为重复。谢谢

    How to save final model using keras? https://www.tensorflow.org/guide/keras/save_and_serialize https://www.tensorflow.org/tutorials/distribute/save_and_load https://www.tensorflow.org/guide/keras/functional How to load a model from an HDF5 file in Keras?

这是我的模型:

def get_model(train=True):
    
    set_seed(33)
    
    pre_process = Lambda(preprocess_input)
    vgg = VGG16(weights = 'imagenet', include_top = True, input_shape = SHAPE)
    vgg = Model(vgg.input, vgg.layers[-3].output)
    vgg.trainable = False
    
    inp = Input(SHAPE)
    vgg_16_process = pre_process(GaussianNoise(0.1)(inp))
    vgg_out = vgg(vgg_16_process)
    
    noise = Lambda(tf.zeros_like)(vgg_out)
    noise = GaussianNoise(0.1)(noise)

    if train:
        x = Lambda(lambda z: tf.concat(z, axis=0))([vgg_out,noise])
        x = Activation('relu')(x)
    else:
        x = vgg_out
        
    x = Dense(512, activation='relu')(x)
    x = Dense(128, activation='relu')(x)
    out = Dense(2, activation='softmax')(x)

    model = Model(inp, out)
    model.compile(Adam(learning_rate=1e-4), loss='binary_crossentropy')
    
    return model

然后我有一些测试和训练生成器如下, 数据集是经典的狗对猫数据集,我正在尝试实现一类分类任务。


train_datagen = ImageDataGenerator()
test_datagen = ImageDataGenerator()

train_generator = train_datagen.flow_from_directory(
            base_path + 'training_set/training_set/',
            target_size = (SHAPE[0], SHAPE[1]),
            batch_size = batch_size,
            class_mode = 'categorical',
            shuffle = True,
            seed = 33,
            classes = ['cats']
    )

test_generator = test_datagen.flow_from_directory(
            base_path + 'test_set/test_set/',
            target_size = (SHAPE[0], SHAPE[1]),
            batch_size = batch_size,
            class_mode = 'categorical',
            shuffle = True,
            seed = 33,
            classes = ['dogs','cats']
)

最后,我编译模型

model = get_model()
model.fit(wrap_generator(train_generator), steps_per_epoch=train_generator.samples/train_generator.batch_size, epochs=1)

然后我按如下方式保存模型

model.save('my_custom_model')

我以该格式保存或“my_custom_model.h5”保存完美,没有任何错误。 如果我只使用保存,则会创建一个包含“资产、变量、.pb 文件”的文件夹,正如 *** 的帖子中提到的那样。

** 那么问题来了**

from keras.models import load_model
loaded_model = load_model('my_custom_model.h5')
#or 
loaded_model = tf.keras.models.load_model('my_custom_model.h5')
#or 
loaded_model = load_model('my_custom_model') # as from folder

都抛出相同的错误

TypeError:“模块”对象不可调用

我知道我犯了一些错误或模型有点不同,请引导我找到正确的方向,我可以在那里寻找解决方案。

Python:3.7.2 张量流:2.6.0 Keras:2.6.0

全栈跟踪

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\ops\array_ops.py in wrapper(*args, **kwargs)
    205     try:
--> 206       return target(*args, **kwargs)
    207     except (TypeError, ValueError):

TypeError: 'str' object is not callable

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-10-cd6655ece7c5> in <module>
      7 # loaded_model = tf.keras.models.load_model("my_custom_model2")
      8 
----> 9 loaded_model = tf.keras.models.load_model('model_notebook.h5')
     10 # print(loaded_model)
     11 # print("------------")

~\AppData\Roaming\Python\Python37\site-packages\keras\saving\save.py in load_model(filepath, custom_objects, compile, options)
    199             (isinstance(filepath, h5py.File) or h5py.is_hdf5(filepath))):
    200           return hdf5_format.load_model_from_hdf5(filepath, custom_objects,
--> 201                                                   compile)
    202 
    203         filepath = path_to_string(filepath)

~\AppData\Roaming\Python\Python37\site-packages\keras\saving\hdf5_format.py in load_model_from_hdf5(filepath, custom_objects, compile)
    179     model_config = json_utils.decode(model_config)
    180     model = model_config_lib.model_from_config(model_config,
--> 181                                                custom_objects=custom_objects)
    182 
    183     # set weights

~\AppData\Roaming\Python\Python37\site-packages\keras\saving\model_config.py in model_from_config(config, custom_objects)
     50                     '`Sequential.from_config(config)`?')
     51   from keras.layers import deserialize  # pylint: disable=g-import-not-at-top
---> 52   return deserialize(config, custom_objects=custom_objects)
     53 
     54 

~\AppData\Roaming\Python\Python37\site-packages\keras\layers\serialization.py in deserialize(config, custom_objects)
    210       module_objects=LOCAL.ALL_OBJECTS,
    211       custom_objects=custom_objects,
--> 212       printable_module_name='layer')

~\AppData\Roaming\Python\Python37\site-packages\keras\utils\generic_utils.py in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
    676             custom_objects=dict(
    677                 list(_GLOBAL_CUSTOM_OBJECTS.items()) +
--> 678                 list(custom_objects.items())))
    679       else:
    680         with CustomObjectScope(custom_objects):

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\functional.py in from_config(cls, config, custom_objects)
    661     with generic_utils.SharedObjectLoadingScope():
    662       input_tensors, output_tensors, created_layers = reconstruct_from_config(
--> 663           config, custom_objects)
    664       model = cls(inputs=input_tensors, outputs=output_tensors,
    665                   name=config.get('name'))

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\functional.py in reconstruct_from_config(config, custom_objects, created_layers)
   1281       if layer in unprocessed_nodes:
   1282         for node_data in unprocessed_nodes.pop(layer):
-> 1283           process_node(layer, node_data)
   1284 
   1285   input_tensors = []

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\functional.py in process_node(layer, node_data)
   1229         input_tensors = (
   1230             base_layer_utils.unnest_if_single_tensor(input_tensors))
-> 1231       output_tensors = layer(input_tensors, **kwargs)
   1232 
   1233       # Update node index map.

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\base_layer.py in __call__(self, *args, **kwargs)
    975     if _in_functional_construction_mode(self, inputs, args, kwargs, input_list):
    976       return self._functional_construction_call(inputs, args, kwargs,
--> 977                                                 input_list)
    978 
    979     # Maintains info about the `Layer.call` stack.

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\base_layer.py in _functional_construction_call(self, inputs, args, kwargs, input_list)
   1113       # Check input assumptions set after layer building, e.g. input shape.
   1114       outputs = self._keras_tensor_symbolic_call(
-> 1115           inputs, input_masks, args, kwargs)
   1116 
   1117       if outputs is None:

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\base_layer.py in _keras_tensor_symbolic_call(self, inputs, input_masks, args, kwargs)
    846       return tf.nest.map_structure(keras_tensor.KerasTensor, output_signature)
    847     else:
--> 848       return self._infer_output_signature(inputs, args, kwargs, input_masks)
    849 
    850   def _infer_output_signature(self, inputs, args, kwargs, input_masks):

~\AppData\Roaming\Python\Python37\site-packages\keras\engine\base_layer.py in _infer_output_signature(self, inputs, args, kwargs, input_masks)
    886           self._maybe_build(inputs)
    887           inputs = self._maybe_cast_inputs(inputs)
--> 888           outputs = call_fn(inputs, *args, **kwargs)
    889 
    890         self._handle_activity_regularization(inputs, outputs)

~\AppData\Roaming\Python\Python37\site-packages\keras\layers\core.py in call(self, inputs, mask, training)
    901     with tf.GradientTape(watch_accessed_variables=True) as tape,\
    902         tf.variable_creator_scope(_variable_creator):
--> 903       result = self.function(inputs, **kwargs)
    904     self._check_variables(created_variables, tape.watched_variables())
    905     return result

~\AppData\Roaming\Python\Python37\site-packages\tensorflow\python\ops\array_ops.py in wrapper(*args, **kwargs)
    208       # Note: convert_to_eager_tensor currently raises a ValueError, not a
    209       # TypeError, when given unexpected types.  So we need to catch both.
--> 210       result = dispatch(wrapper, args, kwargs)
    211       if result is not OpDispatcher.NOT_SUPPORTED:
    212         return result

TypeError: 'module' object is not callable

【问题讨论】:

请为您的错误发布完整的堆栈跟踪。 您添加了很多信息,除了最重要的,完整的回溯,请添加。 好的,对不起,有点长。让我也补充一下。 【参考方案1】:

数据集是经典的狗对猫数据集,我正在努力实现 一类分类任务。

那么模型应该只有一个输出节点,因为这是二元分类的一个例子。您的模型的最后一个 Dense 层具有 两个 输出单元和 softmax 作为激活函数,这是一个可能的解决方案,但对于此类问题,我的建议是指定在最后一个 Dense 层上只有 一个 输出单元和 sigmoid 作为激活函数。

您似乎忘记在 train_generator 的类列表中添加字符串 dog

train_generator = train_datagen.flow_from_directory(
            base_path + 'training_set/training_set/',
            target_size = (SHAPE[0], SHAPE[1]),
            batch_size = batch_size,
            class_mode = 'categorical',
            shuffle = True,
            seed = 33,
            classes = ['cats']
    )

现在,关于您问题的主题。

from keras.models import load_model
loaded_model = load_model('my_custom_model.h5')
#or 
loaded_model = tf.keras.models.load_model('my_custom_model.h5')
#or 
loaded_model = load_model('my_custom_model') # as from folder

我想,但我不是 100% 确定,问题出在这行代码 from keras.models import load_model。从还包括 Keras 模块的 Tensorflow 2.x 开始,必须通过始终将 tensorflow 指定为导入每个 Keras 模块的名字来导入每个函数、类等。简而言之,您应该编写这行代码:from tensorflow.keras.models import load_model,它应该可以工作,因为它以 Tensorflow 作为后台引擎从 Keras 模块调用函数。

【讨论】:

以上是关于加载 keras 模型,TypeError:“模块”对象不可调用的主要内容,如果未能解决你的问题,请参考以下文章

使用自定义损失函数编译 Keras 模型时出现 TypeError

TypeError:张量是不可散列的。相反,使用 tensor.ref() 作为键。在 Keras 外科医生

来自自定义 keras 层的 tflite 转换器

尝试在 Keras 中创建 BLSTM 网络时出现 TypeError

TypeError:传递给优化器的意外关键字参数:learning_rate

使用 TensorFlow 2.1 加载自定义模型