Spaces:
Sleeping
Sleeping
Commit ยท
34b001a
1
Parent(s): c480441
app/Hackathon_setup/face_recognition.py
CHANGED
|
@@ -226,86 +226,92 @@ def get_similarity(img1, img2):
|
|
| 226 |
return -1.0
|
| 227 |
|
| 228 |
def get_face_class(img1):
|
| 229 |
-
"""Get face class for a single image
|
| 230 |
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
| 231 |
|
| 232 |
try:
|
| 233 |
-
# ---
|
| 234 |
det_img1 = detected_face(img1)
|
| 235 |
if det_img1 is None:
|
|
|
|
| 236 |
det_img1 = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))
|
| 237 |
|
| 238 |
face1_tensor = trnscm(det_img1).unsqueeze(0).to(device)
|
| 239 |
-
|
| 240 |
-
|
|
|
|
| 241 |
siamese_net = Siamese().to(device)
|
| 242 |
model_data = torch.load(SIAMESE_MODEL_PATH, map_location=device)
|
|
|
|
| 243 |
if isinstance(model_data, dict) and 'net_dict' in model_data:
|
| 244 |
siamese_net.load_state_dict(model_data['net_dict'])
|
|
|
|
| 245 |
else:
|
| 246 |
siamese_net.load_state_dict(model_data)
|
|
|
|
|
|
|
| 247 |
siamese_net.eval()
|
| 248 |
-
|
| 249 |
-
# Extract
|
| 250 |
with torch.no_grad():
|
| 251 |
embedding_np = siamese_net.forward_once(face1_tensor).cpu().numpy()
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
|
|
|
| 259 |
try:
|
| 260 |
-
# 1. Try joblib/sav loading (most likely format)
|
| 261 |
scaler = safe_load_model(SCALER_PATH, "joblib")
|
| 262 |
classifier = safe_load_model(DECISION_TREE_MODEL_PATH, "joblib")
|
| 263 |
-
print("โ
|
| 264 |
-
|
| 265 |
-
except FileNotFoundError as fnfe:
|
| 266 |
-
print(f"โ Model/Scaler file not found: {fnfe}")
|
| 267 |
-
return "UNKNOWN_CLASS" # Stop if files aren't found
|
| 268 |
-
|
| 269 |
except Exception as e:
|
| 270 |
-
|
| 271 |
-
|
| 272 |
-
|
| 273 |
-
|
| 274 |
-
|
| 275 |
-
|
| 276 |
-
|
| 277 |
-
|
| 278 |
-
|
| 279 |
-
|
|
|
|
| 280 |
|
| 281 |
-
# ---
|
| 282 |
-
|
| 283 |
-
|
|
|
|
|
|
|
| 284 |
return "UNKNOWN_CLASS"
|
| 285 |
|
| 286 |
-
|
| 287 |
-
embedding_scaled =
|
| 288 |
-
|
| 289 |
-
|
| 290 |
-
# Ensure 2D input for prediction
|
| 291 |
-
if embedding_scaled.ndim == 1:
|
| 292 |
-
embedding_scaled = embedding_scaled.reshape(1, -1)
|
| 293 |
-
|
| 294 |
-
predicted_label_index = classifier.predict(embedding_scaled)[0]
|
| 295 |
-
print("Before converting to int", {predicted_label_index} )
|
| 296 |
-
|
| 297 |
-
# --- Map to class name ---
|
| 298 |
try:
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
except (ValueError, TypeError):
|
| 307 |
return "UNKNOWN_CLASS"
|
| 308 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
except Exception as e:
|
| 310 |
-
print(f"Error in get_face_class
|
| 311 |
return f"Error: {str(e)}"
|
|
|
|
| 226 |
return -1.0
|
| 227 |
|
| 228 |
def get_face_class(img1):
|
| 229 |
+
"""Get face class for a single image with detailed debugging."""
|
| 230 |
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
| 231 |
|
| 232 |
try:
|
| 233 |
+
# --- Face Detection ---
|
| 234 |
det_img1 = detected_face(img1)
|
| 235 |
if det_img1 is None:
|
| 236 |
+
print("โ ๏ธ No face detected, using grayscale fallback.")
|
| 237 |
det_img1 = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))
|
| 238 |
|
| 239 |
face1_tensor = trnscm(det_img1).unsqueeze(0).to(device)
|
| 240 |
+
print(f"๐งฉ Face tensor shape: {face1_tensor.shape}")
|
| 241 |
+
|
| 242 |
+
# --- Load Siamese Model ---
|
| 243 |
siamese_net = Siamese().to(device)
|
| 244 |
model_data = torch.load(SIAMESE_MODEL_PATH, map_location=device)
|
| 245 |
+
|
| 246 |
if isinstance(model_data, dict) and 'net_dict' in model_data:
|
| 247 |
siamese_net.load_state_dict(model_data['net_dict'])
|
| 248 |
+
print("โ Siamese model loaded (from net_dict key).")
|
| 249 |
else:
|
| 250 |
siamese_net.load_state_dict(model_data)
|
| 251 |
+
print("โ Siamese model loaded (direct state_dict).")
|
| 252 |
+
|
| 253 |
siamese_net.eval()
|
| 254 |
+
|
| 255 |
+
# --- Extract Embedding ---
|
| 256 |
with torch.no_grad():
|
| 257 |
embedding_np = siamese_net.forward_once(face1_tensor).cpu().numpy()
|
| 258 |
+
|
| 259 |
+
print(f"๐ง Raw embedding shape: {embedding_np.shape}")
|
| 260 |
+
print(f"๐งฎ Embedding mean={np.mean(embedding_np):.5f}, std={np.std(embedding_np):.5f}")
|
| 261 |
+
|
| 262 |
+
if embedding_np.ndim == 1:
|
| 263 |
+
embedding_np = embedding_np.reshape(1, -1)
|
| 264 |
+
|
| 265 |
+
# --- Load Scaler and Classifier ---
|
| 266 |
try:
|
|
|
|
| 267 |
scaler = safe_load_model(SCALER_PATH, "joblib")
|
| 268 |
classifier = safe_load_model(DECISION_TREE_MODEL_PATH, "joblib")
|
| 269 |
+
print("โ Loaded scaler and classifier via joblib.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 270 |
except Exception as e:
|
| 271 |
+
print(f"โ ๏ธ Joblib load failed: {e}, trying pickle...")
|
| 272 |
+
scaler = safe_load_model(SCALER_PATH, "pickle")
|
| 273 |
+
classifier = safe_load_model(DECISION_TREE_MODEL_PATH, "pickle")
|
| 274 |
+
|
| 275 |
+
# --- Validate Objects ---
|
| 276 |
+
if not hasattr(scaler, 'transform'):
|
| 277 |
+
print("โ Scaler missing transform() โ corrupted file?")
|
| 278 |
+
return "UNKNOWN_CLASS"
|
| 279 |
+
if not hasattr(classifier, 'predict'):
|
| 280 |
+
print("โ Classifier missing predict() โ corrupted file?")
|
| 281 |
+
return "UNKNOWN_CLASS"
|
| 282 |
|
| 283 |
+
# --- Transform Embedding ---
|
| 284 |
+
try:
|
| 285 |
+
embedding_scaled = scaler.transform(embedding_np)
|
| 286 |
+
except Exception as e:
|
| 287 |
+
print(f"โ Scaler transform failed: {e}")
|
| 288 |
return "UNKNOWN_CLASS"
|
| 289 |
|
| 290 |
+
print(f"โ๏ธ Scaled embedding (first 5 vals): {embedding_scaled[0, :5]}")
|
| 291 |
+
print(f"โ๏ธ Scaled embedding mean={np.mean(embedding_scaled):.5f}, std={np.std(embedding_scaled):.5f}")
|
| 292 |
+
|
| 293 |
+
# --- Predict Class ---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
try:
|
| 295 |
+
prediction = classifier.predict(embedding_scaled)
|
| 296 |
+
print(f"๐งพ Raw classifier prediction: {prediction}")
|
| 297 |
+
if hasattr(classifier, 'predict_proba'):
|
| 298 |
+
proba = classifier.predict_proba(embedding_scaled)
|
| 299 |
+
print(f"๐ Prediction probabilities: {np.round(proba, 3)}")
|
| 300 |
+
except Exception as e:
|
| 301 |
+
print(f"โ Prediction failed: {e}")
|
|
|
|
| 302 |
return "UNKNOWN_CLASS"
|
| 303 |
+
|
| 304 |
+
predicted_label_index = int(prediction[0])
|
| 305 |
+
|
| 306 |
+
# --- Map Index to Class Name ---
|
| 307 |
+
if 0 <= predicted_label_index < len(CLASS_NAMES):
|
| 308 |
+
class_name = CLASS_NAMES[predicted_label_index]
|
| 309 |
+
print(f"โ
Final Prediction: Index {predicted_label_index} -> {class_name}")
|
| 310 |
+
return class_name
|
| 311 |
+
else:
|
| 312 |
+
print(f"โ ๏ธ Invalid class index: {predicted_label_index}")
|
| 313 |
+
return "UNKNOWN_CLASS"
|
| 314 |
+
|
| 315 |
except Exception as e:
|
| 316 |
+
print(f"๐ฅ Error in get_face_class(): {e}")
|
| 317 |
return f"Error: {str(e)}"
|