加载TensorFlow H5模型时出现AttributeError: 'str' object has no attribute 'decode'求解决
修复AttributeError: 'str' object has no attribute 'decode'的方案
这个错误大多出现在加载Keras h5模型时,是TensorFlow和h5py版本兼容性导致的字符串处理冲突,以下是几种可行的修复方案:
方案1:改用JSON架构+权重文件加载模型
避开h5文件的字符串解码问题,拆分模型架构和权重分别加载:
import numpy as np import cv2 from tensorflow.keras.models import model_from_json # 先加载模型架构 with open('my_model_new.json', 'r') as f: model_json = f.read() model = model_from_json(model_json) # 再加载权重 model.load_weights('my_model_new_weights.h5') # 初始化摄像头(补充原代码缺失的部分) cap = cv2.VideoCapture(0) # 假设你已经定义了这些依赖项 threshold = 0.7 font = cv2.FONT_HERSHEY_SIMPLEX def getClassName(idx): # 这里替换成你的类别映射逻辑 return f"Class_{idx}" def preprocessing(img): # 这里替换成你的预处理逻辑,比如转灰度、归一化等 return cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) while True: success, imgOriginal = cap.read() if not success: break img = np.asarray(imgOriginal) img = cv2.resize(img, (32, 32)) img = preprocessing(img) cv2.imshow("Processed Image", img) img = img.reshape(1, 32, 32, 1) predictions = model.predict(img) classIndex = np.argmax(predictions) probVal = np.amax(predictions) if probVal > threshold: cv2.putText(imgOriginal, f"{getClassName(classIndex)} {probVal:.2f}", (50,50), font, 1, (0,0,255), 1, cv2.LINE_AA) cv2.imshow("Original Image", imgOriginal) # 修正按键判断的位运算逻辑 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放资源(补充原代码缺失的部分) cap.release() cv2.destroyAllWindows()
如果之前没保存过JSON架构和权重,训练模型时用以下代码保存:
# 训练完成后执行 model_json = model.to_json() with open("my_model_new.json", "w") as json_file: json_file.write(model_json) model.save_weights("my_model_new_weights.h5")
方案2:降级h5py版本
高版本h5py(3.x+)修改了字符串存储逻辑,和旧版TensorFlow的模型加载不兼容,直接降级到兼容版本:
pip install h5py==2.10.0
方案3:改用TensorFlow推荐的SavedModel格式
将模型转换为SavedModel格式,兼容性更好,也能彻底避开h5的字符串问题:
# 训练时重新保存模型 model.save("my_model_new_savedmodel") # 加载模型时直接用 from tensorflow.keras.models import load_model model = load_model("my_model_new_savedmodel")
额外注意:原代码的几个潜在问题
cap变量未初始化,必须添加cap = cv2.VideoCapture(0)(调用摄像头)或指定视频文件路径preprocessing、threshold、font、getClassName这些依赖项必须提前定义,否则会触发新的报错- 原代码的
cv2.waitKey(1) and 0xFF == ord('q')是逻辑错误,必须改成cv2.waitKey(1) & 0xFF == ord('q')才能正确捕获按键 - 循环结束后要释放摄像头资源并销毁窗口,避免内存泄漏
内容的提问来源于stack exchange,提问作者auxiler
相关产品推荐
相关产品推荐

