Transformer图像字幕模型TensorFlow加载HDF5权重报错求助
解决子类化TensorFlow模型加载HDF5权重的问题
错误原因
你的ImageCaptioningModel属于TensorFlow子类化Model,这类模型的变量不会在初始化或compile阶段创建,只有当模型第一次处理实际输入数据、触发各层的call方法时,才会完成变量初始化。而HDF5格式的权重文件要求模型变量已存在才能完成权重映射加载,直接调用load_weights自然会报错。
解决方案
在加载权重前,先用一组符合输入形状的虚拟数据调用模型,触发变量初始化,之后再加载权重。
修改后的加载代码
# 创建模型实例并编译(保留你原有的代码) model = ImageCaptioningModel( cnn_model=cnn_model, encoder=encoder, decoder=decoder, image_aug=image_augmentation, ) model.compile( optimizer=tf.keras.optimizers.Adam(), loss=cross_entropy ) # 生成符合输入形状的虚拟数据 # InceptionV3默认输入形状为(299, 299, 3),caption长度对应你的MAX_LENGTH dummy_img = tf.random.normal((1, 299, 299, 3)) dummy_caption = tf.random.uniform((1, MAX_LENGTH), minval=0, maxval=VOCABULARY_SIZE, dtype=tf.int32) # 调用模型的train_step方法,触发变量初始化 _ = model.train_step((dummy_img, dummy_caption)) # 现在可以正常加载权重 model.load_weights('/imagee_captioning_weights.h5')
替代方案:使用SavedModel格式保存整个模型
如果不想手动处理变量初始化,推荐直接保存整个模型而非仅权重,加载时会自动处理变量创建:
保存模型
# 训练完成后,用save方法保存整个模型 caption_model.save('image_captioning_full_model')
加载模型
# 直接加载模型,无需手动初始化变量 loaded_model = tf.keras.models.load_model('image_captioning_full_model')
注意:你的自定义层
__init__方法参数均为可序列化类型,因此可以正常使用SavedModel格式。
内容的提问来源于stack exchange,提问作者Mouad Baaziz
相关产品推荐
相关产品推荐

