facenet_keras.h5能否适配TensorFlow2.16.1与Keras3.3.3?遇EOFError求解
问题:FaceNet Keras模型加载时出现EOFError
我尝试结合FaceNet Keras、TensorFlow与MTCNN实现人脸识别,但运行代码时抛出EOFError: EOF read where object expected错误,想确认facenet_keras.h5模型是否还能正常使用。
我的环境版本:
- TensorFlow 2.16.1
- Keras 3.3.3
- Python 3.11.9
此前无需加载Keras模型的代码在该环境下可正常运行,相关完整代码如下:
import os from os import listdir from PIL import Image as Img from numpy import asarray from numpy import expand_dims from matplotlib import pyplot from keras.models import load_model #type: ignore import numpy as np import tensorflow as tf from keras_facenet import FaceNet # type: ignore import pickle import cv2 HaarCascade = cv2.CascadeClassifier(cv2.samples.findFile(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')) MyFaceNet = load_model("F:\\Andre\\FaceRecognitiontest/facenet_keras.h5") folder='faces/' database = {} for filename in listdir(folder): path = folder + filename gbr1 = cv2.imread(folder + filename) wajah = HaarCascade.detectMultiScale(gbr1,1.1,4) if len(wajah)>0: x1, y1, width, height = wajah[0] else: x1, y1, width, height = 1, 1, 10, 10 x1, y1 = abs(x1), abs(y1) x2, y2 = x1 + width, y1 + height gbr = cv2.cvtColor(gbr1, cv2.COLOR_BGR2RGB) gbr = Img.fromarray(gbr) # 从OpenCV格式转PIL格式 gbr_array = asarray(gbr) face = gbr_array[y1:y2, x1:x2] face = Img.fromarray(face) face = face.resize((160,160)) face = asarray(face) face = face.astype('float32') mean, std = face.mean(), face.std() face = (face - mean) / std face = expand_dims(face, axis=0) signature = MyFaceNet.predict(face) database[os.path.splitext(filename)[0]]=signature myfile = open("data.pkl", "wb") pickle.dump(database, myfile) myfile.close() myfile = open("data.pkl", "rb") database = pickle.load(myfile) myfile.close() def findFaces(frame): gbr1 = frame gbr = cv2.cvtColor(gbr1, cv2.COLOR_BGR2RGB) gbr = Img.fromarray(gbr) # 从OpenCV格式转PIL格式 gbr_array = asarray(gbr) wajah = HaarCascade.detectMultiScale(gbr1,1.1,4) for (x1,y1,w,h) in wajah: x1, y1 = abs(x1), abs(y1) x2, y2 = x1 + w, y1 + h face = gbr_array[y1:y2, x1:x2] face = Img.fromarray(face) face = face.resize((160,160)) face = asarray(face) face = face.astype('float32') mean, std = face.mean(), face.std() face = (face - mean) / std face = expand_dims(face, axis=0) signature = MyFaceNet.predict(face) min_dist=100 identity=' ' for key, value in database.items() : dist = np.linalg.norm(value-signature) if dist < min_dist: min_dist = dist identity = key cv2.putText(gbr1,identity, (x1,y1),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 255, 0), 1, cv2.LINE_AA) cv2.rectangle(gbr1,(x1,y1),(x2,y2), (0,255,0), 2) return gbr1 cap = cv2.VideoCapture(0) while True: ret, frame = cap.read() if not ret: break frame = findFaces(frame) cv2.imshow('Live Stream', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
原因分析与解决方案
错误核心原因
EOFError通常意味着程序读取文件时提前遇到了文件末尾,针对你的场景,大概率是模型文件损坏或Keras版本兼容性问题导致加载失败。
验证模型可用性的步骤
检查模型文件完整性
- 对比文件大小:官方发布的
facenet_keras.h5约为100MB左右,如果你的文件远小于这个值,说明下载过程中断,需重新下载完整模型。 - 用HDF5工具验证文件结构:
若报错则说明文件已损坏,需重新获取模型。import h5py try: with h5py.File("F:\\Andre\\FaceRecognitiontest/facenet_keras.h5", 'r') as f: print("模型文件结构正常:", list(f.keys())) except Exception as e: print("模型文件损坏:", str(e))
- 对比文件大小:官方发布的
适配Keras 3.x兼容性
旧版FaceNet模型是用Keras 2.x保存的,直接用Keras 3加载可能存在格式兼容问题,修改加载代码如下:# 改用TensorFlow集成的Keras加载,并关闭编译(避免旧编译配置冲突) from tensorflow.keras.models import load_model MyFaceNet = load_model("F:\\Andre\\FaceRecognitiontest/facenet_keras.h5", compile=False)替换为keras_facenet库的自动加载方式
你已经导入了keras_facenet.FaceNet,可以直接使用该库的预训练模型,无需手动管理h5文件,兼容问题由库自动处理:from keras_facenet import FaceNet MyFaceNet = FaceNet() # 自动加载官方预训练模型排除pickle环节干扰
暂时注释掉代码中pickle.dump和pickle.load相关逻辑,单独测试模型加载和单张图片预测,确认错误是否来自模型加载环节。
内容的提问来源于stack exchange,提问作者André Pimentel
相关产品推荐
相关产品推荐

