diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 87d0df80..6fe01c66 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -25,7 +25,7 @@ jobs: run: | python --version echo "import tests.actions_test" > test.py - coverage run --source models,examples test.py + coverage run --source facenet_pytorch/models,examples tests/actions_test.py coverage report coverage xml - name: Upload coverage to Codecov diff --git a/README.md b/README.md index 44090393..9eb1471f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# Face Recognition Using Pytorch +# Face Recognition Using Pytorch *You can also read a translated version of this file [in Chinese 简体中文版](README_cn.md).* +![banner](static/facenet-pytorch-banner.png) + [![Downloads](https://pepy.tech/badge/facenet-pytorch)](https://pepy.tech/project/facenet-pytorch) [![Code Coverage](https://img.shields.io/codecov/c/github/timesler/facenet-pytorch.svg)](https://codecov.io/gh/timesler/facenet-pytorch) @@ -18,12 +20,12 @@ Also included in this repo is an efficient pytorch implementation of MTCNN for f * [Quick start](#quick-start) * [Pretrained models](#pretrained-models) * [Example notebooks](#example-notebooks) - + [*Complete detection and recognition pipeline*](#complete-detection-and-recognition-pipeline) - + [*Face tracking in video streams*](#face-tracking-in-video-streams) - + [*Finetuning pretrained models with new data*](#finetuning-pretrained-models-with-new-data) - + [*Guide to MTCNN in facenet-pytorch*](#guide-to-mtcnn-in-facenet-pytorch) - + [*Performance comparison of face detection packages*](#performance-comparison-of-face-detection-packages) - + [*The FastMTCNN algorithm*](#the-fastmtcnn-algorithm) + * [*Complete detection and recognition pipeline*](#complete-detection-and-recognition-pipeline) + * [*Face tracking in video streams*](#face-tracking-in-video-streams) + * [*Finetuning pretrained models with new data*](#finetuning-pretrained-models-with-new-data) + * [*Guide to MTCNN in facenet-pytorch*](#guide-to-mtcnn-in-facenet-pytorch) + * [*Performance comparison of face detection packages*](#performance-comparison-of-face-detection-packages) + * [*The FastMTCNN algorithm*](#the-fastmtcnn-algorithm) * [Running with docker](#running-with-docker) * [Use this repo in your own git project](#use-this-repo-in-your-own-git-project) * [Conversion of parameters from Tensorflow to Pytorch](#conversion-of-parameters-from-tensorflow-to-pytorch) @@ -32,7 +34,7 @@ Also included in this repo is an efficient pytorch implementation of MTCNN for f ## Quick start 1. Install: - + ```bash # With pip: pip install facenet-pytorch @@ -43,10 +45,10 @@ Also included in this repo is an efficient pytorch implementation of MTCNN for f # or use a docker container (see https://github.com/timesler/docker-jupyter-dl-gpu): docker run -it --rm timesler/jupyter-dl-gpu pip install facenet-pytorch && ipython ``` - + 1. In python, import facenet-pytorch and instantiate models: - - ```python + + ```py from facenet_pytorch import MTCNN, InceptionResnetV1 # If required, create a face detection pipeline using MTCNN: @@ -55,10 +57,10 @@ Also included in this repo is an efficient pytorch implementation of MTCNN for f # Create an inception resnet (in eval mode): resnet = InceptionResnetV1(pretrained='vggface2').eval() ``` - + 1. Process an image: - - ```python + + ```py from PIL import Image img = Image.open() @@ -78,7 +80,7 @@ See `help(MTCNN)` and `help(InceptionResnetV1)` for usage and implementation det ## Pretrained models -See: [models/inception_resnet_v1.py](models/inception_resnet_v1.py) +See: [models/inception_resnet_v1.py](facenet_pytorch/models/inception_resnet_v1.py) The following models have been ported to pytorch (with links to download pytorch state_dict's): @@ -89,7 +91,7 @@ The following models have been ported to pytorch (with links to download pytorch There is no need to manually download the pretrained state_dict's; they are downloaded automatically on model instantiation and cached for future use in the torch cache. To use an Inception Resnet (V1) model for facial recognition/identification in pytorch, use: -```python +```py from facenet_pytorch import InceptionResnetV1 # For a model pretrained on VGGFace2 @@ -119,7 +121,7 @@ Face recognition can be easily applied to raw images by first detecting faces us MTCNN can be used to build a face tracking system (using the `MTCNN.detect()` method). A full face tracking example can be found at [examples/face_tracking.ipynb](examples/face_tracking.ipynb). -![](examples/tracked.gif) +![Tracking](examples/tracked.gif) ### *Finetuning pretrained models with new data* @@ -156,7 +158,7 @@ Each package is tested for its speed in detecting the faces in a set of 300 imag |dlib|3.80|8.39|14.53| |mtcnn|3.04|5.70|8.23| -![](examples/performance-comparison.png) +![Performance comparison](examples/performance-comparison.png) See the [notebook on kaggle](https://www.kaggle.com/timesler/comparison-of-face-detection-packages). @@ -193,9 +195,9 @@ Alternatively, the code can be installed as a package using pip: ## Conversion of parameters from Tensorflow to Pytorch -See: [models/utils/tensorflow2pytorch.py](models/tensorflow2pytorch.py) +See: [models/utils/tensorflow2pytorch.py](facenet_pytorch/models/tensorflow2pytorch.py) -Note that this functionality is not needed to use the models in this repo, which depend only on the saved pytorch `state_dict`'s. +Note that this functionality is not needed to use the models in this repo, which depend only on the saved pytorch `state_dict`'s. Following instantiation of the pytorch model, each layer's weights were loaded from equivalent layers in the pretrained tensorflow models from [davidsandberg/facenet](https://github.com/davidsandberg/facenet). @@ -205,7 +207,7 @@ The equivalence of the outputs from the original tensorflow models and the pytor `>>> compare_model_outputs(mdl, sess, torch.randn(5, 160, 160, 3).detach())` -``` +```py Passing test data through TF model tensor([[-0.0142, 0.0615, 0.0057, ..., 0.0497, 0.0375, -0.0838], @@ -228,16 +230,16 @@ Distance 1.2874517096861382e-06 --- -In order to re-run the conversion of tensorflow parameters into the pytorch model, ensure you clone this repo _with submodules_, as the davidsandberg/facenet repo is included as a submodule and parts of it are required for the conversion. +In order to re-run the conversion of tensorflow parameters into the pytorch model, ensure you clone this repo *with submodules_, as the davidsandberg/facenet repo is included as a submodule and parts of it are required for the conversion. ## References 1. David Sandberg's facenet repo: [https://github.com/davidsandberg/facenet](https://github.com/davidsandberg/facenet) -1. F. Schroff, D. Kalenichenko, J. Philbin. _FaceNet: A Unified Embedding for Face Recognition and Clustering_, arXiv:1503.03832, 2015. [PDF](https://arxiv.org/pdf/1503.03832) +1. F. Schroff, D. Kalenichenko, J. Philbin. *FaceNet: A Unified Embedding for Face Recognition and Clustering_, arXiv:1503.03832, 2015. [PDF](https://arxiv.org/pdf/1503.03832) -1. Q. Cao, L. Shen, W. Xie, O. M. Parkhi, A. Zisserman. _VGGFace2: A dataset for recognising face across pose and age_, International Conference on Automatic Face and Gesture Recognition, 2018. [PDF](http://www.robots.ox.ac.uk/~vgg/publications/2018/Cao18/cao18.pdf) +1. Q. Cao, L. Shen, W. Xie, O. M. Parkhi, A. Zisserman. *VGGFace2: A dataset for recognising face across pose and age_, International Conference on Automatic Face and Gesture Recognition, 2018. [PDF](http://www.robots.ox.ac.uk/~vgg/publications/2018/Cao18/cao18.pdf) -1. D. Yi, Z. Lei, S. Liao and S. Z. Li. _CASIAWebface: Learning Face Representation from Scratch_, arXiv:1411.7923, 2014. [PDF](https://arxiv.org/pdf/1411.7923) +1. D. Yi, Z. Lei, S. Liao and S. Z. Li. *CASIAWebface: Learning Face Representation from Scratch_, arXiv:1411.7923, 2014. [PDF](https://arxiv.org/pdf/1411.7923) -1. K. Zhang, Z. Zhang, Z. Li and Y. Qiao. _Joint Face Detection and Alignment Using Multitask Cascaded Convolutional Networks_, IEEE Signal Processing Letters, 2016. [PDF](https://kpzhang93.github.io/MTCNN_face_detection_alignment/paper/spl.pdf) +1. K. Zhang, Z. Zhang, Z. Li and Y. Qiao. *Joint Face Detection and Alignment Using Multitask Cascaded Convolutional Networks_, IEEE Signal Processing Letters, 2016. [PDF](https://kpzhang93.github.io/MTCNN_face_detection_alignment/paper/spl.pdf) diff --git a/README_cn.md b/README_cn.md index b11c9eca..3ed4efe8 100644 --- a/README_cn.md +++ b/README_cn.md @@ -118,7 +118,7 @@ img_probs = resnet(img_cropped.unsqueeze(0)) ## 预训练模型 -请参阅:[models/inception_resnet_v1.py](models/inception_resnet_v1.py) +请参阅:[models/inception_resnet_v1.py](facenet_pytorch/models/inception_resnet_v1.py) 以下模型已移植到 pytorch(包含下载 pytorch state_dict 的链接): @@ -233,7 +233,7 @@ docker run --rm -p 8888:8888 ## Tensorflow 到 Pytorch 的参数转换 -请参阅:[models/utils/tensorflow2pytorch.py](models/tensorflow2pytorch.py) +请参阅:[models/utils/tensorflow2pytorch.py](facenet_pytorch/models/tensorflow2pytorch.py) 请注意,使用此存储库中的模型不需要此功能,该功能仅依赖于pytorch保存的 `state_dict`。 diff --git a/__init__.py b/__init__.py deleted file mode 100644 index 7f1018f1..00000000 --- a/__init__.py +++ /dev/null @@ -1,12 +0,0 @@ -import warnings - -from .models.inception_resnet_v1 import InceptionResnetV1 -from .models.mtcnn import MTCNN, ONet, PNet, RNet, fixed_image_standardization, prewhiten -from .models.utils import training -from .models.utils.detect_face import extract_face - -warnings.filterwarnings( - action="ignore", - message="This overload of nonzero is deprecated:\n\tnonzero()", - category=UserWarning, -) diff --git a/data/.gitignore b/data/.gitignore deleted file mode 100644 index 832aeb8f..00000000 --- a/data/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -2018* -*.json -profile.txt diff --git a/examples/.gitignore b/examples/.gitignore new file mode 100644 index 00000000..a81f8bb4 --- /dev/null +++ b/examples/.gitignore @@ -0,0 +1 @@ +tmptest.py diff --git a/examples/finetune.ipynb b/examples/finetune.ipynb index 45566848..9a21ed4b 100644 --- a/examples/finetune.ipynb +++ b/examples/finetune.ipynb @@ -15,6 +15,7 @@ "metadata": {}, "outputs": [], "source": [ + "from pathlib import Path\n", "from facenet_pytorch import MTCNN, InceptionResnetV1, fixed_image_standardization, training\n", "import torch\n", "from torch.utils.data import DataLoader, SubsetRandomSampler\n", @@ -41,7 +42,8 @@ "metadata": {}, "outputs": [], "source": [ - "data_dir = '../data/test_images'\n", + "root_dir = Path(__file__).parent.parent\n", + "data_dir = root_dir / \"tests\" / \"data\" / \"test_images\"\n", "\n", "batch_size = 32\n", "epochs = 8\n", @@ -106,10 +108,10 @@ "source": [ "dataset = datasets.ImageFolder(data_dir, transform=transforms.Resize((512, 512)))\n", "dataset.samples = [\n", - " (p, p.replace(data_dir, data_dir + '_cropped'))\n", + " (p, p.replace(str(data_dir), str(data_dir.parent / (data_dir.name + \"_aligned\"))))\n", " for p, _ in dataset.samples\n", "]\n", - " \n", + "\n", "loader = DataLoader(\n", " dataset,\n", " num_workers=workers,\n", @@ -117,8 +119,8 @@ " collate_fn=training.collate_pil\n", ")\n", "\n", - "for i, (x, y) in enumerate(loader):\n", - " mtcnn(x, save_path=y)\n", + "for i, (input_file, output_file) in enumerate(loader):\n", + " mtcnn(input_file, save_path=output_file)\n", " print('\\rBatch {} of {}'.format(i + 1, len(loader)), end='')\n", " \n", "# Remove mtcnn to reduce GPU memory usage\n", @@ -168,7 +170,7 @@ " transforms.ToTensor(),\n", " fixed_image_standardization\n", "])\n", - "dataset = datasets.ImageFolder(data_dir + '_cropped', transform=trans)\n", + "dataset = datasets.ImageFolder(data_dir.parent / (data_dir.name + \"_aligned\"), transform=trans)\n", "img_inds = np.arange(len(dataset))\n", "np.random.shuffle(img_inds)\n", "train_inds = img_inds[:int(0.8 * len(img_inds))]\n", diff --git a/examples/finetune_cn.ipynb b/examples/finetune_cn.ipynb index 8190504c..f80ff183 100644 --- a/examples/finetune_cn.ipynb +++ b/examples/finetune_cn.ipynb @@ -15,6 +15,7 @@ "metadata": {}, "outputs": [], "source": [ + "from pathlib import Path\n", "from facenet_pytorch import MTCNN, InceptionResnetV1, fixed_image_standardization, training\n", "import torch\n", "from torch.utils.data import DataLoader, SubsetRandomSampler\n", @@ -41,7 +42,8 @@ "metadata": {}, "outputs": [], "source": [ - "data_dir = '../data/test_images'\n", + "root_dir = Path(__file__).parent.parent\n", + "data_dir = root_dir / \"tests\" / \"data\" / \"test_images\"\n", "\n", "batch_size = 32\n", "epochs = 8\n", @@ -106,7 +108,7 @@ "source": [ "dataset = datasets.ImageFolder(data_dir, transform=transforms.Resize((512, 512)))\n", "dataset.samples = [\n", - " (p, p.replace(data_dir, data_dir + '_cropped'))\n", + " (p, p.replace(str(data_dir), str(data_dir.parent / (data_dir.name + \"_aligned\"))))\n", " for p, _ in dataset.samples\n", "]\n", " \n", @@ -168,7 +170,7 @@ " transforms.ToTensor(),\n", " fixed_image_standardization\n", "])\n", - "dataset = datasets.ImageFolder(data_dir + '_cropped', transform=trans)\n", + "dataset = datasets.ImageFolder(data_dir + '_aligned', transform=trans)\n", "img_inds = np.arange(len(dataset))\n", "np.random.shuffle(img_inds)\n", "train_inds = img_inds[:int(0.8 * len(img_inds))]\n", diff --git a/examples/infer.ipynb b/examples/infer.ipynb index d36a056f..3218656c 100644 --- a/examples/infer.ipynb +++ b/examples/infer.ipynb @@ -20,13 +20,14 @@ "metadata": {}, "outputs": [], "source": [ + "from pathlib import Path\n", + "import os\n", + "\n", "from facenet_pytorch import MTCNN, InceptionResnetV1\n", "import torch\n", "from torch.utils.data import DataLoader\n", "from torchvision import datasets\n", - "import numpy as np\n", "import pandas as pd\n", - "import os\n", "\n", "workers = 0 if os.name == 'nt' else 4" ] @@ -118,7 +119,10 @@ "def collate_fn(x):\n", " return x[0]\n", "\n", - "dataset = datasets.ImageFolder('../data/test_images')\n", + "root_dir = Path(__file__).parent.parent\n", + "data_dir = root_dir / \"tests\" / \"data\" / \"test_images\"\n", + "\n", + "dataset = datasets.ImageFolder(data_dir)\n", "dataset.idx_to_class = {i:c for c, i in dataset.class_to_idx.items()}\n", "loader = DataLoader(dataset, collate_fn=collate_fn, num_workers=workers)" ] @@ -242,4 +246,4 @@ }, "nbformat": 4, "nbformat_minor": 2 -} \ No newline at end of file +} diff --git a/examples/infer_cn.ipynb b/examples/infer_cn.ipynb index 114f0d07..cf69650a 100644 --- a/examples/infer_cn.ipynb +++ b/examples/infer_cn.ipynb @@ -26,13 +26,14 @@ }, "outputs": [], "source": [ + "from pathlib import Path\n", + "import os\n", + "\n", "from facenet_pytorch import MTCNN, InceptionResnetV1\n", "import torch\n", "from torch.utils.data import DataLoader\n", "from torchvision import datasets\n", - "import numpy as np\n", "import pandas as pd\n", - "import os\n", "\n", "workers = 0 if os.name == 'nt' else 4" ] @@ -144,7 +145,10 @@ "def collate_fn(x):\n", " return x[0]\n", "\n", - "dataset = datasets.ImageFolder('../data/test_images')\n", + "root_dir = Path(__file__).parent.parent\n", + "data_dir = root_dir / \"tests\" / \"data\" / \"test_images\"\n", + "\n", + "dataset = datasets.ImageFolder(data_dir)\n", "dataset.idx_to_class = {i:c for c, i in dataset.class_to_idx.items()}\n", "loader = DataLoader(dataset, collate_fn=collate_fn, num_workers=workers)" ] diff --git a/examples/lfw_evaluate.ipynb b/examples/lfw_evaluate.ipynb index 7cde66e6..ef1a1fdc 100644 --- a/examples/lfw_evaluate.ipynb +++ b/examples/lfw_evaluate.ipynb @@ -141,7 +141,7 @@ "box_probs = []\n", "\n", "for i, (x, b_paths) in enumerate(loader):\n", - " crops = [p.replace(data_dir, data_dir + '_cropped') for p in b_paths]\n", + " crops = [p.replace(str(data_dir), str(data_dir.parent / (data_dir.name + \"_aligned\"))) for p in b_paths]\n", " mtcnn(x, save_path=crops)\n", " crop_paths.extend(crops)\n", " print('\\rBatch {} of {}'.format(i + 1, len(loader)), end='')" @@ -176,7 +176,7 @@ " fixed_image_standardization\n", "])\n", "\n", - "dataset = datasets.ImageFolder(data_dir + '_cropped', transform=trans)\n", + "dataset = datasets.ImageFolder(data_dir.parent / data_dir.name + \"_aligned\", transform=trans)\n", "\n", "embed_loader = DataLoader(\n", " dataset,\n", @@ -452,7 +452,7 @@ "outputs": [], "source": [ "pairs = read_pairs(pairs_path)\n", - "path_list, issame_list = get_paths(data_dir+'_cropped', pairs)\n", + "path_list, issame_list = get_paths(data_dir+'_aligned', pairs)\n", "embeddings = np.array([embeddings_dict[path] for path in path_list])\n", "\n", "tpr, fpr, accuracy, val, val_std, far, fp, fn = evaluate(embeddings, issame_list)" @@ -519,4 +519,4 @@ }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} diff --git a/examples/lfw_evaluate_cn.ipynb b/examples/lfw_evaluate_cn.ipynb index ff73624f..9096b4f7 100644 --- a/examples/lfw_evaluate_cn.ipynb +++ b/examples/lfw_evaluate_cn.ipynb @@ -146,7 +146,7 @@ "box_probs = []\n", "\n", "for i, (x, b_paths) in enumerate(loader):\n", - " crops = [p.replace(data_dir, data_dir + '_cropped') for p in b_paths]\n", + " crops = [p.replace(str(data_dir), str(data_dir.parent / (data_dir.name + \"_aligned\"))) for p in b_paths]\n", " mtcnn(x, save_path=crops)\n", " crop_paths.extend(crops)\n", " print('\\r第 {} 批,共 {} 批'.format(i + 1, len(loader)), end='')" @@ -185,7 +185,7 @@ " fixed_image_standardization\n", "])\n", "\n", - "dataset = datasets.ImageFolder(data_dir + '_cropped', transform=trans)\n", + "dataset = datasets.ImageFolder(data_dir.parent / data_dir.name + \"_aligned\", transform=trans)\n", "\n", "embed_loader = DataLoader(\n", " dataset,\n", @@ -454,7 +454,7 @@ "outputs": [], "source": [ "pairs = read_pairs(pairs_path)\n", - "path_list, issame_list = get_paths(data_dir+'_cropped', pairs)\n", + "path_list, issame_list = get_paths(data_dir+'_aligned', pairs)\n", "embeddings = np.array([embeddings_dict[path] for path in path_list])\n", "\n", "tpr, fpr, accuracy, val, val_std, far, fp, fn = evaluate(embeddings, issame_list)" @@ -490,8 +490,7 @@ ], "source": [ "print(accuracy)\n", - "np.mean(accuracy)\n", - "\n" + "np.mean(accuracy)" ] } ], diff --git a/facenet_pytorch/__init__.py b/facenet_pytorch/__init__.py new file mode 100644 index 00000000..f11d3287 --- /dev/null +++ b/facenet_pytorch/__init__.py @@ -0,0 +1,14 @@ +import warnings + +from facenet_pytorch.models.inception_resnet_v1 import InceptionResnetV1 +from facenet_pytorch.models.mtcnn import MTCNN, ONet, PNet, RNet, fixed_image_standardization, prewhiten +from facenet_pytorch.models.utils import training +from facenet_pytorch.models.utils.detect_face import extract_face + +__all__ = ["InceptionResnetV1", "MTCNN", "ONet", "PNet", "RNet", "fixed_image_standardization", "prewhiten", "training", "extract_face"] + +warnings.filterwarnings( + action="ignore", + message="This overload of nonzero is deprecated:\n\tnonzero()", + category=UserWarning, +) diff --git a/data/onet.pt b/facenet_pytorch/data/onet.pt similarity index 100% rename from data/onet.pt rename to facenet_pytorch/data/onet.pt diff --git a/data/pnet.pt b/facenet_pytorch/data/pnet.pt similarity index 100% rename from data/pnet.pt rename to facenet_pytorch/data/pnet.pt diff --git a/data/rnet.pt b/facenet_pytorch/data/rnet.pt similarity index 100% rename from data/rnet.pt rename to facenet_pytorch/data/rnet.pt diff --git a/models/inception_resnet_v1.py b/facenet_pytorch/models/inception_resnet_v1.py similarity index 100% rename from models/inception_resnet_v1.py rename to facenet_pytorch/models/inception_resnet_v1.py diff --git a/models/mtcnn.py b/facenet_pytorch/models/mtcnn.py similarity index 98% rename from models/mtcnn.py rename to facenet_pytorch/models/mtcnn.py index 7eb64550..202943d0 100644 --- a/models/mtcnn.py +++ b/facenet_pytorch/models/mtcnn.py @@ -1,10 +1,12 @@ import os +import importlib.resources import numpy as np import torch from torch import nn -from .utils.detect_face import detect_face, extract_face +from facenet_pytorch.models.utils.detect_face import detect_face, extract_face +import facenet_pytorch.data class PNet(nn.Module): @@ -31,7 +33,7 @@ def __init__(self, pretrained=True): self.training = False if pretrained: - state_dict_path = os.path.join(os.path.dirname(__file__), "../data/pnet.pt") + state_dict_path = importlib.resources.path(facenet_pytorch.data, "pnet.pt") state_dict = torch.load(state_dict_path) self.load_state_dict(state_dict) @@ -76,7 +78,7 @@ def __init__(self, pretrained=True): self.training = False if pretrained: - state_dict_path = os.path.join(os.path.dirname(__file__), "../data/rnet.pt") + state_dict_path = importlib.resources.path(facenet_pytorch.data, "rnet.pt") state_dict = torch.load(state_dict_path) self.load_state_dict(state_dict) @@ -129,7 +131,7 @@ def __init__(self, pretrained=True): self.training = False if pretrained: - state_dict_path = os.path.join(os.path.dirname(__file__), "../data/onet.pt") + state_dict_path = importlib.resources.path(facenet_pytorch.data, "onet.pt") state_dict = torch.load(state_dict_path) self.load_state_dict(state_dict) diff --git a/models/utils/detect_face.py b/facenet_pytorch/models/utils/detect_face.py similarity index 100% rename from models/utils/detect_face.py rename to facenet_pytorch/models/utils/detect_face.py diff --git a/models/utils/download.py b/facenet_pytorch/models/utils/download.py similarity index 100% rename from models/utils/download.py rename to facenet_pytorch/models/utils/download.py diff --git a/models/utils/tensorflow2pytorch.py b/facenet_pytorch/models/utils/tensorflow2pytorch.py similarity index 99% rename from models/utils/tensorflow2pytorch.py rename to facenet_pytorch/models/utils/tensorflow2pytorch.py index 7972b74b..a55e2634 100644 --- a/models/utils/tensorflow2pytorch.py +++ b/facenet_pytorch/models/utils/tensorflow2pytorch.py @@ -1,14 +1,12 @@ import json import os -import sys import tensorflow as tf import torch from dependencies.facenet.src import facenet from dependencies.facenet.src.align import detect_face -from dependencies.facenet.src.models import inception_resnet_v1 as tf_mdl -from models.inception_resnet_v1 import InceptionResnetV1 +from facenet_pytorch.models.inception_resnet_v1 import InceptionResnetV1 from models.mtcnn import ONet, PNet, RNet diff --git a/models/utils/training.py b/facenet_pytorch/models/utils/training.py similarity index 100% rename from models/utils/training.py rename to facenet_pytorch/models/utils/training.py diff --git a/setup.py b/setup.py index 3c096e97..b7086667 100644 --- a/setup.py +++ b/setup.py @@ -30,7 +30,6 @@ "facenet_pytorch.models.utils", "facenet_pytorch.data", ], - package_dir={"facenet_pytorch": "."}, package_data={"": ["*net.pt"]}, classifiers=[ "Programming Language :: Python :: 3", diff --git a/data/facenet-pytorch-banner.png b/static/facenet-pytorch-banner.png similarity index 100% rename from data/facenet-pytorch-banner.png rename to static/facenet-pytorch-banner.png diff --git a/tests/actions_test.py b/tests/actions_test.py index 307673f9..ce575228 100644 --- a/tests/actions_test.py +++ b/tests/actions_test.py @@ -1,10 +1,12 @@ """ -The following code is intended to be run only by Github actions for continuius intengration and -testing purposes. For implementation examples see notebooks in the examples folder. +The following code is intended to be run only by GitHub actions for continuous integration and +testing purposes. +For implementation examples, see notebooks in the examples folder. """ import glob import os +from pathlib import Path import sys from time import time @@ -12,11 +14,10 @@ import pandas as pd import torch from PIL import Image, ImageDraw -from torch.utils.data import DataLoader from torchvision import datasets, transforms -from models.inception_resnet_v1 import InceptionResnetV1, get_torch_home -from models.mtcnn import MTCNN, fixed_image_standardization +from facenet_pytorch.models.inception_resnet_v1 import InceptionResnetV1, get_torch_home +from facenet_pytorch.models.mtcnn import MTCNN, fixed_image_standardization #### CLEAR ALL OUTPUT FILES #### @@ -32,19 +33,17 @@ #### TEST EXAMPLE IPYNB'S #### +test_dir = Path(__file__).parent +root_dir = test_dir.parent +example_dir = root_dir / "examples" -os.system("jupyter nbconvert --to script --stdout examples/infer.ipynb examples/finetune.ipynb > examples/tmptest.py") -os.chdir("examples") -try: - import examples.tmptest -except: - import tmptest -os.chdir("..") +os.system(f"jupyter nbconvert --to python --stdout {example_dir}/infer.ipynb {example_dir}/finetune.ipynb > {example_dir}/tmptest.py") - -#### TEST MTCNN #### +exec((example_dir / "tmptest.py").open().read()) +os.chdir(test_dir) +#### TEST MTCNN #### def get_image(path, trans): img = Image.open(path) img = trans(img) @@ -146,10 +145,9 @@ def get_image(path, trans): assert total_error_fromfile < 1e-2 -#### TEST CLASSIFICATION #### - -resnet_pt = InceptionResnetV1(pretrained=ds, classify=True).eval() -prob = resnet_pt(aligned) + #### TEST CLASSIFICATION #### + resnet_pt = InceptionResnetV1(pretrained=ds, classify=True).eval() + prob = resnet_pt(aligned) #### MULTI-FACE TEST #### diff --git a/data/multiface.jpg b/tests/data/multiface.jpg similarity index 100% rename from data/multiface.jpg rename to tests/data/multiface.jpg diff --git a/data/multiface_detected.png b/tests/data/multiface_detected.png similarity index 100% rename from data/multiface_detected.png rename to tests/data/multiface_detected.png diff --git a/data/test_images/angelina_jolie/1.jpg b/tests/data/test_images/angelina_jolie/1.jpg similarity index 100% rename from data/test_images/angelina_jolie/1.jpg rename to tests/data/test_images/angelina_jolie/1.jpg diff --git a/data/test_images/bradley_cooper/1.jpg b/tests/data/test_images/bradley_cooper/1.jpg similarity index 100% rename from data/test_images/bradley_cooper/1.jpg rename to tests/data/test_images/bradley_cooper/1.jpg diff --git a/data/test_images/kate_siegel/1.jpg b/tests/data/test_images/kate_siegel/1.jpg similarity index 100% rename from data/test_images/kate_siegel/1.jpg rename to tests/data/test_images/kate_siegel/1.jpg diff --git a/data/test_images/paul_rudd/1.jpg b/tests/data/test_images/paul_rudd/1.jpg similarity index 100% rename from data/test_images/paul_rudd/1.jpg rename to tests/data/test_images/paul_rudd/1.jpg diff --git a/data/test_images/shea_whigham/1.jpg b/tests/data/test_images/shea_whigham/1.jpg similarity index 100% rename from data/test_images/shea_whigham/1.jpg rename to tests/data/test_images/shea_whigham/1.jpg diff --git a/data/test_images_aligned/angelina_jolie/1.png b/tests/data/test_images_aligned/angelina_jolie/1.png similarity index 100% rename from data/test_images_aligned/angelina_jolie/1.png rename to tests/data/test_images_aligned/angelina_jolie/1.png diff --git a/data/test_images_aligned/bradley_cooper/1.png b/tests/data/test_images_aligned/bradley_cooper/1.png similarity index 100% rename from data/test_images_aligned/bradley_cooper/1.png rename to tests/data/test_images_aligned/bradley_cooper/1.png diff --git a/data/test_images_aligned/kate_siegel/1.png b/tests/data/test_images_aligned/kate_siegel/1.png similarity index 100% rename from data/test_images_aligned/kate_siegel/1.png rename to tests/data/test_images_aligned/kate_siegel/1.png diff --git a/data/test_images_aligned/paul_rudd/1.png b/tests/data/test_images_aligned/paul_rudd/1.png similarity index 100% rename from data/test_images_aligned/paul_rudd/1.png rename to tests/data/test_images_aligned/paul_rudd/1.png diff --git a/data/test_images_aligned/shea_whigham/1.png b/tests/data/test_images_aligned/shea_whigham/1.png similarity index 100% rename from data/test_images_aligned/shea_whigham/1.png rename to tests/data/test_images_aligned/shea_whigham/1.png