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.89k stars 2.25k forks source link

Performance Issue #256

Closed minyeko closed 3 years ago

minyeko commented 3 years ago

Hi serengil, I am using latest python version running on window 10. And my laptop got 32 GB RAM and CPU is i7 (2.11GHz). It took 15 seconds to verify one pair of photos. I use the photos from your sample deepface.postman_collection.json file and call the verify api from Postman. If three pairs, it took around 40 seconds. Please advice me what need to check? Thanks.

serengil commented 3 years ago

It uses retinaface face detector by default and you cannot set it in api.

In api.py (https://github.com/serengil/deepface/blob/master/api/api.py)

237th line - current resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = vggface_model)

Change that line to: resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = vggface_model , detector_backend = 'opencv')

I will add this in the next release but you can try this for now.

minyeko commented 3 years ago

Thanks a lot for your quick response and it work perfectly after changed as you said. Now it took only 2 seconds.

serengil commented 3 years ago

notice that retinaface is more robust. if you use opencv, then its accuracy would be lower.

minyeko commented 3 years ago

Noted with thanks :)

minyeko commented 3 years ago

Is there any possibility to use retinaface face detector with better performance for api ? If use retinaface , does it always take around 14 seconds? Do you have any hardware recommendation to use it?

hengway commented 3 years ago

hi @serengil, thank you for the effort. I am also face the slow verify issue, it took 20 seconds for each verify in my macbook pro 2016. Really appriciate if you can provide some advice to accelerate it. below is my code and output.

Code:

import datetime
from deepface import DeepFace

# VGG-Face
# OpenFace
# Facenet
# DeepFace
# DeepID
# Dlib
# ArcFace

start = datetime.datetime.now()
model = DeepFace.build_model("DeepFace")
end = datetime.datetime.now()
print("Load model took - " + str((end - start).total_seconds()) + " seconds")

start = datetime.datetime.now()
result = DeepFace.verify("dataset/img1.jpg", "dataset/img2.jpg")
end = datetime.datetime.now()
print("First verify took - " + str((end - start).total_seconds()) + " seconds")
print("Is 1st verified: ", result["verified"])

start = datetime.datetime.now()
result = DeepFace.verify("dataset/img1.jpg", "dataset/img3.jpg")
end = datetime.datetime.now()
print("Second verify took - " + str((end - start).total_seconds()) + " seconds")
print("Is 2nd verified: ", result["verified"])

start = datetime.datetime.now()
result = DeepFace.verify("dataset/img1.jpg", "dataset/img4.jpg")
end = datetime.datetime.now()
print("Third verify took - " + str((end - start).total_seconds()) + " seconds")
print("Is 3rd verified: ", result["verified"])

start = datetime.datetime.now()
result = DeepFace.verify([["dataset/img1.jpg", "dataset/img2.jpg"], ["dataset/img1.jpg", "dataset/img3.jpg"], ["dataset/img1.jpg", "dataset/img4.jpg"]])
end = datetime.datetime.now()
print("Forth verify took - " + str((end - start).total_seconds()) + " seconds")
print("Is 4th verified")

Output:

Load model took - 20.546917 seconds
First verify took - 27.248646 seconds
Is 1st verified:  True
Second verify took - 25.360887 seconds
Is 2nd verified:  False
Third verify took - 24.042487 seconds
Is 3rd verified:  True
Verification: 100%|██████████| 3/3 [00:57<00:00, 19.07s/it]
Forth verify took - 62.568481 seconds
Is 4th verified

Thank you and have a nice day

serengil commented 3 years ago

@hengway you are using 0.0.55?

I just set the default face detector to RetinaFace. This is the strongest one but it is slow. Try opencv or mtcnn to have faster results.

result = DeepFace.verify("dataset/img1.jpg", "dataset/img2.jpg", detector_backend = 'opencv')

serengil commented 3 years ago

I just published deepface 0.0.60. Many production-driven performance issues are handled in this release. Please update the package and re-try.

hengway commented 3 years ago

Hi, @serengil thank you for reply, just upgrade to 0.0.61

bash-3.2$ pip3 show deepface Name: deepface Version: 0.0.61 Summary: A Lightweight Face Recognition and Facial Attribute Analysis Framework (Age, Gender, Emotion, Race) for Python

This is the code I run start = datetime.datetime.now() result = DeepFace.verify("dataset/img1.jpg", "dataset/img2.jpg", "VGG-Face", "cosine", None, True, "opencv") end = datetime.datetime.now() print("verified with VGG: ", result["verified"], " took - ", str((end - start).total_seconds()), " seconds")

start = datetime.datetime.now() result = DeepFace.verify("dataset/img1.jpg", "dataset/img2.jpg", "DeepFace", "cosine", None, True, "opencv") end = datetime.datetime.now() print("verified with DeepFace: ", result["verified"], " took - ", str((end - start).total_seconds()), " seconds")

and this is the output verified with VGG: True took - 3.236698 seconds verified with DeepFace: False took - 54.271675 seconds

after using opencv detector, it seem like faster. but if using deepface model still taking longer and false result. Overall VGG to open CV perform better in my pc. Just curious, can we make the verification goes down to lower then 1 seconds?

Thank you

serengil commented 3 years ago

@hengway deepface model is really complex and I do not think it is a robust model. I recommend you to use VGG-Face, Facenet or ArcFace.

Verify function spends its most of time in model building. I mean that if you call it in a for loop, then it just builds VGG-Face model in the first loop. The other loops will be performed faster.

Alternatively you can build model before calling verify function.

model = DeepFace.build_model("ArcFace")

start = datetime.datetime.now()
result = DeepFace.verify("dataset/img1.jpg", "dataset/img2.jpg", model_name = "ArcFace", model = model)
end = datetime.datetime.now()
print("verified with ArcFace: ", result["verified"], " took - ", str((end - start).total_seconds()), " seconds")
hengway commented 3 years ago

@serengil I see, ok, thank you will give it a try

serengil commented 3 years ago

I updated the api.py. Please pull the latest repo.