在Keras中如何从已保存的.h5模型获取class_indices或预测标签
嘿,这个问题其实很多人在部署Keras模型的时候都会碰到——我来给你理清楚:
首先得明确说:默认情况下,Keras保存的.h5模型文件里是不会包含class_indices这类类标签映射的。因为模型文件本身只负责存储权重、网络架构和训练相关的配置(比如优化器的状态),而class_indices是数据生成器(也就是flow_from_directory())在处理数据集时生成的元数据,不属于模型核心逻辑的一部分,所以不会被自动存进去。
不过别担心,有几个靠谱的解决方案:
最稳妥的方案:训练时同步保存类标签
这是我最推荐的做法,麻烦一次,后面部署省很多事。当你用flow_from_directory()生成训练数据时,直接把生成器的class_indices存成一个单独的JSON或者pickle文件:import json # 假设train_generator是你训练时用的数据生成器 class_labels = train_generator.class_indices # 把类标签映射保存到json文件,和模型文件放一起 with open('class_labels.json', 'w') as f: json.dump(class_labels, f)等部署的时候,只需要加载这个小文件就能拿到类名和索引的对应关系了,还可以反转字典方便预测后查类名:
with open('class_labels.json', 'r') as f: class_labels = json.load(f) # 索引转类名的映射,预测结果出来后直接用 idx_to_class = {v: k for k, v in class_labels.items()}退而求其次:从输出层或数据集反向推导
如果之前没保存类标签,那可以试试这招:- 如果你能访问到训练时用的数据集目录,完全可以重新跑一次
flow_from_directory()(不需要训练,只是生成数据生成器),就能拿到class_indices:from tensorflow.keras.preprocessing.image import ImageDataGenerator # 用训练数据集目录生成一个临时生成器,batch_size设1就行,不用占资源 dummy_gen = ImageDataGenerator(rescale=1./255).flow_from_directory( 'path/to/your/training_data', target_size=(224, 224), # 和训练时一致 batch_size=1, class_mode='categorical', shuffle=False ) class_labels = dummy_gen.class_indices - 要是没法访问数据集,那只能从模型输出层知道类别的数量(输出层神经元数=类别数),但没法直接拿到类名——这种情况就只能回忆或者查训练时的数据集结构了,毕竟类名是从数据集目录来的。
- 如果你能访问到训练时用的数据集目录,完全可以重新跑一次
进阶玩法:用SavedModel格式保存模型+元数据
如果你不想分开保存模型和类标签,可以改用TensorFlow的SavedModel格式(而不是.h5)来保存模型。SavedModel支持在assets目录里添加自定义的元数据文件(比如刚才的JSON),部署的时候可以一起加载,这样模型和类标签就绑定在一起了,管理起来更方便。
总结一下:虽然.h5模型本身不带类标签,但只要训练时提前保存好元数据,或者能反向从数据集推导,就能轻松解决部署时的类标签问题。
内容的提问来源于stack exchange,提问作者Ryan Chase

