Skip to main content

A PyTorch landmarks-only library with 100+ data augmentations, training and inference, can easily install with pip and compatible with albumentations and torchvision.

Project description

torchlm-logo

English | 中文文档

🤗 Introduction

torchlm is aims to build a high level pipeline for face landmarks detection, support 100+ data augmentations, training and inference, can can easily install with pip.

❤️ Star 🌟👆🏻 this repo to support me if it does any helps to you, thanks ~

👋 Core Features

  • High level pipeline for training and inference.
  • Provides 30+ native landmarks data augmentations.
  • Can bind 80+ transforms from torchvision and albumentations with one-line-code.
  • Support awesome models for face landmarks detection, such as YOLOX, YOLOv5, ResNet, MobileNet, ShuffleNet and PIPNet, etc.

🆕 What's New

🛠️ Usage

Requirements

  • opencv-python-headless>=4.5.2
  • numpy>=1.14.4
  • torch>=1.6.0
  • torchvision>=0.8.0
  • albumentations>=1.1.0
  • onnx>=1.8.0
  • onnxruntime>=1.7.0
  • tqdm>=4.10.0

Installation

you can install torchlm directly from pypi. See NOTE before installation!!!

pip3 install torchlm
# install from specific pypi mirrors use '-i'
pip3 install torchlm -i https://pypi.org/simple/

or install from source if you want the latest torchlm and install it in editable mode with -e.

# clone torchlm repository locally if you want the latest torchlm
git clone --depth=1 https://github.com/DefTruth/torchlm.git 
cd torchlm
# install in editable mode
pip install -e .

NOTE: If you have the conflict problem between different installed version of opencv (opencv-python and opencv-python-headless, ablumentations need opencv-python-headless). Please uninstall the opencv-python and opencv-python-headless first, and then reinstall torchlm. See albumentations#1139 for more details.

# first uninstall confilct opencvs
pip uninstall opencv-python
pip uninstall opencv-python-headless
pip uninstall torchlm  # if you have installed torchlm
# then reinstall torchlm
pip install torchlm # will also install deps, e.g opencv

🌟🌟Data Augmentation

torchlm provides 30+ native data augmentations for landmarks and can bind with 80+ transforms from torchvision and albumentations through torchlm.bind method. Further, torchlm.bind provide a prob param at bind-level to force any transform or callable be a random-style augmentation. The data augmentations in torchlm are safe and simplest. Any transform operations at runtime cause landmarks outside will be auto dropped to keep the number of landmarks unchanged. The layout format of landmarks is xy with shape (N, 2), N denotes the number of the input landmarks. No matter the input is a np.ndarray or a torch Tensor, torchlm will automatically be compatible with different data types and then wrap it back to the original type through a autodtype wrapper.

  • use almost 30+ native transforms from torchlm directly
import torchlm
transform = torchlm.LandmarksCompose([
    torchlm.LandmarksRandomScale(prob=0.5),
    torchlm.LandmarksRandomMask(prob=0.5),
    torchlm.LandmarksRandomBlur(kernel_range=(5, 25), prob=0.5),
    torchlm.LandmarksRandomBrightness(prob=0.),
    torchlm.LandmarksRandomRotate(40, prob=0.5, bins=8),
    torchlm.LandmarksRandomCenterCrop((0.5, 1.0), (0.5, 1.0), prob=0.5)
])
  • bind 80+ torchvision and albumentations's transforms through torchlm.bind
transform = torchlm.LandmarksCompose([
    torchlm.bind(torchvision.transforms.GaussianBlur(kernel_size=(5, 25)), prob=0.5),  
    torchlm.bind(albumentations.ColorJitter(p=0.5))
])

See transforms.md for supported transforms sets and more example can be found at test/transforms.py.

