### Install DeepFace from Source Source: https://github.com/serengil/deepface/blob/master/README.md Clone the repository and install DeepFace from its source code to access the latest features not yet published on PyPI. ```shell $ git clone https://github.com/serengil/deepface.git $ cd deepface $ pip install -e . ``` -------------------------------- ### Install DeepFace from PyPI Source: https://github.com/serengil/deepface/blob/master/README.md Use this command to install the DeepFace library and its prerequisites from the Python Package Index. ```shell $ pip install deepface ``` -------------------------------- ### Run DeepFace API Service Source: https://github.com/serengil/deepface/blob/master/README.md Commands to start the DeepFace API service. Use `./service.sh` for direct execution or `./dockerize.sh` for Docker-based deployment. ```shell cd scripts && ./service.sh ``` ```shell cd scripts && ./dockerize.sh ``` -------------------------------- ### Print Experiment Configuration Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Outputs the selected facial recognition model and detector backend to the console, indicating the start of a specific experiment. ```python print(f"Running an experiment for {model_name} & {detector_backend}...") ``` -------------------------------- ### Display DeepFace Version Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Prints the installed version of the DeepFace library. This is useful for reproducibility and debugging. ```python print(f"This experiment is done with pip package of deepface with {DeepFace.__version__} version") ``` -------------------------------- ### Import DeepFace Library Source: https://github.com/serengil/deepface/blob/master/README.md Import the DeepFace class to start using its functionalities in your Python project. ```python from deepface import DeepFace ``` -------------------------------- ### Register Face with DeepFace API Source: https://github.com/serengil/deepface/blob/master/README.md Example cURL command to register a face using the 'register' endpoint. Requires a model name and image path. ```shell $ curl -X POST http://localhost:5005/register \ -d '{"model_name":"Facenet", "img":"img18.jpg"}' ``` -------------------------------- ### Import Dependencies for DeepFace Experiments Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Imports necessary libraries for the experiments, including DeepFace, NumPy, Pandas, Matplotlib, and scikit-learn. Ensure these packages are installed. ```python # built-in dependencies import os # 3rd party dependencies import numpy as np import pandas as pd from tqdm import tqdm import matplotlib.pyplot as plt from sklearn.metrics import accuracy_score from sklearn.datasets import fetch_lfw_pairs from deepface import DeepFace ``` -------------------------------- ### Verify Face Identity with DeepFace API Source: https://github.com/serengil/deepface/blob/master/README.md Example cURL command for face verification using the 'verify' endpoint. Provide paths for two images to compare. ```shell $ curl -X POST http://localhost:5005/verify \ -d '{"img1":"img1.jpg", "img2":"img3.jpg"}' ``` -------------------------------- ### Get Face Embeddings with DeepFace API Source: https://github.com/serengil/deepface/blob/master/README.md Example cURL command to get facial embeddings using the 'represent' endpoint. Specify the model name and image path. ```shell $ curl -X POST http://localhost:5005/represent \ -d '{"model_name":"Facenet", "img":"img1.jpg"}' ``` -------------------------------- ### Generate Negative Sample Pairs Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Generates pairs of images that belong to different people. These are used as negative examples. Requires itertools for product and pandas for DataFrame creation. ```python samples_list = list(idendities.values()) negatives = [] for i in range(0, len(idendities) - 1): for j in range(i+1, len(idendities)): cross_product = itertools.product(samples_list[i], samples_list[j]) cross_product = list(cross_product) for cross_sample in cross_product: negative = [] negative.append(cross_sample[0]) negative.append(cross_sample[1]) negatives.append(negative) negatives = pd.DataFrame(negatives, columns = ["file_x", "file_y"]) negatives["actual"] = "Different Persons" ``` -------------------------------- ### Generate Positive Sample Pairs Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Generates pairs of images that belong to the same person. These are used as positive examples in the dataset. Requires pandas for DataFrame creation. ```python positives = [] for key, values in idendities.items(): for i in range(0, len(values)-1): for j in range(i+1, len(values)): positive = [] positive.append(values[i]) positive.append(values[j]) positives.append(positive) positives = pd.DataFrame(positives, columns = ["file_x", "file_y"]) positives["actual"] = "Same Person" ``` -------------------------------- ### Stream Real-time Video with DeepFace Source: https://github.com/serengil/deepface/blob/master/README.md Initiates real-time video analysis by accessing the webcam. It applies face recognition and facial attribute analysis, starting analysis when a face is detected for 5 consecutive frames and displaying results for 5 seconds. ```python DeepFace.stream(db_path = "C:/database") ``` -------------------------------- ### Search Face in Database with DeepFace API Source: https://github.com/serengil/deepface/blob/master/README.md Example cURL command to search for a face within a registered database using the 'search' endpoint. Specify the image and model name. ```shell $ curl -X POST http://localhost:5005/search \ -d '{"img":"img1.jpg", "model_name":"Facenet"}' ``` -------------------------------- ### Analyze Facial Attributes with DeepFace API Source: https://github.com/serengil/deepface/blob/master/README.md Example cURL command to analyze facial attributes like age and gender using the 'analyze' endpoint. Specify the image and desired actions. ```shell $ curl -X POST http://localhost:5005/analyze \ -d '{"img": "img2.jpg", "actions": ["age", "gender"]}' ``` -------------------------------- ### Load LFW Dataset or Use Existing Files Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Loads the LFW test dataset using `fetch_lfw_pairs` or loads pre-saved NumPy arrays if they exist. This step prepares the image pairs and labels for the experiments. ```python target_path = "dataset/test_lfw.npy" labels_path = "dataset/test_labels.npy" if os.path.exists(target_path) != True: fetch_lfw_pairs = fetch_lfw_pairs(subset = 'test', color = True , resize = 2 , funneled = False , slice_=None ) pairs = fetch_lfw_pairs.pairs labels = fetch_lfw_pairs.target target_names = fetch_lfw_pairs.target_names np.save(target_path, pairs) np.save(labels_path, labels) else: if not os.path.exists(pairs_touch): # loading pairs takes some time. but if we extract these pairs as image, no need to load it anymore pairs = np.load(target_path) labels = np.load(labels_path) ``` -------------------------------- ### Create Output and Dataset Folders Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Creates necessary directories for storing experiment outputs and datasets if they do not already exist. This ensures the experiment has a place to save its results. ```python target_paths = ["lfwe", "dataset", "outputs", "outputs/test", "results"] for target_path in target_paths: if not os.path.exists(target_path): os.mkdir(target_path) print(f"{target_path} is just created") ``` -------------------------------- ### Get Training Data Shape Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Retrieves the shape of the training data. Useful for understanding the dimensions of the dataset before further processing. ```python dfs["train"].shape ``` -------------------------------- ### Set Experiment Configuration Variables Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Sets up initial configuration variables for the experiment, including a random seed, the detector backend, and a flag to control data augmentation for training. ```python seed = 17 detector_backend = "retinaface" more_train = False # append some of validation data into train ``` -------------------------------- ### SHAP Explainer and Values Calculation Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Initializes a SHAP explainer for the trained LightGBM model and calculates SHAP values for the test dataset. ```python explainer = shap.Explainer(gbms[winner_id]) shap_values = explainer(x_test) ``` -------------------------------- ### Prepare LightGBM Datasets Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Prepares training, testing, and validation datasets for LightGBM. It separates features and labels and specifies categorical features. ```python feature_names = list(dfs["train"].drop(columns=["actuals"]).columns) y_train = dfs["train"]["actuals"].values x_train = dfs["train"].drop(columns=["actuals"]).values y_test = dfs["test"]["actuals"].values x_test = dfs["test"].drop(columns=["actuals"]).values y_val = dfs["10_folds"]["actuals"].values x_val = dfs["10_folds"].drop(columns=["actuals"]).values lgb_train = lgb.Dataset( x_train, y_train, feature_name = feature_names, categorical_feature = categorical_features, free_raw_data=False ) lgb_test = lgb.Dataset( x_test, y_test, feature_name = feature_names, categorical_feature = categorical_features, free_raw_data=False ) ``` -------------------------------- ### Create Directories for Experiment Data Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Ensures all required directories for storing dataset, results, and models are present. Creates them if they do not exist. ```python target_paths = [ "lfwe", "lfwe/test", "lfwe/train", "lfwe/10_folds", "dataset", "outputs", "outputs/test", "outputs/train", "outputs/10_folds", "results", "models", ] for target_path in target_paths: if os.path.exists(target_path) is not True: os.mkdir(target_path) print(f"{target_path} is just created") ``` -------------------------------- ### Create Folders for Experiment Data Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Ensures that all required directories for storing dataset, LFW images, and experiment outputs are created if they do not already exist. ```python target_paths = [ "lfwe", "lfwe/test", "lfwe/train", "lfwe/10_folds", "dataset", "outputs", "outputs/test", "outputs/train", "outputs/10_folds", "results" ] for target_path in target_paths: if os.path.exists(target_path) != True: os.mkdir(target_path) print(f"{target_path} is just created") ``` -------------------------------- ### Define XGBoost Parameters Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Sets up a dictionary of hyperparameters for the XGBoost model, including learning rate, tree depth, and number of estimators. ```python params = { 'learning_rate': 0.01 , 'max_depth': 5 , 'max_leaves': pow(2, 5) - 1 , 'n_estimators': 10000 , 'seed': 17 , 'nthread': 2 , 'object': 'binary:logistic' } ``` -------------------------------- ### DeepFace Core Functions with Detector Backend Source: https://github.com/serengil/deepface/blob/master/README.md Demonstrates the usage of core DeepFace functions like verify, find, represent, analyze, and extract_faces, allowing selection of different detector backends and alignment options. ```python backends = [ 'opencv', 'ssd', 'dlib', 'mtcnn', 'fastmtcnn', 'retinaface', 'mediapipe', 'yolov8n', 'yolov8m', 'yolov8l', 'yolov11n', 'yolov11s', 'yolov11m', 'yolov11l', 'yolov12n', 'yolov12s', 'yolov12m', 'yolov12l', 'yunet', 'centerface', ] detector = backends[3] align = True obj = DeepFace.verify( img1_path = "img1.jpg", img2_path = "img2.jpg", detector_backend = detector, align = align ) dfs = DeepFace.find( img_path = "img.jpg", db_path = "my_db", detector_backend = detector, align = align ) embedding_objs = DeepFace.represent( img_path = "img.jpg", detector_backend = detector, align = align ) demographies = DeepFace.analyze( img_path = "img4.jpg", detector_backend = detector, align = align ) face_objs = DeepFace.extract_faces( img_path = "img.jpg", detector_backend = detector, align = align ) ``` -------------------------------- ### Retrieve and Prepare LFW Dataset Pairs Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Fetches LFW pairs and labels for specified tasks (test, train, 10_folds), saves them to disk, and extracts/saves individual images to the 'lfwe' directory. Handles potential memory issues by adjusting resize for '10_folds'. ```python def retrieve_lfe(task: str): if task == "test": instances = 1000 elif task == "train": instances = 2200 elif task == "10_folds": instances = 6000 else: raise ValueError(f"unimplemented task - {task}") pairs_touch = f"outputs/{task}_lfwe.txt" target_path = f"dataset/{task}_lfw.npy" labels_path = f"dataset/{task}_labels.npy" if os.path.exists(target_path) != True: fetched_lfw_pairs = fetch_lfw_pairs( subset = task, color = True, # memory allocation problem occurs for validation set resize = 2 if task != "10_folds" else 1, funneled = False, slice_=None, ) print("fetched") pairs = fetched_lfw_pairs.pairs labels = fetched_lfw_pairs.target # target_names = fetched_lfw_pairs.target_names np.save(target_path, pairs) np.save(labels_path, labels) else: if os.path.exists(pairs_touch) != True: # loading pairs takes some time. but if we extract these pairs as image, no need to load it anymore pairs = np.load(target_path) labels = np.load(labels_path) # store to file system for i in tqdm(range(0, instances)): img1_target = f"lfwe/{task}/{i}_1.jpg" img2_target = f"lfwe/{task}/{i}_2.jpg" if os.path.exists(img1_target) != True: img1 = pairs[i][0] # plt.imsave(img1_target, img1/255) #works for my mac plt.imsave(img1_target, img1) #works for my debian if os.path.exists(img2_target) != True: img2 = pairs[i][1] # plt.imsave(img2_target, img2/255) #works for my mac plt.imsave(img2_target, img2) #works for my debian if os.path.exists(pairs_touch) != True: open(pairs_touch,'a').close() ``` -------------------------------- ### Define Experiment Configuration Parameters Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Sets up configuration variables for the experiments, including alignment options, facial recognition models, face detectors, distance metrics, and expansion percentage. ```python # all configuration alternatives for 4 dimensions of arguments alignment = [True, False] models = ["Facenet512", "Facenet", "VGG-Face", "ArcFace", "Dlib", "GhostFaceNet", "SFace", "OpenFace", "DeepFace", "DeepID"] detectors = ["retinaface", "mtcnn", "fastmtcnn", "dlib", "yolov8", "yunet", "centerface", "mediapipe", "ssd", "opencv", "skip"] metrics = ["euclidean", "euclidean_l2", "cosine"] expand_percentage = 0 ``` -------------------------------- ### Define Model and Distance Metric Options Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Sets up lists of available facial recognition models and distance metrics to be used in experiments. The detector backend is also specified. ```python detector_backend = "mtcnn" # a robust one model_names = [ "VGG-Face", "Facenet", "Facenet512", "ArcFace", "GhostFaceNet", "Dlib", "SFace", "OpenFace", "DeepFace", "DeepID", "Buffalo_L" ] distance_metrics = [ "cosine", "euclidean", "euclidean_l2", "angular", ] ``` -------------------------------- ### Retrieve and Prepare LFW Dataset Pairs Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Fetches LFW dataset pairs, saves them as numpy arrays, and extracts images to disk. Handles different instance counts for test, train, and 10_folds tasks. ```python def retrieve_lfe(task: str): if task == "test": instances = 1000 elif task == "train": instances = 2200 elif task == "10_folds": instances = 6000 else: raise ValueError(f"unimplemented task - {task}") pairs_touch = f"outputs/{task}_lfwe.txt" target_path = f"dataset/{task}_lfw.npy" labels_path = f"dataset/{task}_labels.npy" if os.path.exists(target_path) != True: fetched_lfw_pairs = fetch_lfw_pairs( subset = task, color = True, # memory allocation problem occurs for validation set resize = 2 if task != "10_folds" else 1, funneled = False, slice_=None, ) print("fetched") pairs = fetched_lfw_pairs.pairs labels = fetched_lfw_pairs.target # target_names = fetched_lfw_pairs.target_names np.save(target_path, pairs) np.save(labels_path, labels) else: if os.path.exists(pairs_touch) != True: # loading pairs takes some time. but if we extract these pairs as image, no need to load it anymore pairs = np.load(target_path) labels = np.load(labels_path) # store to file system for i in tqdm(range(0, instances)): img1_target = f"lfwe/{task}/{i}_1.jpg" img2_target = f"lfwe/{task}/{i}_2.jpg" if os.path.exists(img1_target) != True: img1 = pairs[i][0] # plt.imsave(img1_target, img1/255) #works for my mac plt.imsave(img1_target, img1) #works for my debian if os.path.exists(img2_target) != True: img2 = pairs[i][1] # plt.imsave(img2_target, img2/255) #works for my mac plt.imsave(img2_target, img2) #works for my debian if os.path.exists(pairs_touch) != True: open(pairs_touch,'a').close() ``` ```python retrieve_lfe(task = "test") retrieve_lfe(task = "train") retrieve_lfe(task = "10_folds") ``` -------------------------------- ### Perform Experiments with XGBoost Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Initiates the experiment execution. This function likely orchestrates the training and evaluation of XGBoost models. ```python perform_experiments() ``` -------------------------------- ### Define Experiment Alternatives Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Sets up lists of alternative configurations for various experimental dimensions, including alignment, facial recognition models, detectors, and distance metrics. ```python # all configuration alternatives for 4 dimensions of arguments alignment = [True] models = ["Facenet", "Facenet512", "VGG-Face", "ArcFace", "Dlib"] # 99.1 detectors = ["retinaface"] metrics = ["euclidean_l2"] expand_percentage = 0 # TODO: find increase impact ``` -------------------------------- ### DeepFace Similarity Verification with Different Metrics Source: https://github.com/serengil/deepface/blob/master/README.md Illustrates how to use the DeepFace.verify and DeepFace.find functions with different distance metrics for face similarity comparison. Supported metrics include cosine, euclidean, euclidean_l2, and angular. ```python metrics = ["cosine", "euclidean", "euclidean_l2", "angular"] result = DeepFace.verify( img1_path = "img1.jpg", img2_path = "img2.jpg", distance_metric = metrics[1] ) dfs = DeepFace.find( img_path = "img1.jpg", db_path = "C:/my_db", distance_metric = metrics[2] ) ``` -------------------------------- ### Visualize Learning Curves with LightGBM Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Plot the training and validation loss for each fold up to the best iteration. This helps in understanding model convergence and identifying overfitting or underfitting. ```python if learning_curves: for i in range(0, k+1): if multiclass is True: training_loss = learning_curves[i]["training"]["multi_logloss"] validation_loss = learning_curves[i]["valid_1"]["multi_logloss"] else: training_loss = learning_curves[i]["training"]["binary_logloss"] validation_loss = learning_curves[i]["valid_1"]["binary_logloss"] # fold_idx = winner_id # fold_idx = 9 fold_idx = i best_iter = best_iterations[fold_idx] plt.plot(training_loss[:best_iter], label='Training loss') plt.plot(validation_loss[:best_iter], label='Validation loss') plt.xlabel('Iterations') plt.ylabel('Binary Logloss') plt.title(f'Training and Validation Loss in fold {fold_idx+1}') plt.legend() plt.show() ``` -------------------------------- ### Prepare Data for XGBoost Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Extracts training, validation, and testing data from a DataFrame. Assumes 'actuals' is the target column. ```python y_train = dfs["train"]["actuals"].values x_train = dfs["train"].drop(columns=["actuals"]).values y_test = dfs["test"]["actuals"].values x_test = dfs["test"].drop(columns=["actuals"]).values y_val = dfs["10_folds"]["actuals"].values x_val = dfs["10_folds"].drop(columns=["actuals"]).values ``` -------------------------------- ### Sample Training DataFrame Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Displays a random sample of 5 rows from the training DataFrame, including original distances, classification results, sums, and multiplications. Useful for inspecting the processed data. ```python dfs["train"].sample(5) ``` -------------------------------- ### Display Performance Tables Source: https://github.com/serengil/deepface/blob/master/benchmarks/Evaluate-Results.ipynb Iterates through distance metrics and alignment options, reads corresponding CSV results, and displays them as HTML tables. Requires results to be pre-computed and saved as CSV files. ```python for align in alignment: for metric in distance_metrics: df = pd.read_csv(f"results/pivot_{metric}_with_alignment_{align}.csv") df = df.rename(columns = {'Unnamed: 0': 'detector'}) df = df.set_index('detector') print(f"{metric} for alignment {align}") display(HTML(df.to_html())) display(HTML("
")) ``` -------------------------------- ### Set LFW Test Pair File and Instance Count Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Defines the path for the LFW test pairs file and the number of instances to process. This prepares for loading and saving LFW data. ```python pairs_touch = "outputs/test_lfwe.txt" instances = 1000 #pairs.shape[0] ``` -------------------------------- ### Perform DeepFace Verification Experiments Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Iterates through different models, detector backends, distance metrics, and alignment options to calculate and store verification distances. Skips alignment if detector backend is 'skip'. ```python def perform_experiments(): for model_name in models: for detector_backend in detectors: for distance_metric in metrics: for align in alignment: if detector_backend == "skip" and align is True: # Alignment is not possible for a skipped detector configuration continue calculate_distances( model_name=model_name, detector_backend=detector_backend, distance_metric=distance_metric, align=align, ) def calculate_distances( model_name: str, detector_backend: str, distance_metric: str = "euclidean_l2", align: bool = True ): for experiment in ["test", "train", "10_folds"]: if experiment == "test": instances = 1000 elif experiment == "train": instances = 2200 elif experiment == "10_folds": instances = 6000 else: raise ValueError(f"unimplemented experiment - {experiment}") labels = np.load(f"dataset/{experiment}_labels.npy") alignment_text = "aligned" if align is True else "unaligned" task = f"{experiment}/{model_name}_{detector_backend}_{distance_metric}_{alignment_text}" output_file = f"outputs/{task}.csv" print(output_file) # check file is already available if os.path.exists(output_file) is True: continue distances = [] for i in tqdm(range(0, instances), desc = task): img1_target = f"lfwe/{experiment}/{i}_1.jpg" img2_target = f"lfwe/{experiment}/{i}_2.jpg" result = DeepFace.verify( img1_path=img1_target, img2_path=img2_target, model_name=model_name, detector_backend=detector_backend, distance_metric=distance_metric, align=align, enforce_detection=False, expand_percentage=expand_percentage, ) distance = result["distance"] distances.append(distance) # ----------------------------------- ``` -------------------------------- ### Build DeepFace Models Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Pre-builds the DeepFace model and face detector for subsequent operations. Ensure the model_name and detector_backend are correctly specified. ```python model = DeepFace.build_model(model_name) detector = DeepFace.build_model(task="face_detector", model_name=detector_backend) ``` -------------------------------- ### Calculate Confidence Metrics Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Initializes a dictionary to store confidence metrics and iterates through distance metrics to find the maximum value for each. ```python confidence_metrics = {} for distance_metric in distance_metrics: max_value = df[distance_metric].max() ``` -------------------------------- ### Perform DeepFace Experiments Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Iterates through predefined models, detector backends, distance metrics, and alignment options to calculate and store distances for each experiment task. Skips alignment if detector backend is 'skip'. ```python def perform_experiments(): for model_name in models: for detector_backend in detectors: for distance_metric in metrics: for align in alignment: if detector_backend == "skip" and align is True: # Alignment is not possible for a skipped detector configuration continue calculate_distances( model_name=model_name, detector_backend=detector_backend, distance_metric=distance_metric, align=align, ) def calculate_distances( model_name: str, detector_backend: str, distance_metric: str = "euclidean_l2", align: bool = True ): for experiment in ["test", "train", "10_folds"]: if experiment == "test": instances = 1000 elif experiment == "train": instances = 2200 elif experiment == "10_folds": instances = 6000 else: raise ValueError(f"unimplemented experiment - {experiment}") labels = np.load(f"dataset/{experiment}_labels.npy") alignment_text = "aligned" if align is True else "unaligned" task = f"{experiment}/{model_name}_{detector_backend}_{distance_metric}_{alignment_text}" output_file = f"outputs/{task}.csv" # check file is already available if os.path.exists(output_file) is True: continue distances = [] for i in tqdm(range(0, instances), desc = task): img1_target = f"lfwe/{experiment}/{i}_1.jpg" img2_target = f"lfwe/{experiment}/{i}_2.jpg" result = DeepFace.verify( img1_path=img1_target, img2_path=img2_target, model_name=model_name, detector_backend=detector_backend, distance_metric=distance_metric, align=align, enforce_detection=False, expand_percentage=expand_percentage, ) distance = result["distance"] distances.append(distance) # ----------------------------------- df = pd.DataFrame(list(labels), columns = ["actuals"]) ``` -------------------------------- ### Execute LFW Dataset Preparation Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Calls the `retrieve_lfe` function to prepare the LFW dataset for 'test', 'train', and '10_folds' tasks. ```python retrieve_lfe(task = "test") retrieve_lfe(task = "train") retrieve_lfe(task = "10_folds") ``` -------------------------------- ### Calculate and Print Performance Metrics Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Calculates accuracy, precision, recall, and F1-score based on the predicted and true labels, then prints these metrics. ```python accuracy= 100 * round(accuracy_score(y_test, pred_classes), 4) precision = 100 * round(precision_score(y_test, pred_classes), 4) recall = 100 * round(recall_score(y_test, pred_classes), 4) f1 = 100 * round(f1_score(y_test, pred_classes), 4) print(f"Boosted LightFace's {accuracy=}, {precision=}, {recall=}, {f1=}") ``` -------------------------------- ### Import Dependencies for DeepFace Experiments Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Imports necessary libraries for data manipulation, machine learning, and DeepFace operations. Includes built-in, third-party, and specific library imports like XGBoost and LightGBM. ```python # built-in dependencies import os # os.environ['CUDA_VISIBLE_DEVICES'] = '-1' import statistics # 3rd party dependencies import numpy as np import pandas as pd from tqdm import tqdm import matplotlib.pyplot as plt from sklearn.metrics import accuracy_score from sklearn.datasets import fetch_lfw_pairs from deepface import DeepFace import lightgbm as lgb import xgboost from xgboost import plot_importance from sklearn.model_selection import KFold from tqdm import tqdm ``` -------------------------------- ### Display Confidence Metrics Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Prints the calculated confidence metrics, including model weights, intercept, normalizer, and min/max confidence values for true and false matches. ```python confidence_metrics ``` -------------------------------- ### Generate GitHub Markdown Tables Source: https://github.com/serengil/deepface/blob/master/benchmarks/Evaluate-Results.ipynb Creates performance matrices in GitHub markdown format for different distance metrics and alignment settings. It highlights values above a certain threshold. ```python def create_github_table(): for metric in distance_metrics: for align in [True, False]: df = pd.read_csv(f"results/pivot_{metric}_with_alignment_{align}.csv") df = df.rename(columns = {'Unnamed: 0': 'detector'}) df = df.set_index('detector') print(f"Performance Matrix for {metric} while alignment is {align} ") header = "| | " for col_name in df.columns.tolist(): header += f"{col_name} |" print(header) # ---------------- מיט- seperator = "| --- | " for col_name in df.columns.tolist(): seperator += " --- |" print(seperator) # ---------------- מיט- for index, instance in df.iterrows(): line = f"| {instance.name} |" for i in instance.values: if i < 97.5: line += f"{i} |" else: line += f"**{i}** |" print(line) print("\n---------------------------") ``` -------------------------------- ### Face Anti-Spoofing with DeepFace Source: https://github.com/serengil/deepface/blob/master/README.md Shows how to enable the anti-spoofing feature in DeepFace for face extraction and real-time streaming. This helps determine if a face is real or a spoof. ```python # anti spoofing test in face detection face_objs = DeepFace.extract_faces(img_path="dataset/img1.jpg", anti_spoofing = True) assert all(face_obj["is_real"] is True for face_obj in face_objs) # anti spoofing test in real time analysis DeepFace.stream(db_path = "C:/database", anti_spoofing = True) ``` -------------------------------- ### Train LightGBM Models with Cross-Validation Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Trains LightGBM models using k-fold cross-validation. It handles pre-trained models and saves newly trained ones. ```python gbms = [] learning_curves = [] best_iterations = [] feature_importances = [] for k in range(0, k): model_file = f"models/boosted_lightface_{k}.txt" if enforce_training is False and os.path.exists(model_file) is True: print(f"Using pre-trained model for {k+1}-th fold.") gbm = lgb.Booster(model_file=model_file) gbms.append(gbm) continue print(f"Training {k}-th model") valid_from = k * 600 valid_until = valid_from + 600 lgb_val = lgb.Dataset( x_val[valid_from:valid_until], y_val[valid_from:valid_until], feature_name = feature_names, categorical_feature = categorical_features, free_raw_data=False ) # copy the rest of validation set into training # train_indices = list(range(0, valid_from)) + list(range(valid_until, len(x_val))) # x_train_extended = np.concatenate((x_train, x_val[train_indices]), axis=0) # y_train_extended = np.concatenate((y_train, y_val[train_indices]), axis=0) # lgb_train = lgb.Dataset( # x_train_extended, # y_train_extended, # feature_name=feature_names, # categorical_feature=categorical_features, # free_raw_data=False # ) evals_result = {} gbm = lgb.train( params = params, train_set = lgb_train, valid_sets = [lgb_train, lgb_val], num_boost_round=10000, callbacks=[ lgb.early_stopping(stopping_rounds=500), lgb.record_evaluation(evals_result), ], ) gbm.save_model(f'models/boosted_lightface_{k}.txt') gbms.append(gbm) learning_curves.append(evals_result) best_iterations.append(gbm.best_iteration) feature_importances.append(gbm.feature_importance) ``` -------------------------------- ### Select Model for Experiment Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Chooses a specific facial recognition model from the predefined list for the current experiment. ```python model_name = model_names[1] ``` -------------------------------- ### Define LightGBM Parameters Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Defines the parameters for LightGBM training, differentiating between multi-class and binary classification objectives. ```python if multiclass is True: params = { 'boosting_type': 'gbdt', 'objective': 'multiclass', 'num_class': 2, #same person, different persons 'metric': 'multi_logloss', 'num_leaves': pow(2, 5) - 1, 'learning_rate': 0.01, 'verbose': -1, 'max_depth': 5, } else: # binary params = { 'boosting_type': 'gbdt', 'objective': 'binary', 'metric': 'binary_logloss', 'num_leaves': pow(2, 5) - 1, 'learning_rate': 0.01, 'verbose': -1, 'max_depth': 5, } ``` -------------------------------- ### Run DeepFace Verification Experiments Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Iterates through all combinations of models, detectors, metrics, and alignment settings to perform facial verification on LFW image pairs. Results are saved as CSV files. ```python for model_name in models: for detector_backend in detectors: for distance_metric in metrics: for align in alignment: if detector_backend == "skip" and align is True: # Alignment is not possible for a skipped detector configuration continue alignment_text = "aligned" if align is True else "unaligned" task = f"{model_name}_{detector_backend}_{distance_metric}_{alignment_text}" output_file = f"outputs/test/{task}.csv" if os.path.exists(output_file): #print(f"{output_file} is available already") continue distances = [] for i in tqdm(range(0, instances), desc = task): img1_target = f"lfwe/test/{i}_1.jpg" img2_target = f"lfwe/test/{i}_2.jpg" result = DeepFace.verify( img1_path=img1_target, img2_path=img2_target, model_name=model_name, detector_backend=detector_backend, distance_metric=distance_metric, align=align, enforce_detection=False, expand_percentage=expand_percentage, ) distance = result["distance"] distances.append(distance) # ----------------------------------- df = pd.DataFrame(list(labels), columns = ["actuals"]) df["distances"] = distances df.to_csv(output_file, index=False) ``` -------------------------------- ### Register Image and Perform Face Search Source: https://github.com/serengil/deepface/blob/master/README.md Register an image into the database and perform both exact and approximate nearest neighbor searches for face recognition. ```python # register an image into the database DeepFace.register(img = "img1.jpg") # perform exact search dfs: List[pd.DataFrame] = DeepFace.search(img = "target.jpg") # perform approximate nearest neighbor search dfs: List[pd.DataFrame] = DeepFace.search(img = "target.jpg", search_method = "ann") ``` -------------------------------- ### Import Libraries Source: https://github.com/serengil/deepface/blob/master/benchmarks/Evaluate-Results.ipynb Imports necessary libraries for data manipulation, display, and plotting. ```python import pandas as pd from IPython.display import display, HTML from sklearn import metrics import matplotlib.pyplot as plt ``` -------------------------------- ### Display DataFrame Head Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Shows the first few rows of the processed DataFrame to verify the data structure and content. Requires pandas. ```python df.head() ``` -------------------------------- ### Display Head of Training DataFrame Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Shows the first few rows of the training DataFrame to inspect the loaded and merged data. Useful for a quick data validation. ```python dfs["train"].head() ``` -------------------------------- ### Import Dependencies for DeepFace Experiments Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Imports necessary built-in and third-party libraries for performing facial recognition experiments, including data handling, visualization, and machine learning frameworks. ```python # built-in dependencies import os # 3rd party dependencies import numpy as np import pandas as pd from tqdm import tqdm import matplotlib.pyplot as plt import sklearn from sklearn.datasets import fetch_lfw_pairs from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay, precision_score, recall_score, f1_score, accuracy_score from deepface import DeepFace from deepface.modules import preprocessing import lightgbm as lgb from tqdm import tqdm import cv2 import matplotlib.pyplot as plt import shap ``` -------------------------------- ### Set Experiment Configuration Parameters Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Defines key parameters for the facial recognition experiments, such as random seed, detector backend, number of pairs (k), multiclass setting, and whether to enforce training. ```python seed = 17 detector_backend = "retinaface" k = 10 multiclass = False # multiclass with 2 classes or binary. both are same. enforce_training = False ``` -------------------------------- ### Combine and Preprocess Dataset Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Concatenates positive and negative sample pairs into a single DataFrame and prepends the base path to the image file paths. Requires pandas. ```python df = pd.concat([positives, negatives]).reset_index(drop = True) df.file_x = "../tests/dataset/"+df.file_x df.file_y = "../tests/dataset/"+df.file_y ``` -------------------------------- ### Import Dependencies for DeepFace Experiments Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Imports necessary built-in, third-party, and DeepFace specific modules for conducting facial recognition experiments and analysis. ```python # built-in dependencies import itertools import math # 3rd party dependencies import pandas as pd from deepface import DeepFace from deepface.modules.verification import find_distance, find_threshold from tqdm import tqdm from sklearn.linear_model import LogisticRegression import matplotlib.pyplot as plt ``` -------------------------------- ### Visualize Feature Importance with LightGBM Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Generate and display feature importance plots (gain and split) for the best performing model. This helps in understanding which features contribute most to the model's predictions. ```python for importance_type in ["gain", "split"]: # feature importance with percentages fi_df = pd.DataFrame({ "feature_name": gbms[winner_id].feature_name(), importance_type: gbms[winner_id].feature_importance( importance_type=importance_type ) }) fi_df = fi_df.sort_values(by = [importance_type], ascending=False) fi_df[importance_type] = 100 * fi_df[importance_type] / fi_df[importance_type].sum() fi_df = fi_df[fi_df[importance_type] > 0] ax = fi_df.plot.barh(x='feature_name', y=importance_type) ax.invert_yaxis() plt.legend(loc='lower right') # _ = ax.bar_label(ax.containers[0]) plt.show() ``` -------------------------------- ### Initialize Data Structure for Results Source: https://github.com/serengil/deepface/blob/master/benchmarks/Perform-Experiments.ipynb Initializes a pandas DataFrame to store accuracy results, with models as columns and detectors as rows. ```python data = [[0 for _ in range(len(models))] for _ in range(len(detectors))] base_df = pd.DataFrame(data, columns=models, index=detectors) ``` -------------------------------- ### Define Model and Experiment Parameters Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Configures various parameters for facial recognition experiments, including alignment options, facial recognition models, detection backends, distance metrics, and expansion percentages. ```python # all configuration alternatives for 4 dimensions of arguments alignment = [True] models = ["Facenet", "Facenet512", "VGG-Face", "ArcFace", "Dlib"] detectors = ["retinaface"] metrics = ["euclidean_l2"] expand_percentage = 0 ``` -------------------------------- ### Backup DataFrame Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Creates a copy of the current DataFrame for backup purposes. ```python df_backup = df.copy() ``` -------------------------------- ### Calculate and Store Feature Importances Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Calculates and stores feature importances ('gain' and 'split') for a trained LightGBM model. It normalizes these importances to percentages and sorts them in descending order. ```python feature_importances = {} for importance_type in ["gain", "split"]: # feature importance with percentages fi_df = pd.DataFrame({ "feature_name": gbms[winner_id].feature_name(), importance_type: gbms[winner_id].feature_importance( importance_type=importance_type ) }) fi_df = fi_df.sort_values(by = [importance_type], ascending=False) fi_df[importance_type] = round(100 * fi_df[importance_type] / fi_df[importance_type].sum(), 2) # fi_df = fi_df[fi_df[importance_type] > 0] feature_importances[importance_type] = fi_df ``` -------------------------------- ### Predict and Calculate Confusion Matrix Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-LightGBM.ipynb Predicts class labels using the trained LightGBM model and computes the confusion matrix based on true and predicted labels. ```python pred_probas = gbms[winner_id].predict(x_test) pred_classes = [] for pred_proba in pred_probas: if multiclass is True: pred_class = 1 if pred_proba[1] > pred_proba[0] else 0 else: pred_class = 1 if pred_proba > 0.5 else 0 pred_classes.append(pred_class) cm = confusion_matrix(y_test, pred_classes) print(cm) ``` -------------------------------- ### Find Matching Faces in a Database Source: https://github.com/serengil/deepface/blob/master/README.md Searches a database for faces that match a given image using a specified model. It returns a DataFrame containing the results. ```python dfs = DeepFace.find( img_path = "img1.jpg", db_path = "C:/my_db", model_name = models[1] ) ``` -------------------------------- ### Define Evaluation Parameters Source: https://github.com/serengil/deepface/blob/master/benchmarks/Evaluate-Results.ipynb Defines lists of alignment options, models, detectors, and distance metrics to be used in the evaluation. ```python alignment = [False, True] models = ["Facenet512", "Facenet", "VGG-Face", "ArcFace", "Dlib", "GhostFaceNet", "SFace", "OpenFace", "DeepFace", "DeepID"] detectors = ["retinaface", "mtcnn", "fastmtcnn", "dlib", "yolov8", "yunet", "centerface", "mediapipe", "ssd", "opencv", "skip"] distance_metrics = ["euclidean", "euclidean_l2", "cosine"] ``` -------------------------------- ### Define Identity Image Mappings Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Creates a dictionary mapping identity names to lists of their corresponding image file paths. This structure is used to generate training data. ```python idendities = { "Angelina": ["img1.jpg", "img2.jpg", "img4.jpg" , "img5.jpg", "img6.jpg", "img7.jpg", "img10.jpg", "img11.jpg"], "Scarlett": ["img8.jpg", "img9.jpg"], "Jennifer": ["img3.jpg", "img12.jpg"], "Mark": ["img13.jpg", "img14.jpg", "img15.jpg"], "Jack": ["img16.jpg", "img17.jpg"], "Elon": ["img18.jpg", "img19.jpg"], "Jeff": ["img20.jpg", "img21.jpg"], "Marissa": ["img22.jpg", "img23.jpg"], "Sundar": ["img24.jpg", "img25.jpg"] } ``` -------------------------------- ### Set Pre-tuned Thresholds for Face Recognition Models Source: https://github.com/serengil/deepface/blob/master/boosted/Perform-Boosting-Experiments-XGBoost.ipynb Defines thresholds for various face recognition models based on the selected detector backend. Use this to set decision boundaries for classification. ```python if detector_backend == "mtcnn": thresholds = { "Facenet": 1.0927487190831375, "Facenet512": 1.0676744382971612, "VGG-Face": 1.199458073887602, "ArcFace": 1.1853355178343647, "Dlib": 0.4020917206804517, } elif detector_backend == "retinaface": thresholds = { "Facenet": 1.0771751259493634, "Facenet512": 1.080821730376328, "VGG-Face": 1.1952250102966764, "ArcFace": 1.1601818883318848, "Dlib": 0.4022031592966787, } elif detector_backend == "yunet": thresholds = { "Facenet": 1.066751738677861, "Facenet512": 1.0691771483816928, "VGG-Face": 1.1802823845238797, "ArcFace": 1.1945138501899335, "Dlib": 0.422060409585814, } else: raise ValueError(f"unimplemented detector - {detector_backend}") ``` -------------------------------- ### Displaying 'Different Persons' Predictions in DeepFace Source: https://github.com/serengil/deepface/blob/master/experiments/distance-to-confidence.ipynb Selects and displays the first 10 rows of the DataFrame where the 'actual' column is 'Different Persons'. It includes identity, file paths, actual labels, and various distance/confidence metrics. ```python df[df["actual"] == "Different Persons"][[ "file_x", "file_y", "actual", "cosine", "euclidean", "euclidean_l2", "angular", "cosine_confidence", "euclidean_confidence", "euclidean_l2_confidence", "angular_confidence", ]].head(10) ```