Spaces:
Sleeping
Sleeping
Commit ·
7bf7aa7
1
Parent(s): 25e986d
deploy code
Browse files- app/Hackathon_setup/__pycache__/face_recognition.cpython-313.pyc +0 -0
- app/Hackathon_setup/__pycache__/face_recognition_model.cpython-313.pyc +0 -0
- app/Hackathon_setup/diagnose_errors.py +167 -0
- app/Hackathon_setup/face_recognition.py +47 -9
- app/Hackathon_setup/face_recognition_model.py +38 -104
- app/Hackathon_setup/inspect_model.py +41 -0
- app/Hackathon_setup/test_cosine_similarity.py +159 -0
app/Hackathon_setup/__pycache__/face_recognition.cpython-313.pyc
ADDED
|
Binary file (7.73 kB). View file
|
|
|
app/Hackathon_setup/__pycache__/face_recognition_model.cpython-313.pyc
ADDED
|
Binary file (3 kB). View file
|
|
|
app/Hackathon_setup/diagnose_errors.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Diagnostic script to identify common issues with face recognition setup
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
import sys
|
| 6 |
+
import os
|
| 7 |
+
import traceback
|
| 8 |
+
|
| 9 |
+
def check_python_version():
|
| 10 |
+
"""Check Python version"""
|
| 11 |
+
print("Python Version Check")
|
| 12 |
+
print("=" * 20)
|
| 13 |
+
print(f"Python version: {sys.version}")
|
| 14 |
+
if sys.version_info < (3, 6):
|
| 15 |
+
print("WARNING: Python 3.6+ recommended")
|
| 16 |
+
else:
|
| 17 |
+
print("OK: Python version is compatible")
|
| 18 |
+
|
| 19 |
+
def check_packages():
|
| 20 |
+
"""Check if required packages are installed"""
|
| 21 |
+
print("\nPackage Installation Check")
|
| 22 |
+
print("=" * 30)
|
| 23 |
+
|
| 24 |
+
packages = [
|
| 25 |
+
('numpy', 'numpy'),
|
| 26 |
+
('cv2', 'cv2'),
|
| 27 |
+
('torch', 'torch'),
|
| 28 |
+
('sklearn', 'sklearn'),
|
| 29 |
+
('PIL', 'PIL'),
|
| 30 |
+
('matplotlib', 'matplotlib'),
|
| 31 |
+
('joblib', 'joblib')
|
| 32 |
+
]
|
| 33 |
+
|
| 34 |
+
missing_packages = []
|
| 35 |
+
|
| 36 |
+
for package_name, import_name in packages:
|
| 37 |
+
try:
|
| 38 |
+
__import__(import_name)
|
| 39 |
+
print(f"OK: {package_name}")
|
| 40 |
+
except ImportError:
|
| 41 |
+
print(f"ERROR: {package_name} - MISSING")
|
| 42 |
+
missing_packages.append(package_name)
|
| 43 |
+
|
| 44 |
+
if missing_packages:
|
| 45 |
+
print(f"\nWARNING: Missing packages: {', '.join(missing_packages)}")
|
| 46 |
+
print("Install with: pip install " + " ".join(missing_packages))
|
| 47 |
+
return False
|
| 48 |
+
else:
|
| 49 |
+
print("\nOK: All required packages are installed")
|
| 50 |
+
return True
|
| 51 |
+
|
| 52 |
+
def check_files():
|
| 53 |
+
"""Check if required files exist"""
|
| 54 |
+
print("\nFile Structure Check")
|
| 55 |
+
print("=" * 25)
|
| 56 |
+
|
| 57 |
+
required_files = [
|
| 58 |
+
'face_recognition.py',
|
| 59 |
+
'face_recognition_model.py',
|
| 60 |
+
'test_cosine_similarity.py'
|
| 61 |
+
]
|
| 62 |
+
|
| 63 |
+
model_files = [
|
| 64 |
+
'siamese_model.t7',
|
| 65 |
+
'decision_tree_model.sav',
|
| 66 |
+
'face_recognition_scaler.sav'
|
| 67 |
+
]
|
| 68 |
+
|
| 69 |
+
missing_files = []
|
| 70 |
+
|
| 71 |
+
print("Required Python files:")
|
| 72 |
+
for file in required_files:
|
| 73 |
+
if os.path.exists(file):
|
| 74 |
+
print(f"OK: {file}")
|
| 75 |
+
else:
|
| 76 |
+
print(f"ERROR: {file} - MISSING")
|
| 77 |
+
missing_files.append(file)
|
| 78 |
+
|
| 79 |
+
print("\nModel files (need to be trained):")
|
| 80 |
+
for file in model_files:
|
| 81 |
+
if os.path.exists(file):
|
| 82 |
+
print(f"OK: {file}")
|
| 83 |
+
else:
|
| 84 |
+
print(f"ERROR: {file} - MISSING (needs training)")
|
| 85 |
+
missing_files.append(file)
|
| 86 |
+
|
| 87 |
+
return len(missing_files) == 0
|
| 88 |
+
|
| 89 |
+
def test_imports():
|
| 90 |
+
"""Test importing the face recognition module"""
|
| 91 |
+
print("\nImport Test")
|
| 92 |
+
print("=" * 15)
|
| 93 |
+
|
| 94 |
+
try:
|
| 95 |
+
# Add current directory to path
|
| 96 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 97 |
+
sys.path.insert(0, current_dir)
|
| 98 |
+
|
| 99 |
+
from face_recognition import get_similarity, get_face_class
|
| 100 |
+
print("OK: Successfully imported face_recognition functions")
|
| 101 |
+
return True
|
| 102 |
+
except Exception as e:
|
| 103 |
+
print(f"ERROR: Failed to import face_recognition: {e}")
|
| 104 |
+
print("Full error:")
|
| 105 |
+
traceback.print_exc()
|
| 106 |
+
return False
|
| 107 |
+
|
| 108 |
+
def test_basic_functionality():
|
| 109 |
+
"""Test basic functionality without model files"""
|
| 110 |
+
print("\nBasic Functionality Test")
|
| 111 |
+
print("=" * 30)
|
| 112 |
+
|
| 113 |
+
try:
|
| 114 |
+
import numpy as np
|
| 115 |
+
from face_recognition import detected_face
|
| 116 |
+
|
| 117 |
+
# Create a test image
|
| 118 |
+
test_img = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
|
| 119 |
+
|
| 120 |
+
# Test face detection
|
| 121 |
+
result = detected_face(test_img)
|
| 122 |
+
print("OK: detected_face function works")
|
| 123 |
+
|
| 124 |
+
return True
|
| 125 |
+
except Exception as e:
|
| 126 |
+
print(f"ERROR: Basic functionality test failed: {e}")
|
| 127 |
+
traceback.print_exc()
|
| 128 |
+
return False
|
| 129 |
+
|
| 130 |
+
def main():
|
| 131 |
+
"""Run all diagnostic checks"""
|
| 132 |
+
print("Face Recognition System Diagnostic")
|
| 133 |
+
print("=" * 40)
|
| 134 |
+
|
| 135 |
+
checks = [
|
| 136 |
+
check_python_version,
|
| 137 |
+
check_packages,
|
| 138 |
+
check_files,
|
| 139 |
+
test_imports,
|
| 140 |
+
test_basic_functionality
|
| 141 |
+
]
|
| 142 |
+
|
| 143 |
+
results = []
|
| 144 |
+
for check in checks:
|
| 145 |
+
try:
|
| 146 |
+
result = check()
|
| 147 |
+
results.append(result)
|
| 148 |
+
except Exception as e:
|
| 149 |
+
print(f"ERROR: Check failed with error: {e}")
|
| 150 |
+
results.append(False)
|
| 151 |
+
|
| 152 |
+
print("\n" + "=" * 40)
|
| 153 |
+
print("DIAGNOSTIC SUMMARY")
|
| 154 |
+
print("=" * 40)
|
| 155 |
+
|
| 156 |
+
if all(results):
|
| 157 |
+
print("SUCCESS: All checks passed! Your setup looks good.")
|
| 158 |
+
print("You can now run the test script.")
|
| 159 |
+
else:
|
| 160 |
+
print("ERROR: Some checks failed. Please fix the issues above.")
|
| 161 |
+
print("\nCommon solutions:")
|
| 162 |
+
print("1. Install missing packages: pip install numpy opencv-python torch scikit-learn matplotlib joblib")
|
| 163 |
+
print("2. Make sure all Python files are in the same directory")
|
| 164 |
+
print("3. Train your models first before testing similarity")
|
| 165 |
+
|
| 166 |
+
if __name__ == "__main__":
|
| 167 |
+
main()
|
app/Hackathon_setup/face_recognition.py
CHANGED
|
@@ -3,13 +3,19 @@ import cv2
|
|
| 3 |
from matplotlib import pyplot as plt
|
| 4 |
import torch
|
| 5 |
# In the below line,remove '.' while working on your local system. However Make sure that '.' is present before face_recognition_model while uploading to the server, Do not remove it.
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
from PIL import Image
|
| 8 |
import base64
|
| 9 |
import io
|
| 10 |
import os
|
| 11 |
import joblib
|
| 12 |
import pickle
|
|
|
|
|
|
|
| 13 |
# Add more imports if required
|
| 14 |
|
| 15 |
|
|
@@ -90,9 +96,16 @@ def get_similarity(img1, img2):
|
|
| 90 |
# YOUR CODE HERE, return similarity measure using your model
|
| 91 |
# 1. Initialize and Load Siamese Network
|
| 92 |
try:
|
| 93 |
-
#
|
| 94 |
-
siamese_net =
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
siamese_net.eval()
|
| 97 |
except Exception as e:
|
| 98 |
print(f"Error loading Siamese Model get_similarity: {e}")
|
|
@@ -102,8 +115,8 @@ def get_similarity(img1, img2):
|
|
| 102 |
with torch.no_grad():
|
| 103 |
# Get the feature vector from one tower/forward_once method
|
| 104 |
# Ensure your SiameseNetwork class has a forward_once or get_embedding method
|
| 105 |
-
embed1 = siamese_net.forward_once(face1).cpu().numpy()
|
| 106 |
-
embed2 = siamese_net.forward_once(face2).cpu().numpy()
|
| 107 |
|
| 108 |
# 3. Calculate Similarity Measure
|
| 109 |
# The Euclidean distance is the fundamental metric used by the Triplet/Contrastive loss.
|
|
@@ -114,7 +127,21 @@ def get_similarity(img1, img2):
|
|
| 114 |
# similarity = -distance
|
| 115 |
|
| 116 |
# Option B: Cosine Similarity (Higher is better) -> Recommended
|
| 117 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
|
| 119 |
return float(similarity)
|
| 120 |
|
|
@@ -137,8 +164,15 @@ def get_face_class(img1):
|
|
| 137 |
|
| 138 |
# 1. Load Siamese Network (Feature Extractor)
|
| 139 |
try:
|
| 140 |
-
siamese_net =
|
| 141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
siamese_net.eval()
|
| 143 |
except Exception as e:
|
| 144 |
return f"Error loading Siamese Model get_face_class: {e}"
|
|
@@ -146,6 +180,10 @@ def get_face_class(img1):
|
|
| 146 |
# 2. Extract Embedding
|
| 147 |
with torch.no_grad():
|
| 148 |
embedding_np = siamese_net.forward_once(face1_tensor).cpu().numpy()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 149 |
|
| 150 |
# 3. Load Sklearn Scaler and Classifier (Joblib)
|
| 151 |
try:
|
|
|
|
| 3 |
from matplotlib import pyplot as plt
|
| 4 |
import torch
|
| 5 |
# In the below line,remove '.' while working on your local system. However Make sure that '.' is present before face_recognition_model while uploading to the server, Do not remove it.
|
| 6 |
+
try:
|
| 7 |
+
from .face_recognition_model import *
|
| 8 |
+
except ImportError:
|
| 9 |
+
# Fallback for when running as standalone script
|
| 10 |
+
from face_recognition_model import *
|
| 11 |
from PIL import Image
|
| 12 |
import base64
|
| 13 |
import io
|
| 14 |
import os
|
| 15 |
import joblib
|
| 16 |
import pickle
|
| 17 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
| 18 |
+
from sklearn.preprocessing import StandardScaler
|
| 19 |
# Add more imports if required
|
| 20 |
|
| 21 |
|
|
|
|
| 96 |
# YOUR CODE HERE, return similarity measure using your model
|
| 97 |
# 1. Initialize and Load Siamese Network
|
| 98 |
try:
|
| 99 |
+
# Using the Siamese class from your model file
|
| 100 |
+
siamese_net = Siamese().to(device)
|
| 101 |
+
|
| 102 |
+
# Load the model - check if it has 'net_dict' key
|
| 103 |
+
model_data = torch.load(SIAMESE_MODEL_PATH, map_location=device)
|
| 104 |
+
if isinstance(model_data, dict) and 'net_dict' in model_data:
|
| 105 |
+
siamese_net.load_state_dict(model_data['net_dict'])
|
| 106 |
+
else:
|
| 107 |
+
siamese_net.load_state_dict(model_data)
|
| 108 |
+
|
| 109 |
siamese_net.eval()
|
| 110 |
except Exception as e:
|
| 111 |
print(f"Error loading Siamese Model get_similarity: {e}")
|
|
|
|
| 115 |
with torch.no_grad():
|
| 116 |
# Get the feature vector from one tower/forward_once method
|
| 117 |
# Ensure your SiameseNetwork class has a forward_once or get_embedding method
|
| 118 |
+
embed1 = siamese_net.forward_once(face1.to(device)).cpu().numpy()
|
| 119 |
+
embed2 = siamese_net.forward_once(face2.to(device)).cpu().numpy()
|
| 120 |
|
| 121 |
# 3. Calculate Similarity Measure
|
| 122 |
# The Euclidean distance is the fundamental metric used by the Triplet/Contrastive loss.
|
|
|
|
| 127 |
# similarity = -distance
|
| 128 |
|
| 129 |
# Option B: Cosine Similarity (Higher is better) -> Recommended
|
| 130 |
+
try:
|
| 131 |
+
# Ensure embeddings are 2D arrays for sklearn cosine_similarity
|
| 132 |
+
if embed1.ndim == 1:
|
| 133 |
+
embed1 = embed1.reshape(1, -1)
|
| 134 |
+
if embed2.ndim == 1:
|
| 135 |
+
embed2 = embed2.reshape(1, -1)
|
| 136 |
+
|
| 137 |
+
similarity = cosine_similarity(embed1, embed2)[0][0]
|
| 138 |
+
|
| 139 |
+
# Clamp similarity to valid range [-1, 1] to handle numerical precision issues
|
| 140 |
+
similarity = np.clip(similarity, -1.0, 1.0)
|
| 141 |
+
|
| 142 |
+
except Exception as e:
|
| 143 |
+
print(f"Error calculating cosine similarity: {e}")
|
| 144 |
+
return -1.0 # Return error value
|
| 145 |
|
| 146 |
return float(similarity)
|
| 147 |
|
|
|
|
| 164 |
|
| 165 |
# 1. Load Siamese Network (Feature Extractor)
|
| 166 |
try:
|
| 167 |
+
siamese_net = Siamese().to(device)
|
| 168 |
+
|
| 169 |
+
# Load the model - check if it has 'net_dict' key
|
| 170 |
+
model_data = torch.load(SIAMESE_MODEL_PATH, map_location=device)
|
| 171 |
+
if isinstance(model_data, dict) and 'net_dict' in model_data:
|
| 172 |
+
siamese_net.load_state_dict(model_data['net_dict'])
|
| 173 |
+
else:
|
| 174 |
+
siamese_net.load_state_dict(model_data)
|
| 175 |
+
|
| 176 |
siamese_net.eval()
|
| 177 |
except Exception as e:
|
| 178 |
return f"Error loading Siamese Model get_face_class: {e}"
|
|
|
|
| 180 |
# 2. Extract Embedding
|
| 181 |
with torch.no_grad():
|
| 182 |
embedding_np = siamese_net.forward_once(face1_tensor).cpu().numpy()
|
| 183 |
+
|
| 184 |
+
# Ensure embedding is 2D for sklearn
|
| 185 |
+
if embedding_np.ndim == 1:
|
| 186 |
+
embedding_np = embedding_np.reshape(1, -1)
|
| 187 |
|
| 188 |
# 3. Load Sklearn Scaler and Classifier (Joblib)
|
| 189 |
try:
|
app/Hackathon_setup/face_recognition_model.py
CHANGED
|
@@ -14,11 +14,43 @@ trnscm = transforms.Compose([transforms.Resize((100,100)), transforms.ToTensor()
|
|
| 14 |
class Siamese(torch.nn.Module):
|
| 15 |
def __init__(self):
|
| 16 |
super(Siamese, self).__init__()
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
##########################################################################################################
|
| 24 |
## Sample classification network (Specify if you are using a pytorch classifier during the training) ##
|
|
@@ -28,102 +60,4 @@ class Siamese(torch.nn.Module):
|
|
| 28 |
# YOUR CODE HERE for pytorch classifier
|
| 29 |
|
| 30 |
# Definition of classes as dictionary
|
| 31 |
-
classes = ['person1','person2','person3','person4','person5','person6','person7']
|
| 32 |
-
def get_similarity(img1, img2):
|
| 33 |
-
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
| 34 |
-
|
| 35 |
-
det_img1 = detected_face(img1)
|
| 36 |
-
det_img2 = detected_face(img2)
|
| 37 |
-
if(det_img1 == 0 or det_img2 == 0):
|
| 38 |
-
det_img1 = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))
|
| 39 |
-
det_img2 = Image.fromarray(cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY))
|
| 40 |
-
face1 = trnscm(det_img1).unsqueeze(0)
|
| 41 |
-
face2 = trnscm(det_img2).unsqueeze(0)
|
| 42 |
-
##########################################################################################
|
| 43 |
-
##Example for loading a model using weight state dictionary: ##
|
| 44 |
-
## feature_net = light_cnn() #Example Network ##
|
| 45 |
-
## model = torch.load(current_path + '/siamese_model.t7', map_location=device) ##
|
| 46 |
-
## feature_net.load_state_dict(model['net_dict']) ##
|
| 47 |
-
## ##
|
| 48 |
-
##current_path + '/<network_definition>' is path of the saved model if present in ##
|
| 49 |
-
##the same path as this file, we recommend to put in the same directory ##
|
| 50 |
-
##########################################################################################
|
| 51 |
-
##########################################################################################
|
| 52 |
-
|
| 53 |
-
# YOUR CODE HERE, load the model
|
| 54 |
-
|
| 55 |
-
# YOUR CODE HERE, return similarity measure using your model
|
| 56 |
-
# 1. Initialize and Load Siamese Network
|
| 57 |
-
try:
|
| 58 |
-
# Assuming your Siamese Network class is named 'SiameseNetwork'
|
| 59 |
-
siamese_net = SiameseNetwork().to(device)
|
| 60 |
-
siamese_net.load_state_dict(torch.load(SIAMESE_MODEL_PATH, map_location=device))
|
| 61 |
-
siamese_net.eval()
|
| 62 |
-
except Exception as e:
|
| 63 |
-
print(f"Error loading Siamese Model: {e}")
|
| 64 |
-
return -1 # Return error code
|
| 65 |
-
|
| 66 |
-
# 2. Get Features (Embeddings)
|
| 67 |
-
with torch.no_grad():
|
| 68 |
-
# Get the feature vector from one tower/forward_once method
|
| 69 |
-
# Ensure your SiameseNetwork class has a forward_once or get_embedding method
|
| 70 |
-
embed1 = siamese_net.forward_once(face1).cpu().numpy()
|
| 71 |
-
embed2 = siamese_net.forward_once(face2).cpu().numpy()
|
| 72 |
-
|
| 73 |
-
# 3. Calculate Similarity Measure
|
| 74 |
-
# The Euclidean distance is the fundamental metric used by the Triplet/Contrastive loss.
|
| 75 |
-
# We return the NEGATIVE Euclidean distance or COSINE similarity, as *higher* value usually means *more* similar.
|
| 76 |
-
|
| 77 |
-
# Option A: Euclidean Distance (Lower is better) -> return NEGATIVE distance for API expectation
|
| 78 |
-
# distance = euclidean_distances(embed1, embed2)[0][0]
|
| 79 |
-
# similarity = -distance
|
| 80 |
-
|
| 81 |
-
# Option B: Cosine Similarity (Higher is better) -> Recommended
|
| 82 |
-
similarity = cosine_similarity(embed1, embed2)[0][0]
|
| 83 |
-
|
| 84 |
-
return float(similarity)
|
| 85 |
-
|
| 86 |
-
def get_face_class(img1):
|
| 87 |
-
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
| 88 |
-
|
| 89 |
-
det_img1 = detected_face(img1)
|
| 90 |
-
if(det_img1 == 0):
|
| 91 |
-
det_img1 = Image.fromarray(cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY))
|
| 92 |
-
##YOUR CODE HERE, return face class here
|
| 93 |
-
##Hint: you need a classifier finetuned for your classes, it takes o/p of siamese as i/p to it
|
| 94 |
-
##Better Hint: Siamese experiment is covered in one of the labs
|
| 95 |
-
face1_tensor = trnscm(det_img1).unsqueeze(0).to(device)
|
| 96 |
-
|
| 97 |
-
# 1. Load Siamese Network (Feature Extractor)
|
| 98 |
-
try:
|
| 99 |
-
siamese_net = SiameseNetwork().to(device)
|
| 100 |
-
siamese_net.load_state_dict(torch.load(SIAMESE_MODEL_PATH, map_location=device))
|
| 101 |
-
siamese_net.eval()
|
| 102 |
-
except Exception as e:
|
| 103 |
-
return f"Error loading Siamese Model get_face_class: {e}"
|
| 104 |
-
|
| 105 |
-
# 2. Extract Embedding
|
| 106 |
-
with torch.no_grad():
|
| 107 |
-
embedding_np = siamese_net.forward_once(face1_tensor).cpu().numpy()
|
| 108 |
-
|
| 109 |
-
# 3. Load Sklearn Scaler and Classifier (Joblib)
|
| 110 |
-
try:
|
| 111 |
-
knn_classifier = joblib.load(KNN_CLASSIFIER_PATH)
|
| 112 |
-
scaler = joblib.load(SCALER_PATH)
|
| 113 |
-
except Exception as e:
|
| 114 |
-
return f"Error loading Sklearn models: {e}"
|
| 115 |
-
|
| 116 |
-
# 4. Preprocess Embedding and Predict
|
| 117 |
-
# The embedding must be reshaped to (1, N_features) for the scaler
|
| 118 |
-
embedding_scaled = scaler.transform(embedding_np.reshape(1, -1))
|
| 119 |
-
|
| 120 |
-
# Perform prediction (returns a NumPy array with the predicted label index)
|
| 121 |
-
predicted_label_index = knn_classifier.predict(embedding_scaled)[0]
|
| 122 |
-
|
| 123 |
-
# 5. Map index to Class Name
|
| 124 |
-
if predicted_label_index < len(CLASS_NAMES):
|
| 125 |
-
predicted_class_name = CLASS_NAMES[predicted_label_index]
|
| 126 |
-
else:
|
| 127 |
-
predicted_class_name = "UNKNOWN_CLASS"
|
| 128 |
-
|
| 129 |
-
return predicted_class_name
|
|
|
|
| 14 |
class Siamese(torch.nn.Module):
|
| 15 |
def __init__(self):
|
| 16 |
super(Siamese, self).__init__()
|
| 17 |
+
self.cnn1 = nn.Sequential(
|
| 18 |
+
nn.ReflectionPad2d(1), #Pads the input tensor using the reflection of the input boundary, it similar to the padding.
|
| 19 |
+
nn.Conv2d(1, 4, kernel_size=3),
|
| 20 |
+
nn.ReLU(inplace=True),
|
| 21 |
+
nn.BatchNorm2d(4),
|
| 22 |
+
|
| 23 |
+
nn.ReflectionPad2d(1),
|
| 24 |
+
nn.Conv2d(4, 8, kernel_size=3),
|
| 25 |
+
nn.ReLU(inplace=True),
|
| 26 |
+
nn.BatchNorm2d(8),
|
| 27 |
+
|
| 28 |
+
nn.ReflectionPad2d(1),
|
| 29 |
+
nn.Conv2d(8, 8, kernel_size=3),
|
| 30 |
+
nn.ReLU(inplace=True),
|
| 31 |
+
nn.BatchNorm2d(8),
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
self.fc1 = nn.Sequential(
|
| 35 |
+
nn.Linear(8*100*100, 500),
|
| 36 |
+
nn.ReLU(inplace=True),
|
| 37 |
+
|
| 38 |
+
nn.Linear(500, 500),
|
| 39 |
+
nn.ReLU(inplace=True),
|
| 40 |
+
|
| 41 |
+
nn.Linear(500, 5))
|
| 42 |
+
|
| 43 |
+
# forward_once is for one image. This can be used while classifying the face images
|
| 44 |
+
def forward_once(self, x):
|
| 45 |
+
output = self.cnn1(x)
|
| 46 |
+
output = output.view(output.size()[0], -1)
|
| 47 |
+
output = self.fc1(output)
|
| 48 |
+
return output
|
| 49 |
+
|
| 50 |
+
def forward(self, input1, input2):
|
| 51 |
+
output1 = self.forward_once(input1)
|
| 52 |
+
output2 = self.forward_once(input2)
|
| 53 |
+
return output1, output2
|
| 54 |
|
| 55 |
##########################################################################################################
|
| 56 |
## Sample classification network (Specify if you are using a pytorch classifier during the training) ##
|
|
|
|
| 60 |
# YOUR CODE HERE for pytorch classifier
|
| 61 |
|
| 62 |
# Definition of classes as dictionary
|
| 63 |
+
classes = ['person1','person2','person3','person4','person5','person6','person7']
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/Hackathon_setup/inspect_model.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Script to inspect the saved model structure
|
| 3 |
+
"""
|
| 4 |
+
|
| 5 |
+
import torch
|
| 6 |
+
import os
|
| 7 |
+
|
| 8 |
+
def inspect_model():
|
| 9 |
+
"""Inspect the structure of the saved model"""
|
| 10 |
+
model_path = 'siamese_model.t7'
|
| 11 |
+
|
| 12 |
+
if not os.path.exists(model_path):
|
| 13 |
+
print(f"Model file {model_path} not found!")
|
| 14 |
+
return
|
| 15 |
+
|
| 16 |
+
try:
|
| 17 |
+
# Load the model
|
| 18 |
+
model_data = torch.load(model_path, map_location='cpu')
|
| 19 |
+
|
| 20 |
+
print("Model file loaded successfully!")
|
| 21 |
+
print(f"Type: {type(model_data)}")
|
| 22 |
+
|
| 23 |
+
if isinstance(model_data, dict):
|
| 24 |
+
print("\nDictionary keys:")
|
| 25 |
+
for key in model_data.keys():
|
| 26 |
+
print(f" - {key}")
|
| 27 |
+
|
| 28 |
+
if 'net_dict' in model_data:
|
| 29 |
+
print(f"\n'net_dict' contains {len(model_data['net_dict'])} items:")
|
| 30 |
+
for key in list(model_data['net_dict'].keys())[:10]: # Show first 10 keys
|
| 31 |
+
print(f" - {key}")
|
| 32 |
+
if len(model_data['net_dict']) > 10:
|
| 33 |
+
print(f" ... and {len(model_data['net_dict']) - 10} more keys")
|
| 34 |
+
else:
|
| 35 |
+
print("Model data is not a dictionary")
|
| 36 |
+
|
| 37 |
+
except Exception as e:
|
| 38 |
+
print(f"Error loading model: {e}")
|
| 39 |
+
|
| 40 |
+
if __name__ == "__main__":
|
| 41 |
+
inspect_model()
|
app/Hackathon_setup/test_cosine_similarity.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""
|
| 2 |
+
Test script to demonstrate cosine similarity for face recognition
|
| 3 |
+
This script shows how to use the implemented cosine similarity functionality
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import sys
|
| 7 |
+
import os
|
| 8 |
+
import traceback
|
| 9 |
+
|
| 10 |
+
# Add current directory to path to ensure imports work
|
| 11 |
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
| 12 |
+
sys.path.insert(0, current_dir)
|
| 13 |
+
|
| 14 |
+
try:
|
| 15 |
+
import numpy as np
|
| 16 |
+
import cv2
|
| 17 |
+
import torch
|
| 18 |
+
from sklearn.metrics.pairwise import cosine_similarity
|
| 19 |
+
print("OK: All required packages imported successfully")
|
| 20 |
+
except ImportError as e:
|
| 21 |
+
print(f"✗ Import Error: {e}")
|
| 22 |
+
print("Please install missing packages:")
|
| 23 |
+
print("pip install numpy opencv-python torch scikit-learn matplotlib")
|
| 24 |
+
sys.exit(1)
|
| 25 |
+
|
| 26 |
+
try:
|
| 27 |
+
from face_recognition import get_similarity, get_face_class
|
| 28 |
+
print("OK: Face recognition module imported successfully")
|
| 29 |
+
except ImportError as e:
|
| 30 |
+
print(f"✗ Error importing face_recognition module: {e}")
|
| 31 |
+
print("Make sure face_recognition.py is in the same directory")
|
| 32 |
+
sys.exit(1)
|
| 33 |
+
|
| 34 |
+
def check_model_files():
|
| 35 |
+
"""
|
| 36 |
+
Check if required model files exist
|
| 37 |
+
"""
|
| 38 |
+
print("Checking for required model files...")
|
| 39 |
+
model_files = [
|
| 40 |
+
'siamese_model.t7',
|
| 41 |
+
'decision_tree_model.sav',
|
| 42 |
+
'face_recognition_scaler.sav'
|
| 43 |
+
]
|
| 44 |
+
|
| 45 |
+
missing_files = []
|
| 46 |
+
for file in model_files:
|
| 47 |
+
if os.path.exists(file):
|
| 48 |
+
print(f"OK: Found {file}")
|
| 49 |
+
else:
|
| 50 |
+
print(f"ERROR: Missing {file}")
|
| 51 |
+
missing_files.append(file)
|
| 52 |
+
|
| 53 |
+
if missing_files:
|
| 54 |
+
print(f"\nWARNING: Missing {len(missing_files)} model files!")
|
| 55 |
+
print("You need to train and save these models first.")
|
| 56 |
+
return False
|
| 57 |
+
else:
|
| 58 |
+
print("OK: All model files found!")
|
| 59 |
+
return True
|
| 60 |
+
|
| 61 |
+
def test_cosine_similarity():
|
| 62 |
+
"""
|
| 63 |
+
Test function to demonstrate cosine similarity between faces
|
| 64 |
+
"""
|
| 65 |
+
print("\nTesting Cosine Similarity for Face Recognition")
|
| 66 |
+
print("=" * 50)
|
| 67 |
+
|
| 68 |
+
# Check if model files exist first
|
| 69 |
+
if not check_model_files():
|
| 70 |
+
print("Skipping similarity test due to missing model files.")
|
| 71 |
+
return
|
| 72 |
+
|
| 73 |
+
# Create sample test images (you can replace these with actual face images)
|
| 74 |
+
# For demonstration, we'll create random images
|
| 75 |
+
img1 = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
|
| 76 |
+
img2 = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
|
| 77 |
+
|
| 78 |
+
print("Sample images created for testing...")
|
| 79 |
+
|
| 80 |
+
try:
|
| 81 |
+
print("Calling get_similarity function...")
|
| 82 |
+
# Test cosine similarity
|
| 83 |
+
similarity_score = get_similarity(img1, img2)
|
| 84 |
+
print(f"Cosine Similarity Score: {similarity_score:.4f}")
|
| 85 |
+
|
| 86 |
+
# Interpret the similarity score
|
| 87 |
+
if similarity_score > 0.8:
|
| 88 |
+
print("Result: Very High Similarity (likely same person)")
|
| 89 |
+
elif similarity_score > 0.6:
|
| 90 |
+
print("Result: High Similarity (possibly same person)")
|
| 91 |
+
elif similarity_score > 0.4:
|
| 92 |
+
print("Result: Moderate Similarity (uncertain)")
|
| 93 |
+
elif similarity_score > 0.2:
|
| 94 |
+
print("Result: Low Similarity (likely different persons)")
|
| 95 |
+
else:
|
| 96 |
+
print("Result: Very Low Similarity (definitely different persons)")
|
| 97 |
+
|
| 98 |
+
except Exception as e:
|
| 99 |
+
print(f"ERROR: Error during similarity calculation: {e}")
|
| 100 |
+
print("Full error details:")
|
| 101 |
+
traceback.print_exc()
|
| 102 |
+
print("\nTroubleshooting tips:")
|
| 103 |
+
print("1. Make sure your model files are properly trained and saved")
|
| 104 |
+
print("2. Check that PyTorch is installed correctly")
|
| 105 |
+
print("3. Verify the model architecture matches your saved model")
|
| 106 |
+
|
| 107 |
+
print("\n" + "=" * 50)
|
| 108 |
+
print("Cosine Similarity Test Complete!")
|
| 109 |
+
print("\nKey Points about Cosine Similarity:")
|
| 110 |
+
print("- Range: -1 to +1")
|
| 111 |
+
print("- +1: Identical faces (same person)")
|
| 112 |
+
print("- 0: No similarity (orthogonal vectors)")
|
| 113 |
+
print("- -1: Completely opposite (different persons)")
|
| 114 |
+
print("- Values closer to +1 indicate higher similarity")
|
| 115 |
+
|
| 116 |
+
def test_face_classification():
|
| 117 |
+
"""
|
| 118 |
+
Test function to demonstrate face classification
|
| 119 |
+
"""
|
| 120 |
+
print("\nTesting Face Classification")
|
| 121 |
+
print("=" * 30)
|
| 122 |
+
|
| 123 |
+
# Check if model files exist first
|
| 124 |
+
if not check_model_files():
|
| 125 |
+
print("Skipping classification test due to missing model files.")
|
| 126 |
+
return
|
| 127 |
+
|
| 128 |
+
# Create sample test image
|
| 129 |
+
img = np.random.randint(0, 255, (100, 100, 3), dtype=np.uint8)
|
| 130 |
+
|
| 131 |
+
try:
|
| 132 |
+
print("Calling get_face_class function...")
|
| 133 |
+
# Test face classification
|
| 134 |
+
predicted_class = get_face_class(img)
|
| 135 |
+
print(f"Predicted Face Class: {predicted_class}")
|
| 136 |
+
|
| 137 |
+
except Exception as e:
|
| 138 |
+
print(f"ERROR: Error during face classification: {e}")
|
| 139 |
+
print("Full error details:")
|
| 140 |
+
traceback.print_exc()
|
| 141 |
+
print("\nTroubleshooting tips:")
|
| 142 |
+
print("1. Make sure your classifier and scaler files are properly trained")
|
| 143 |
+
print("2. Check that joblib is installed correctly")
|
| 144 |
+
print("3. Verify the scaler was trained on the same embedding format")
|
| 145 |
+
|
| 146 |
+
if __name__ == "__main__":
|
| 147 |
+
# Run the tests
|
| 148 |
+
test_cosine_similarity()
|
| 149 |
+
test_face_classification()
|
| 150 |
+
|
| 151 |
+
print("\n" + "=" * 60)
|
| 152 |
+
print("IMPORTANT NOTES:")
|
| 153 |
+
print("1. This is a demonstration with random images")
|
| 154 |
+
print("2. For real testing, use actual face images")
|
| 155 |
+
print("3. Make sure your model files are trained and saved:")
|
| 156 |
+
print(" - siamese_model.t7")
|
| 157 |
+
print(" - decision_tree_model.sav")
|
| 158 |
+
print(" - face_recognition_scaler.sav")
|
| 159 |
+
print("4. The cosine similarity will work best with properly trained models")
|