添加序列化配置后,加载自定义Keras机器翻译模型仍报TypeError
问题原因与解决方法
你的错误根源在于**get_config()方法返回的配置包含了__init__函数未定义的参数**。当Keras加载模型时,会默认将get_config()返回的所有键值对作为关键字参数传递给模型类的__init__方法,但你的__init__只接受input_vocabulary_size、output_vocabulary_size、embedding_size、units_lstm这四个参数,并不认识encoder_embedding、encoder等额外参数,因此抛出Keyword argument not understood错误。
错误的核心问题
你在get_config()中错误地将模型的子层(如encoder_embedding、encoder)加入了配置字典,但Keras会自动处理子层的序列化与反序列化,不需要手动将这些层对象加入配置。你只需要在get_config()中返回__init__方法需要的初始化参数即可。
修正后的代码
修改get_config()方法,只保留__init__签名中的参数:
@keras.saving.register_keras_serializable() class BidirectionalEncoderandDecoderWithAttention(keras.Model): def __init__( self, input_vocabulary_size = 5000, output_vocabulary_size=5000, embedding_size = 256, units_lstm =512, **kwargs): super().__init__(**kwargs) self.input_vocabulary_size = input_vocabulary_size self.output_vocabulary_size = output_vocabulary_size self.embedding_size = embedding_size self.units_lstm = units_lstm self.encoder_embedding = Embedding(self.input_vocabulary_size,self.embedding_size,mask_zero = True) self.encoder = Bidirectional(LSTM(self.units_lstm//2,return_sequences = True,return_state = True)) self.decoder_embedding = Embedding(self.output_vocabulary_size,self.embedding_size,mask_zero = True) self.decoder = LSTM(self.units_lstm,return_sequences = True) self.attention = Attention() self.output_layer = Dense(self.output_vocabulary_size,activation = 'softmax') def call(self,inputs): encoder_inputs,decoder_inputs = inputs encoder_embeddings = self.encoder_embedding(encoder_inputs) decoder_embeddings = self.decoder_embedding(decoder_inputs) encoder_op,*encoder_state = self.encoder(encoder_embeddings) encoder_state = [ tf.concat(encoder_state[0::2], axis=-1), tf.concat(encoder_state[1::2], axis=-1), ] decoder_op = self.decoder(decoder_embeddings,initial_state = encoder_state) attention_output = self.attention([decoder_op,encoder_op]) output = self.output_layer(attention_output) return output def get_config(self): config = super().get_config() config.update ({ 'input_vocabulary_size': self.input_vocabulary_size, 'output_vocabulary_size': self.output_vocabulary_size, 'embedding_size': self.embedding_size, 'units_lstm': self.units_lstm }) return config
加载模型的正确方式
因为你已经添加了@keras.saving.register_keras_serializable()装饰器,加载时可以直接使用:
my_model_2 = keras.models.load_model("/content/tf.keras")
如果装饰器在某些环境中未生效,再传入custom_objects:
my_model_2 = keras.models.load_model( "/content/tf.keras", custom_objects={'BidirectionalEncoderandDecoderWithAttention': BidirectionalEncoderandDecoderWithAttention} )
为什么这样能解决问题
Keras的模型序列化机制中:
get_config()只需要返回初始化模型所需的参数,也就是__init__方法中定义的参数(除了**kwargs)。- 模型的子层(如Embedding、LSTM等)会被Keras自动递归序列化,不需要手动加入配置字典。
- 加载时,Keras会先通过
get_config()返回的参数创建模型实例,再自动恢复子层的权重和配置。
内容的提问来源于stack exchange,提问作者user8916969
相关产品推荐
相关产品推荐

