chenchaoyun commited on
Commit
1eb6063
·
1 Parent(s): 2cbce78
Files changed (1) hide show
  1. api_routes.py +47 -13
api_routes.py CHANGED
@@ -65,33 +65,67 @@ if DEEPFACE_AVAILABLE:
65
  deepface_module = DeepFace
66
  try:
67
  from deepface.models import FacialRecognition as df_facial_recognition
68
- DeepFaceModel = getattr(df_facial_recognition, "Model", None)
69
  _original_forward = df_facial_recognition.FacialRecognition.forward
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  def _patched_forward(self, img):
72
  """
73
  兼容Keras 3 / tf_keras 返回SymbolicTensor的情况,必要时退回predict。
74
  """
75
- if DeepFaceModel is None or not isinstance(self.model, DeepFaceModel):
76
  return _original_forward(self, img)
 
 
 
 
 
 
 
 
 
 
77
 
78
  if img.ndim == 3:
79
  img = np.expand_dims(img, axis=0)
80
 
81
- if img.ndim == 4 and img.shape[0] == 1:
82
- try:
83
- outputs = self.model(img, training=False)
84
- embeddings = outputs.numpy()
85
- except Exception:
86
- # Keras 3 调用 self.model(...) 可能返回SymbolicTensor,退回 predict
87
- embeddings = self.model.predict(img, verbose=0)
88
- elif img.ndim == 4 and img.shape[0] > 1:
89
- embeddings = self.model.predict_on_batch(img)
90
- else:
91
  raise ValueError(
92
- f"Input image must be (1, X, X, 3) shaped but it is {img.shape}"
93
  )
94
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  embeddings = np.asarray(embeddings)
96
  if embeddings.ndim == 0:
97
  raise ValueError("Embeddings output is empty.")
 
65
  deepface_module = DeepFace
66
  try:
67
  from deepface.models import FacialRecognition as df_facial_recognition
68
+
69
  _original_forward = df_facial_recognition.FacialRecognition.forward
70
 
71
+ def _safe_tensor_to_numpy(output_obj):
72
+ """尝试把tensorflow张量、安全列表转换为numpy数组。"""
73
+ if output_obj is None:
74
+ return None
75
+ if hasattr(output_obj, "numpy"):
76
+ try:
77
+ return output_obj.numpy()
78
+ except Exception:
79
+ return None
80
+ if isinstance(output_obj, np.ndarray):
81
+ return output_obj
82
+ if isinstance(output_obj, (list, tuple)):
83
+ # DeepFace只关心第一个输出
84
+ for item in output_obj:
85
+ result = _safe_tensor_to_numpy(item)
86
+ if result is not None:
87
+ return result
88
+ return None
89
+
90
  def _patched_forward(self, img):
91
  """
92
  兼容Keras 3 / tf_keras 返回SymbolicTensor的情况,必要时退回predict。
93
  """
94
+ try:
95
  return _original_forward(self, img)
96
+ except AttributeError as attr_err:
97
+ if "numpy" not in str(attr_err):
98
+ raise
99
+ logger.warning("DeepFace 原始 forward 触发 numpy AttributeError,启用兼容路径")
100
+ except Exception as generic_exc:
101
+ if "SymbolicTensor" not in str(generic_exc) and "numpy" not in str(generic_exc):
102
+ raise
103
+ logger.warning(
104
+ f"DeepFace 原始 forward 触发 SymbolicTensor 异常({generic_exc}), 启用兼容路径"
105
+ )
106
 
107
  if img.ndim == 3:
108
  img = np.expand_dims(img, axis=0)
109
 
110
+ if img.ndim != 4:
 
 
 
 
 
 
 
 
 
111
  raise ValueError(
112
+ f"Input image must be (N, X, X, 3) shaped but it is {img.shape}"
113
  )
114
 
115
+ embeddings = None
116
+ try:
117
+ outputs = self.model(img, training=False)
118
+ embeddings = _safe_tensor_to_numpy(outputs)
119
+ except Exception as call_exc:
120
+ logger.debug(f"DeepFace forward fallback self.model 调用失败,改用 predict: {call_exc}")
121
+
122
+ if embeddings is None:
123
+ # Keras 3 调用 self.model(...) 可能返回SymbolicTensor,退回 predict
124
+ predict_fn = getattr(self.model, "predict", None)
125
+ if predict_fn is None:
126
+ raise RuntimeError("DeepFace model 没有 predict 方法,无法转换 SymbolicTensor")
127
+ embeddings = predict_fn(img, verbose=0)
128
+
129
  embeddings = np.asarray(embeddings)
130
  if embeddings.ndim == 0:
131
  raise ValueError("Embeddings output is empty.")