使用Keras ModelCheckpoint保存模型报无法创建数据集(名称已存在)错误
Keras Swin Transformer示例添加ModelCheckpoint保存HDF5权重报错解决
问题表现
- 运行Keras官方Swin Transformer图像分类示例代码,无修改时可正常运行
- 仅在
model.fit的callbacks参数中添加ModelCheckpoint回调,尝试保存hdf5格式权重时,触发如下报错:
ValueError: Unable to create dataset (name already exists)
- 复现环境覆盖本地Windows 10(TensorFlow 2.8.0)、Google Colab(TensorFlow 2.8.2),均能稳定触发该问题
- 新增的回调代码片段如下:
history = model.fit( x_train, y_train, batch_size=batch_size, epochs=num_epochs, validation_split=validation_split, # 新增的ModelCheckpoint配置 callbacks = keras.callbacks.ModelCheckpoint('lowest_loss.hdf5', monitor='loss', verbose=0, save_best_only=True, save_weights_only=True) )
- 报错栈最终定位到h5py创建HDF5数据集的逻辑,提示目标名称已存在。
报错原因
报错信息里的name指的是HDF5文件内部存储每个权重张量对应的数据集路径名。
触发问题的根源是官方Swin Transformer示例里的自定义层(窗口注意力层、Swin Transformer块层)实现中,存在权重张量重名注册的问题:
- 普通训练流程的前向、反向传播阶段,TensorFlow不会强制校验权重命名的全局唯一性,所以原始代码跑训练不会报错
- 当调用HDF5格式的权重保存逻辑时,h5py需要为每一个权重创建独立路径的数据集,遇到重名的权重项时,就会直接抛出“名称已存在无法创建数据集”的错误。
可行解决方案
- 方案1(成本最低,优先推荐):更换权重保存格式,放弃hdf5格式,改用TensorFlow原生ckpt格式保存。只需要把
ModelCheckpoint里的文件名后缀从.hdf5改成.ckpt即可,其余代码不需要做任何修改,保存、加载权重的逻辑完全一致。 - 方案2:修复自定义层的权重命名。逐行检查Swin Transformer实现里的自定义层代码,给所有通过
self.add_weight()创建的权重参数显式传入全局唯一的name参数,确认整个模型没有重名权重后,即可正常用hdf5格式保存。 - 方案3:升级TensorFlow版本到2.10及以上。高版本TensorFlow对HDF5保存逻辑做了兼容优化,遇到重名权重时会自动追加数字后缀做区分,不会再抛出该类报错。
内容的提问来源于stack exchange,提问作者Ayanami Rei
相关产品推荐
相关产品推荐

