【问题标题】:Errors when saving a Keras ML model保存 Keras ML 模型时出错
【发布时间】:2021-10-09 21:33:52
【问题描述】:

我在保存 ML 模型时遇到错误。我在这里搜索了 SO,看起来建议是将函数的参数更改为 '=None'。但是当我尝试这样做时,我得到了一个错误None types are not iterable。有什么想法吗?

# Save the model
model.save('./alexnet_model.hdf5')
# Load the model
alexnet_model = tf.keras.models.load_model('./alexnet_model.hdf5', custom_objects={'AlexNet': AlexNet})

错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-76-504e90d49459> in <module>()
      6 model.save('./alexnet_model.hdf5')
      7 # Load the model
----> 8 alexnet_model = tf.keras.models.load_model('./alexnet_model.hdf5', custom_objects={'AlexNet': AlexNet})
      9 #alexnet_model = tf.keras.models.load_model('./alexnet_model.hdf5')

5 frames
/usr/local/lib/python3.7/dist-packages/keras/engine/sequential.py in from_config(cls, config, custom_objects)
    428       build_input_shape = None
    429       layer_configs = config
--> 430     model = cls(name=name)
    431     for layer_config in layer_configs:
    432       layer = layer_module.deserialize(layer_config,

TypeError: __init__() missing 2 required positional arguments: 'input_shape' and 'num_classes'

这是模型架构的前几行:

# Define the AlexNet model
class AlexNet(Sequential):
   def __init__(self, input_shape, num_classes, **kwargs):
    super().__init__()

尝试使用 get_config 函数更新 AlexNet 架构:

# Define the AlexNet model
class AlexNet(Sequential):
   def __init__(self, input_shape, num_classes, **kwargs):
    super().__init__()

    self.add(Conv2D(96, kernel_size=(11,11), strides= 4,
                    padding= 'valid', activation= 'relu',
                    input_shape= input_shape, kernel_initializer= 'he_normal'))
    self.add(BatchNormalization())
    self.add(MaxPooling2D(pool_size=(3,3), strides= (2,2),
                          padding= 'valid', data_format= None))
    
    
    self.add(Conv2D(256, kernel_size=(5,5), strides= 1,
                    padding= 'same', activation= 'relu',
                    kernel_initializer= 'he_normal'))
    self.add(BatchNormalization())
    self.add(MaxPooling2D(pool_size=(3,3), strides= (2,2),
                          padding= 'valid', data_format= None)) 
    

    self.add(Conv2D(384, kernel_size=(3,3), strides= 1,
                    padding= 'same', activation= 'relu',
                    kernel_initializer= 'he_normal'))
    self.add(BatchNormalization())
    
    self.add(Conv2D(384, kernel_size=(3,3), strides= 1,
                    padding= 'same', activation= 'relu',
                    kernel_initializer= 'he_normal'))
    self.add(BatchNormalization())
    
    self.add(Conv2D(256, kernel_size=(3,3), strides= 1,
                    padding= 'same', activation= 'relu',
                    kernel_initializer= 'he_normal'))
    self.add(BatchNormalization())
    
    self.add(MaxPooling2D(pool_size=(3,3), strides= (2,2),
                          padding= 'valid', data_format= None))
    

    self.add(Flatten())
    
    self.add(Dense(num_classes, activation= 'sigmoid')) #try sigmoid vs. softmax

    self.compile(optimizer= tf.keras.optimizers.Adam(learning_rate=lr_schedule),
                loss='binary_crossentropy',
                metrics=['accuracy'])

   def get_config(self):
     return {'input_shape': (256, 256, 3), 'num_classes': 3}

仍然遇到同样的错误:

# Save the model
model.save('./alexnet_model.hdf5')
# Load the model
alexnet_model = tf.keras.models.load_model('./alexnet_model.hdf5', custom_objects={'AlexNet': AlexNet})

【问题讨论】:

    标签: python tensorflow machine-learning keras


    【解决方案1】:

    您是否在模型中定义了get_config 方法来返回您的初始化参数? 你能再看看他们的教程来比较你的模型配置吗?

    https://www.tensorflow.org/guide/keras/save_and_serialize

    【讨论】:

      【解决方案2】:

      正如@firattamur 提到的,您需要添加一个get_config 方法,该方法可以在反序列化模型时返回构造函数的参数。请参阅Save and Load Keras models 中的this 部分。它提到,

      子类模型和层的架构在 方法__init__call。它们被认为是 Python 字节码, 无法序列化为与 JSON 兼容的配置 - 您可以尝试 序列化字节码(例如通过pickle),但它完全不安全 并且意味着您的模型无法加载到其他系统上。

      为了保存/加载具有自定义层的模型,或 子类模型,您应该覆盖 get_config 并且可以选择 from_config 方法。此外,您应该使用注册自定义 对象,以便 Keras 知道它。

      get_config 方法添加到您的类AlexNet

      class AlexNet(Sequential):
      
         def __init__(self, input_shape, num_classes, **kwargs):
          super().__init__()
      
         def call( self , inputs ):
          ...
      
         def get_config( self ):
            # Modify these according to your requirements
            return { 'input_shape' : ( 224 , 224 , 1 ) , 
                     'num_classes' : 3 }
      

      【讨论】:

      • 只是为了确认 - get_config 不应该在 itit 函数内?这行代码我仍然遇到同样的错误:alexnet_model = tf.keras.models.load_model('./alexnet_model.hdf5', custom_objects={'AlexNet': AlexNet})。我需要在那里改变什么吗?
      • 我添加了完整模型架构的更新
      猜你喜欢
      • 2021-04-24
      • 2021-06-08
      • 2019-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-08-05
      • 2016-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多