DeepFace.analyze()报ValueError:sequential层未定义输入求助
问题:调用DeepFace.analyze()时抛出
ValueError: The layer sequential has never been called and thus has no defined input 问题背景
基于Streamlit开发实时人脸口罩检测应用,使用MobileNet v2预训练模型实现口罩检测,通过OpenCV获取摄像头实时流;当检测到未戴口罩时,调用DeepFace.analyze()估算年龄和性别,运行时在该函数处抛出错误。
报错栈
File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 542, in _run_script exec(code, module.__dict__) File "D:\Machine Learning Projects\Face Mask Detection\app.py", line 63, in <module> results = DeepFace.analyze(img_path = frame[y:y+h, x:x+w], actions=['age', 'gender'], enforce_detection=False) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\deepface\DeepFace.py", line 222, in analyze return demography.analyze( ^^^^^^^^^^^^^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\deepface\modules\demography.py", line 157, in analyze apparent_age = modeling.build_model("Age").predict(img_content) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\deepface\modules\modeling.py", line 46, in build_model model_obj[model_name] = model() ^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\deepface\extendedmodels\Age.py", line 32, in __init__ self.model = load_model() ^^^^^^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\deepface\extendedmodels\Age.py", line 61, in load_model age_model = Model(inputs=model.input, outputs=base_model_output) ^^^^^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\keras\src\ops\operation.py", line 216, in input return self._get_node_attribute_at_index(0, "input_tensors", "input") ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\Machine Learning Projects\Face Mask Detection\.venv\Lib\site-packages\keras\src\ops\operation.py", line 247, in _get_node_attribute_at_index raise ValueError( ValueError: The layer sequential has never been called and thus has no defined input.
错误原因
这个错误源于DeepFace的年龄检测模型与TensorFlow/Keras 3.x版本不兼容。DeepFace加载预训练年龄模型时采用了旧的Keras模型拼接逻辑,而Keras 3.x中,未被调用过的Sequential层无法直接获取input属性,导致模型初始化失败。
解决方案
方案1:强制DeepFace使用tf.keras(推荐)
在代码开头添加环境变量设置,指定DeepFace使用TensorFlow的Keras实现,避免版本冲突:
import os os.environ["KERAS_BACKEND"] = "tensorflow"
方案2:修改DeepFace的Age.py文件
找到DeepFace安装目录下的extendedmodels/Age.py,修改load_model函数,显式定义输入层:
原代码片段:
age_model = Model(inputs=model.input, outputs=base_model_output)
修改为:
from tensorflow.keras.layers import Input # 显式定义输入形状(匹配年龄模型要求的224x224x3) input_shape = (224, 224, 3) inputs = Input(shape=input_shape) x = model(inputs) x = base_model_output(x) age_model = Model(inputs=inputs, outputs=x)
方案3:降级TensorFlow到2.x版本
如果不需要Keras 3.x的特性,可以降级TensorFlow到2.15.x及以下版本,兼容DeepFace的旧模型加载逻辑:
pip install tensorflow==2.15.0
修改后的完整代码
import os os.environ["KERAS_BACKEND"] = "tensorflow" # 强制使用tf.keras import streamlit as st import cv2 import numpy as np from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.image import img_to_array from tensorflow.keras.applications.mobilenet_v2 import preprocess_input from deepface import DeepFace # Load the trained mask detection model model = load_model("mask_detection_model.h5") # Load the pre-trained face detection model face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') # Create a function for real-time mask detection def detect_mask(frame): # Preprocess the frame resized_frame = cv2.resize(frame, (128, 128)) resized_frame = img_to_array(resized_frame) resized_frame = preprocess_input(resized_frame) resized_frame = np.expand_dims(resized_frame, axis=0) # Perform prediction predictions = model.predict(resized_frame) return predictions # Streamlit web app st.title("Real-time Face Mask Detection") # Open the webcam cap = cv2.VideoCapture(0) if not cap.isOpened(): st.error("Error: Could not open webcam.") else: stframe = st.empty() # 添加停止按钮控制循环 stop_button = st.button("Stop Detection") while not stop_button: ret, frame = cap.read() if not ret: st.error("Error: Unable to capture frame.") break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(100, 100)) # Display the frame with the label for (x, y, w, h) in faces: # 仅对人脸区域做口罩检测,优化性能 face_roi = frame[y:y + h, x:x + w] predictions = detect_mask(face_roi) label = "Mask" if np.argmax(predictions) == 1 else "No Mask" color = (0, 255, 0) if label == "Mask" else (0, 0, 255) # If no mask is detected, estimate age and gender if label == "No Mask": results = DeepFace.analyze(img_path=face_roi, actions=['age', 'gender'], enforce_detection=False) results = results[0] age = results['age'] gender = results['dominant_gender'] # Display age and gender estimation cv2.putText(frame, f'Age: {age:.1f} years', (x, y - 60), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) cv2.putText(frame, f'Gender: {gender}', (x, y - 40), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2) # Display mask detection result cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2) cv2.putText(frame, label, (x,y-10), cv2.FONT_HERSHEY_SIMPLEX, 1, color, 2) # Convert the frame to RGB for Streamlit frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # Display the frame using Streamlit stframe.image(frame_rgb, channels="RGB", use_column_width=True) # 更新停止按钮状态 stop_button = st.button("Stop Detection", key="stop") cv2.waitKey(1) cap.release() cv2.destroyAllWindows()
内容的提问来源于stack exchange,提问作者Probal Kar
相关产品推荐
相关产品推荐

