diff --git a/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py b/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py new file mode 100644 index 0000000000000000000000000000000000000000..b8f13ec4834df8198225b66f3e1dfa0f22ed7f7b --- /dev/null +++ b/bob/bio/face/config/baseline/resnet50_vgg2_arcface_2021.py @@ -0,0 +1,34 @@ +from bob.bio.face.embeddings.resnet50 import Resnet50_VGG2_ArcFace_2021 +from bob.bio.face.config.baseline.helpers import embedding_transformer_112x112 +from bob.bio.base.pipelines.vanilla_biometrics import ( + Distance, + VanillaBiometricsPipeline, +) + +memory_demanding = False +if "database" in locals(): + annotation_type = database.annotation_type + fixed_positions = database.fixed_positions + + memory_demanding = ( + database.memory_demanding if hasattr(database, "memory_demanding") else False + ) +else: + annotation_type = None + fixed_positions = None + + +def load(annotation_type, fixed_positions=None): + transformer = embedding_transformer_112x112( + Resnet50_VGG2_ArcFace_2021(memory_demanding=memory_demanding), + annotation_type, + fixed_positions, + ) + + algorithm = Distance() + + return VanillaBiometricsPipeline(transformer, algorithm) + + +pipeline = load(annotation_type, fixed_positions) +transformer = pipeline.transformer diff --git a/bob/bio/face/embeddings/resnet50.py b/bob/bio/face/embeddings/resnet50.py index 8a75b2ed602e12c0e2dba708ab672b37c0c4bb3b..c542c39d734e7ec7d402e3834359977f406fe4a8 100644 --- a/bob/bio/face/embeddings/resnet50.py +++ b/bob/bio/face/embeddings/resnet50.py @@ -77,3 +77,72 @@ class Resnet50_MsCeleb_ArcFace_2021(TransformTensorflow): embeddings = tf.math.l2_normalize(prelogits, axis=-1) return embeddings + +class Resnet50_VGG2_ArcFace_2021(TransformTensorflow): + """ + Resnet50 Backbone trained with the VGG2 database. + + The bottleneck layer (a.k.a embedding) has 512d. + + The configuration file used to trained is: + + ```yaml + batch-size: 128 + face-size: 112 + face-output_size: 112 + n-classes: 8631 + + + ## Backbone + backbone: 'resnet50' + head: 'arcface' + s: 64 + bottleneck: 512 + m: 0.5 + + # Training parameters + solver: "sgd" + lr: 0.1 + dropout-rate: 0.5 + epochs: 1047 + + + train-tf-record-path: "<PATH>" + validation-tf-record-path: "<PATH>" + + ``` + + + """ + + def __init__(self, memory_demanding=False): + internal_path = pkg_resources.resource_filename( + __name__, os.path.join("data", "resnet50_vgg2_arcface_2021"), + ) + + checkpoint_path = ( + internal_path + if rc["bob.bio.face.models.resnet50_vgg2_arcface_2021"] is None + else rc["bob.bio.face.models.resnet50_vgg2_arcface_2021"] + ) + + urls = [ + "https://www.idiap.ch/software/bob/data/bob/bob.bio.face/master/tf2/resnet50_vgg2_arcface_2021.tar.gz", + "http://www.idiap.ch/software/bob/data/bob/bob.bio.face/master/tf2/resnet50_vgg2_arcface_2021.tar.gz", + ] + + download_model(checkpoint_path, urls, "resnet50_vgg2_arcface_2021.tar.gz") + + super(Resnet50_VGG2_ArcFace_2021, self).__init__( + checkpoint_path, + preprocessor=lambda X: X / 255.0, + memory_demanding=memory_demanding, + ) + + def inference(self, X): + if self.preprocessor is not None: + X = self.preprocessor(tf.cast(X, "float32")) + + prelogits = self.model.predict_on_batch(X) + embeddings = tf.math.l2_normalize(prelogits, axis=-1) + return embeddings diff --git a/setup.py b/setup.py index 34bcf0e25d3e179309f3962b9b60602ea80c265a..4fd8cf61adbe60ca34b9454a721be08bf950b153 100644 --- a/setup.py +++ b/setup.py @@ -147,6 +147,7 @@ setup( "lda = bob.bio.face.config.baseline.lda:pipeline", "dummy = bob.bio.face.config.baseline.dummy:pipeline", "resnet50-msceleb-arcface-2021 = bob.bio.face.config.baseline.resnet50_msceleb_arcface_2021:pipeline", + "resnet50-vgg2-arcface-2021 = bob.bio.face.config.baseline.resnet50_vgg2_arcface_2021:pipeline", "mobilenetv2-msceleb-arcface-2021 = bob.bio.face.config.baseline.mobilenetv2_msceleb_arcface_2021", ], "bob.bio.config": [ @@ -177,6 +178,7 @@ setup( "meds = bob.bio.face.config.database.meds", "morph = bob.bio.face.config.database.morph", "resnet50-msceleb-arcface-2021 = bob.bio.face.config.baseline.resnet50_msceleb_arcface_2021", + "resnet50-vgg2-arcface-2021 = bob.bio.face.config.baseline.resnet50_vgg2_arcface_2021", "mobilenetv2-msceleb-arcface-2021 = bob.bio.face.config.baseline.mobilenetv2_msceleb_arcface_2021", ], "bob.bio.cli": [