serengil / deepface

A Lightweight Face Recognition and Facial Attribute Analysis (Age, Gender, Emotion and Race) Library for Python
https://bit.ly/deepface-py
MIT License
14.56k stars 2.21k forks source link

Cosine Distance bigger than 1 #437

Closed TinoCalamia closed 2 years ago

TinoCalamia commented 2 years ago

Hey,

first of all thank you very much for this amazing framework!

I was recently playing around with a facial dataset and using DeepFace. For some models I used the cosine distance and got values bigger than 1. As far as I know the value should be between 0 - 1. Is there anything I am missing? And is this expected?

I am using the most recent version of DeepFace.

Thank you!

serengil commented 2 years ago

rounding might cause this. can you share your input image and configuration?

TinoCalamia commented 2 years ago

Not sure if this is a rounding issue as I sometimes get values of e.g. 1.3. I am using a variety of images from the LFW database, so this is not happening on a particular image. Using the Tensorflow2.6 image from google cloud platform :)

serengil commented 2 years ago

can you share the exact image in LFW?

TinoCalamia commented 2 years ago

The source data is from "Racial faces in the wild" dataset which divides the LFW into ethnic groups. But I would assume the middle part refers to the same folder in the LFW dataset.

It happens when I compare the following images:

I used FaceNet512 and the cosine distance

serengil commented 2 years ago

@TinoCalamia would you please attach the items into this issue? i cannot access the data set.

serengil commented 2 years ago

I found a pair in deepface unit tests having a cosine distance greater than 1.

Besides, I tested same pair with scipy cosine distance formula. The both deepface and scipy return a distance value greater than 1.

from deepface import DeepFace
from deepface.commons import distance as dst
from scipy import spatial

img1_path = "deepface/tests/dataset/img6.jpg"
img2_path = "deepface/tests/dataset/img8.jpg"

#obj = DeepFace.verify(img1_path, img2_path, model_name = "Facenet512", distance_metric="cosine")
#print(obj)

img1 = DeepFace.represent(img1_path, model_name = "Facenet512")
img2 = DeepFace.represent(img2_path, model_name = "Facenet512")

distance_v1 = dst.findCosineDistance(img1, img2)
print(distance_v1)

distance_v2 = spatial.distance.cosine(img1, img2)
print(distance_v2)

According to this stackoverflow post, if dot product of these vectors is negative, it's perfectly OK for cosine to return a value greater than 1.

So, this is not a bug.