# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 2
#     language: python
#     name: python2
# ---

# ## LBPH Evaluation

# ### Methodology

# 1. Normalize each image from the dataset by: 
#     * Pre-processing - histogram equalization
#     * Post-processing - 2D facial alignment
# 2. Randomise folds containing train-test splits for each subject
# 3. Train a classifier on each fold's train split
# 4. Evaluate the trained model in step 4 by it's corresponding test split
# 5. Repeat step 2, 3, 4 by varying the number of training samples per subject
# 6. Report the average value of **Precision@1** across each fold.

from __future__ import division
from multiprocessing import Process, Queue
import numpy as np

from Dataset import Dataset
from FaceRecognizer import FaceRecognizer


def predict_one(idx, recognizer_obj, image, queue):
    queue.put((idx, recognizer_obj.model.predict(image)))


# ### ATT Dataset

dataset_path =  "/media/ankurrc/new_volume/softura/facerec/datasets/norm_standard_att"

folds = 3
training_samples = [2, 5, 8]

results = []

# #### Train the recognizer for the different folds and evaluate

recognizer_model = FaceRecognizer()
dataset = Dataset(dataset_path)

for training_sample in training_samples:
    print "Training on", training_sample, "samples per subject."
    for fold in range(1, folds+1):
        output = Queue()
        X_train, y_train = dataset.load_data(is_train=True, fold=fold, num_train=training_sample)
        print "Training recognizer (", len(X_train), "samples and", len(np.unique(y_train)), "subjects)..."
        recognizer_model.train(X_train, y_train)
        print "completed."
        X_test, y_test = dataset.load_data(is_train=False, fold=fold, num_train=training_sample)
        print "Predicting on (", len(X_test), "samples)..."
        processes = [Process(target=predict_one,
                             args=(idx,
                                   recognizer_model,
                                   image,
                                   output))
                     for idx, image in enumerate(X_test)]

        for p in processes:
            p.start()

        predictions = [output.get() for p in processes]

        for p in processes:
            p.join()

        print "Done"

        predictions = [(x[1][0], x[1][1])
                       for x in sorted(predictions, key=lambda x: x[0])]
        recognizer_model.evaluate(predictions, y_test)
        
    print "-"*120

# ### Cyber Extruder Ultimate Dataset

dataset_path =  "/media/ankurrc/new_volume/softura/facerec/datasets/norm_cyber_extruder_ultimate"

recognizer_model = FaceRecognizer()
dataset = Dataset(dataset_path)

for training_sample in training_samples:
    print "Training on", training_sample, "samples per subject."
    for fold in range(1, folds+1):
        X_train, y_train = dataset.load_data(is_train=True, fold=fold, num_train=training_sample)
        print "Training recognizer (", len(X_train), "samples and", len(np.unique(y_train)), "subjects)..."
        recognizer_model.train(X_train, y_train)
        print "completed."
        X_test, y_test = dataset.load_data(is_train=False, fold=fold, num_train=training_sample)
        print "Predicting on (", len(X_test), "samples)..."
        predictions = recognizer_model.predict(images=X_test)
        print "Done"
        recognizer_model.evaluate(predictions, y_test)
        
    print "-"*120

# ## Results

result_att = np.array([[87.89, 85.98, 87.89], [95.87, 97.93, 96.39], [98.6, 100.0, 100.0]])
result_ceu = np.array([[24.16, 23.33, 24.18], [37.37, 37.54, 38.48], [51.81 ,47.27, 51.13]])
samples_subject = [2, 5, 8]

att_avg = np.mean(axis=1, a=result_att)
ceu_avg = np.mean(axis=1, a=result_ceu)

import matplotlib.pyplot as plt

plt.xlabel('Number of training samples')
plt.ylabel('Precision')
plt.plot(samples_subject, att_avg, label="ATT")
plt.plot(samples_subject, ceu_avg, label="CEU")
plt.legend(loc='upper right')
plt.show()

StarcoderdataJupyterScriptsDedupFiltered