chenchaoyun
commited on
Commit
·
1eb6063
1
Parent(s):
2cbce78
fix
Browse files- 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 |
-
|
| 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 |
-
|
| 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
|
| 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 (
|
| 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.")
|