bind custom callable array or Tensor functions through torchlm.bind
# First, defined your custom functions
def callable_array_noop(img: np.ndarray, landmarks: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: # do some transform here ...
    return img.astype(np.uint32), landmarks.astype(np.float32)

def callable_tensor_noop(img: Tensor, landmarks: Tensor) -> Tuple[Tensor, Tensor]: # do some transform here ...
    return img, landmarks
# Then, bind your functions and put it into the transforms pipeline.
transform = torchlm.LandmarksCompose([
        torchlm.bind(callable_array_noop, bind_type=torchlm.BindEnum.Callable_Array),
        torchlm.bind(callable_tensor_noop, bind_type=torchlm.BindEnum.Callable_Tensor, prob=0.5)
])
some global debug setting for torchlm's transform
  • setup logging mode as True globally might help you figure out the runtime details
# some global setting
torchlm.set_transforms_debug(True)
torchlm.set_transforms_logging(True)
torchlm.set_autodtype_logging(True)

some detail information will show you at each runtime, the infos might look like

LandmarksRandomScale() AutoDtype Info: AutoDtypeEnum.Array_InOut
LandmarksRandomScale() Execution Flag: False
BindTorchVisionTransform(GaussianBlur())() AutoDtype Info: AutoDtypeEnum.Tensor_InOut
BindTorchVisionTransform(GaussianBlur())() Execution Flag: True
BindAlbumentationsTransform(ColorJitter())() AutoDtype Info: AutoDtypeEnum.Array_InOut
BindAlbumentationsTransform(ColorJitter())() Execution Flag: True
BindTensorCallable(callable_tensor_noop())() AutoDtype Info: AutoDtypeEnum.Tensor_InOut
BindTensorCallable(callable_tensor_noop())() Execution Flag: False
Error at LandmarksRandomTranslate() Skip, Flag: False Error Info: LandmarksRandomTranslate() have 98 input landmarks, but got 96 output landmarks!
LandmarksRandomTranslate() Execution Flag: False
  • Execution Flag: True means current transform was executed successful, False means it was not executed because of the random probability or some Runtime Exceptions(torchlm will should the error infos if debug mode is True).

  • AutoDtype Info:

    • Array_InOut means current transform need a np.ndnarray as input and then output a np.ndarray.
    • Tensor_InOut means current transform need a torch Tensor as input and then output a torch Tensor.
    • Array_In means current transform needs a np.ndarray input and then output a torch Tensor.
    • Tensor_In means current transform needs a torch Tensor input and then output a np.ndarray.

    But, is ok if you pass a Tensor to a np.ndarray-like transform, torchlm will automatically be compatible with different data types and then wrap it back to the original type through a autodtype wrapper.

🎉🎉Training

In torchlm, each model have a high level and user-friendly API named training, here is a example of PIPNet.

from torchlm.models import pipnet

model = pipnet(
        backbone="resnet18",
        pretrained=False,
        num_nb=10,
        num_lms=98,
        net_stride=32,
        input_size=256,
        meanface_type="wflw",
        backbone_pretrained=True,
        map_location="cuda",
        checkpoint=None
)

model.training(
        self,
        annotation_path: str,
        criterion_cls: nn.Module = nn.MSELoss(),
        criterion_reg: nn.Module = nn.L1Loss(),
        learning_rate: float = 0.0001,
        cls_loss_weight: float = 10.,
        reg_loss_weight: float = 1.,
        num_nb: int = 10,
        num_epochs: int = 60,
        save_dir: Optional[str] = "./save",
        save_interval: Optional[int] = 10,
        save_prefix: Optional[str] = "",
        decay_steps: Optional[List[int]] = (30, 50),
        decay_gamma: Optional[float] = 0.1,
        device: Optional[Union[str, torch.device]] = "cuda",
        transform: Optional[transforms.LandmarksCompose] = None,
        coordinates_already_normalized: Optional[bool] = False,
        **kwargs: Any  # params for DataLoader
) -> nn.Module:

Please jump to the entry point of the function for the detail documentations of training API for each defined models in torchlm, e.g pipnet/_impls.py#L159. Further, the model implementation plan is as follows:

❔ YOLOX ❔ YOLOv5 ❔ NanoDet ✅ PIPNet ❔ ResNet ❔ MobileNet ❔ ShuffleNet ❔...

✅ = known work and official supported, ❔ = in my plan, but not coming soon.

👀👇 Inference

C++ API

The ONNXRuntime(CPU/GPU), MNN, NCNN and TNN C++ inference of torchlm will be release at lite.ai.toolkit.

Python API

In torchlm, we offer a high level API named runtime.bind to bind any models in torchlm and then you can run the runtime.forward API to get the output landmarks and bboxes, here is a example of PIPNet.

import cv2
import torchlm
from torchlm.tools import faceboxesv2
from torchlm.models import pipnet

def test_pipnet_runtime():
    img_path = "./1.jpg"
    save_path = "./1.jpg"
    checkpoint = "./pipnet_resnet18_10x98x32x256_wflw.pth"
    image = cv2.imread(img_path)

    torchlm.runtime.bind(faceboxesv2())
    torchlm.runtime.bind(
        pipnet(
            backbone="resnet18",
            pretrained=True,
            num_nb=10,
            num_lms=98,
            net_stride=32,
            input_size=256,
            meanface_type="wflw",
            backbone_pretrained=True,
            map_location="cpu",
            checkpoint=checkpoint
        )
    )
    landmarks, bboxes = torchlm.runtime.forward(image)
    image = torchlm.utils.draw_bboxes(image, bboxes=bboxes)
    image = torchlm.utils.draw_landmarks(image, landmarks=landmarks)

    cv2.imwrite(save_path, image)

📖 Documentations

🎓 License

The code of torchlm is released under the MIT License.

❤️ Contribution

Please consider ⭐ this repo if you like it, as it is the simplest way to support me.

👋 Acknowledgement

The implementation of torchlm's transforms borrow the code from Paperspace .

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

torchlm-0.1.6.tar.gz (8.8 MB view details)

Uploaded Source

Built Distribution

torchlm-0.1.6-py3-none-any.whl (8.8 MB view details)

Uploaded Python 3

File details

Details for the file torchlm-0.1.6.tar.gz.

File metadata

  • Download URL: torchlm-0.1.6.tar.gz
  • Upload date:
  • Size: 8.8 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.25.1 requests-toolbelt/0.9.1 urllib3/1.26.4 tqdm/4.60.0 importlib-metadata/4.10.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.2

File hashes

Hashes for torchlm-0.1.6.tar.gz
Algorithm Hash digest
SHA256 8070e7dfd6fe02856829c08d4eabd93bb2b9676991586c918ebcb598b71f7412
MD5 ae48eaec012736fdb0b83a1b73e03212
BLAKE2b-256 4ee8065c7f384668e08f0d18dcf2e50a6b7edf4fa6d2489fcf78f51e1d0097b5

See more details on using hashes here.

File details

Details for the file torchlm-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: torchlm-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 8.8 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/32.0 requests/2.25.1 requests-toolbelt/0.9.1 urllib3/1.26.4 tqdm/4.60.0 importlib-metadata/4.10.1 keyring/23.5.0 rfc3986/2.0.0 colorama/0.4.4 CPython/3.8.2

File hashes

Hashes for torchlm-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 b5ef900d9a8e2fafd31c00c84eb23a9bc2b530fc71552fcd50459a681f59fd9a
MD5 1c43d3f6a8937975d3039467f674d9a0
BLAKE2b-256 af0193aa7f30b3d7bb33d6ee3a6fc4637a4db29700e1ff41aff41b20a5ca6f83

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page