Giter Club home page Giter Club logo

lightly's Introduction

Lightly SSL self-supervised learning Logo

GitHub Unit Tests PyPI Downloads Code style: black Discord

Lightly SSL is a computer vision framework for self-supervised learning.

For a commercial version with more features, including Docker support and pretraining models for embedding, classification, detection, and segmentation tasks with a single command, please contact [email protected].

We've also built a whole platform on top, with additional features for active learning and data curation. If you're interested in the Lightly Worker Solution to easily process millions of samples and run powerful algorithms on your data, check out lightly.ai. It's free to get started!

Features

This self-supervised learning framework offers the following features:

  • Modular framework, which exposes low-level building blocks such as loss functions and model heads.
  • Easy to use and written in a PyTorch like style.
  • Supports custom backbone models for self-supervised pre-training.
  • Support for distributed training using PyTorch Lightning.

Supported Models

You can find sample code for all the supported models here. We provide PyTorch, PyTorch Lightning, and PyTorch Lightning distributed examples for all models to kickstart your project.

Models:

Tutorials

Want to jump to the tutorials and see Lightly in action?

Community and partner projects:

Quick Start

Lightly requires Python 3.7+. We recommend installing Lightly in a Linux or OSX environment. Python 3.12 is not yet supported, as PyTorch itself lacks Python 3.12 compatibility.

Dependencies

Due to the modular nature of the Lightly package some modules can be used with older versions of dependencies. However, to use all features as of today lightly requires the following dependencies:

Lightly is compatible with PyTorch and PyTorch Lightning v2.0+!

Installation

You can install Lightly and its dependencies from PyPI with:

pip3 install lightly

We strongly recommend that you install Lightly in a dedicated virtualenv, to avoid conflicting with your system packages.

Lightly in Action

With Lightly, you can use the latest self-supervised learning methods in a modular way using the full power of PyTorch. Experiment with different backbones, models, and loss functions. The framework has been designed to be easy to use from the ground up. Find more examples in our docs.

import torch
import torchvision

from lightly import loss
from lightly import transforms
from lightly.data import LightlyDataset
from lightly.models.modules import heads


# Create a PyTorch module for the SimCLR model.
class SimCLR(torch.nn.Module):
    def __init__(self, backbone):
        super().__init__()
        self.backbone = backbone
        self.projection_head = heads.SimCLRProjectionHead(
            input_dim=512,  # Resnet18 features have 512 dimensions.
            hidden_dim=512,
            output_dim=128,
        )

    def forward(self, x):
        features = self.backbone(x).flatten(start_dim=1)
        z = self.projection_head(features)
        return z


# Use a resnet backbone.
backbone = torchvision.models.resnet18()
# Ignore the classification head as we only want the features.
backbone.fc = torch.nn.Identity()

# Build the SimCLR model.
model = SimCLR(backbone)

# Prepare transform that creates multiple random views for every image.
transform = transforms.SimCLRTransform(input_size=32, cj_prob=0.5)


# Create a dataset from your image folder.
dataset = LightlyDataset(input_dir="./my/cute/cats/dataset/", transform=transform)

# Build a PyTorch dataloader.
dataloader = torch.utils.data.DataLoader(
    dataset,  # Pass the dataset to the dataloader.
    batch_size=128,  # A large batch size helps with the learning.
    shuffle=True,  # Shuffling is important!
)

# Lightly exposes building blocks such as loss functions.
criterion = loss.NTXentLoss(temperature=0.5)

# Get a PyTorch optimizer.
optimizer = torch.optim.SGD(model.parameters(), lr=0.1, weight_decay=1e-6)

# Train the model.
for epoch in range(10):
    for (view0, view1), targets, filenames in dataloader:
        z0 = model(view0)
        z1 = model(view1)
        loss = criterion(z0, z1)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()
        print(f"loss: {loss.item():.5f}")

You can easily use another model like SimSiam by swapping the model and the loss function.

# PyTorch module for the SimSiam model.
class SimSiam(torch.nn.Module):
    def __init__(self, backbone):
        super().__init__()
        self.backbone = backbone
        self.projection_head = heads.SimSiamProjectionHead(512, 512, 128)
        self.prediction_head = heads.SimSiamPredictionHead(128, 64, 128)

    def forward(self, x):
        features = self.backbone(x).flatten(start_dim=1)
        z = self.projection_head(features)
        p = self.prediction_head(z)
        z = z.detach()
        return z, p


model = SimSiam(backbone)

# Use the SimSiam loss function.
criterion = loss.NegativeCosineSimilarity()

You can find a more complete example for SimSiam here.

Use PyTorch Lightning to train the model:

from pytorch_lightning import LightningModule, Trainer

class SimCLR(LightningModule):
    def __init__(self):
        super().__init__()
        resnet = torchvision.models.resnet18()
        resnet.fc = torch.nn.Identity()
        self.backbone = resnet
        self.projection_head = heads.SimCLRProjectionHead(512, 512, 128)
        self.criterion = loss.NTXentLoss()

    def forward(self, x):
        features = self.backbone(x).flatten(start_dim=1)
        z = self.projection_head(features)
        return z

    def training_step(self, batch, batch_index):
        (view0, view1), _, _ = batch
        z0 = self.forward(view0)
        z1 = self.forward(view1)
        loss = self.criterion(z0, z1)
        return loss

    def configure_optimizers(self):
        optim = torch.optim.SGD(self.parameters(), lr=0.06)
        return optim


model = SimCLR()
trainer = Trainer(max_epochs=10, devices=1, accelerator="gpu")
trainer.fit(model, dataloader)

See our docs for a full PyTorch Lightning example.

Or train the model on 4 GPUs:

# Use distributed version of loss functions.
criterion = loss.NTXentLoss(gather_distributed=True)

trainer = Trainer(
    max_epochs=10,
    devices=4,
    accelerator="gpu",
    strategy="ddp",
    sync_batchnorm=True,
    use_distributed_sampler=True,  # or replace_sampler_ddp=True for PyTorch Lightning <2.0
)
trainer.fit(model, dataloader)

We provide multi-GPU training examples with distributed gather and synchronized BatchNorm. Have a look at our docs regarding distributed training.

Benchmarks

Implemented models and their performance on various datasets. Hyperparameters are not tuned for maximum accuracy. For detailed results and more information about the benchmarks click here.

ImageNet1k

ImageNet1k benchmarks

Note: Evaluation settings are based on these papers:

See the benchmarking scripts for details.

Model Backbone Batch Size Epochs Linear Top1 Finetune Top1 kNN Top1 Tensorboard Checkpoint
BarlowTwins Res50 256 100 62.9 72.6 45.6 link link
BYOL Res50 256 100 62.5 74.5 46.0 - link
DINO Res50 128 100 68.2 72.5 49.9 link link
MAE ViT-B/16 256 100 46.0 81.3 11.2 - link
MoCoV2 Res50 256 100 61.5 74.3 41.8 - link
SimCLR* Res50 256 100 63.2 73.9 44.8 link link
SimCLR* + DCL Res50 256 100 65.1 73.5 49.6 link link
SimCLR* + DCLW Res50 256 100 64.5 73.2 48.5 link link
SwAV Res50 256 100 67.2 75.4 49.5 link link
TiCo Res50 256 100 49.7 72.7 26.6 - link
VICReg Res50 256 100 63.0 73.7 46.3 link link

*We use square root learning rate scaling instead of linear scaling as it yields better results for smaller batch sizes. See Appendix B.1 in the SimCLR paper.

ImageNet100

ImageNet100 benchmarks detailed results

Imagenette

Imagenette benchmarks detailed results

CIFAR-10

CIFAR-10 benchmarks detailed results

Terminology

Below you can see a schematic overview of the different concepts in the package. The terms in bold are explained in more detail in our documentation.

Overview of the Lightly pip package

Next Steps

Head to the documentation and see the things you can achieve with Lightly!

Development

To install dev dependencies (for example to contribute to the framework) you can use the following command:

pip3 install -e ".[dev]"

For more information about how to contribute have a look here.

Running Tests

Unit tests are within the tests directory and we recommend running them using pytest. There are two test configurations available. By default, only a subset will be run:

make test-fast

To run all tests (including the slow ones) you can use the following command:

make test

To test a specific file or directory use:

pytest <path to file or directory>

Code Formatting

To format code with black and isort run:

make format

Further Reading

Self-Supervised Learning:

FAQ

  • Why should I care about self-supervised learning? Aren't pre-trained models from ImageNet much better for transfer learning?

    • Self-supervised learning has become increasingly popular among scientists over the last years because the learned representations perform extraordinarily well on downstream tasks. This means that they capture the important information in an image better than other types of pre-trained models. By training a self-supervised model on your dataset, you can make sure that the representations have all the necessary information about your images.
  • How can I contribute?

    • Create an issue if you encounter bugs or have ideas for features we should implement. You can also add your own code by forking this repository and creating a PR. More details about how to contribute with code is in our contribution guide.
  • Is this framework for free?

    • Yes, this framework is completely free to use and we provide the source code. We believe that we need to make training deep learning models more data efficient to achieve widespread adoption. One step to achieve this goal is by leveraging self-supervised learning. The company behind Lightly is committed to keep this framework open-source.
  • If this framework is free, how is the company behind Lightly making money?

    • Training self-supervised models is only one part of our solution. The company behind Lightly focuses on processing and analyzing embeddings created by self-supervised models. By building, what we call a self-supervised active learning loop we help companies understand and work with their data more efficiently. As the Lightly Solution is a freemium product, you can try it out for free. However, we will charge for some features.
    • In any case this framework will always be free to use, even for commercial purposes.

Lightly in Research

Company behind this Open Source Framework

Lightly is a spin-off from ETH Zurich that helps companies build efficient active learning pipelines to select the most relevant data for their models.

You can find out more about the company and it's services by following the links below:

BibTeX

If you want to cite the framework feel free to use this:

@article{susmelj2020lightly,
  title={Lightly},
  author={Igor Susmelj and Matthias Heller and Philipp Wirth and Jeremy Prescott and Malte Ebner et al.},
  journal={GitHub. Note: https://github.com/lightly-ai/lightly},
  year={2020}
}

lightly's People

Contributors

adamjstewart avatar agpeshal avatar anishacharya avatar atharva-phatak avatar busycalibrating avatar drisdr avatar ersi-lightly avatar guarin avatar huan-lightly-0 avatar ibro45 avatar igorsusmelj avatar jannikwirtz avatar japrescott avatar johnsutor avatar jwuphysics avatar lukesutor avatar malteebner avatar matthiasheller avatar michal-lightly avatar natyren avatar otavioon avatar philippmwirth avatar pranavsinghps1 avatar ra1nik avatar sadimanna avatar shaundaley39 avatar shikharmn avatar shruti-shyam avatar utkuozbulak avatar vnshanmukh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lightly's Issues

Add support for new tag representation (binary mask)

The new Lightly platform will use a new tag representation. The transmitted data will be encoded as (16bit) hex strings.

The goal is to provide a simple helper class to work with this new format and switch between hex representation and binary representation.

Some functionalities which need to be implemented:

  • convert a hex string from the API to a binary mask
'ab3f' --> '1010101100111111'
  • get the set indices from a binary mask
  • basic arithmetics (&, ~) to set individual bits or invert the bitmask

RuntimeError: Forbidden upload to dataset with no existing tags

Got the following error while uploading embedding

Command used

lightly-upload token='' dataset_id='' embeddings='/home/usr/embeddings.csv'

Error

Traceback (most recent call last):
  File "/home/ubuntu/anaconda3/envs/effd/lib/python3.7/site-packages/lightly/cli/upload_cli.py", line 107, in upload_cli
    _upload_cli(cfg)
  File "/home/ubuntu/anaconda3/envs/effd/lib/python3.7/site-packages/lightly/cli/upload_cli.py", line 52, in _upload_cli
    embedding_name=cfg['embedding_name']
  File "/home/ubuntu/anaconda3/envs/effd/lib/python3.7/site-packages/lightly/api/upload.py", line 115, in upload_embeddings_from_csv
    raise RuntimeError(msg)
RuntimeError: Forbidden upload to dataset with no existing tags.

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.

Update config.yaml

The config.yaml has not the latest collate parameters. E.g. vf_prob, hf_prob is missing.

Additionally, there is no information about using half-precision. This should be added.

Replace the double-concatenation in the BaseCollateFunction

Currently, the BaseCollateFunction concatenates the input images as follows:

# three concatenations
b0 = torch.cat([transform(img) for img in imgs], 0)
b1 = torch.cat([transform(img) for img in imgs], 0)
return torch.cat([b0, b1], 0)

This is inefficient because new memory has to be allocated for every concatenation operation (of which there are three).
An alternative with a single concatenation would be:

# single concatenation
b = [transform(imgs[i % bsz]) for i in range(2*bsz)]
return torch.cat(b, 0)

A short experiment for bsz=512 and image_height=128 shows the potential speed-up:

Required time (so far): 0.1442425012588501s
Required time (new): 0.09266984462738038s  

Move loading of pretrained model from CLI to models

Pre-trained models from the model zoo can only be used from the CLI. It would be better to move them to the models module and add the option to load a pre-trained model.

Since there is no evidence pretrained models can hurt performance I would use them by default.

Then we could create them using:

E.g.

model = lightly.models.ResNetMoCo(num_ftrs=128, pretrained=True)

Add callback for knn-validation

Add hooks for validation at the end of each epoch (only informative if there are labels). Let's make sure it can be switched off and that the user can pass a validation set of his choice.

Update backbones to use default PyTorch implementations

Currently, the primary ResNet backbone uses a custom implementation that would not be directly compatible with the default PyTorch implementations (in addition to having a slightly different layer configuration). I think it would be advantageous to move to using the standard models offered in torchvision as most people likely default to those.

Add prebuilt collate functions for SimCLR, MoCo, and SwAV

This will save the user a line of code when trying to reproduce results and can make our example code leaner.

I suggest something like the following lines in lightly.data.collate.py

class SimCLRCollateFunction(ImageCollateFunction):
    """Description...

    """

    def __init__(self, input_size=32):
        super(SimCLRCollateFunction, self).__init__(
            input_size=input_size,
            # put all the SimCLR settings here
        )

Handle sampling results (tag) in PIP package

Description

After sampling, we get a tag back. Translate the tag into a list of filenames.

Tasks

  • Update API request to expect a tagId after sampling
  • Add method to translate a tag into a list of related filenames
  • Update methods depending on tags (download dataset, copy dataset) if needed

Make transform settable in Lightly Dataset

Currently if one has created a Lightly Dataset and wants to apply transforms at a later stage, we have to do it as follows:

dataset = data.LightlyDataset(root="./", name='CIFAR10', download=True)
...
use dataset to train SimCLR model for example
...
test_transforms = torchvision.transforms.ToTensor()
dataset.dataset.transform = test_transforms

We should extend the Dataset wrapper to directly support transforms.

Lightly-magic fails with trainer.max_epochs=0

When trying to use the lightly-magic CLI command without fine-tuning a model the CLI fails because it tries to load a checkpoint during the embedding phase which doesn't exist.

Command to reproduce: lightly-magic input_dir=raw trainer.max_epochs=0

Error message:

Training: 0it [00:00, ?it/s]Saving latest checkpoint...
[2020-11-26 15:47:06,327][lightning][INFO] - Saving latest checkpoint...
Training: 0it [00:00, ?it/s]
Best model is stored at: /datasets/videos/lightly_outputs/2020-11-26/15-46-37/
Traceback (most recent call last):
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/lightly_cli.py", line 72, in lightly_cli
    return _lightly_cli(cfg)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/lightly_cli.py", line 28, in _lightly_cli
    embeddings = _embed_cli(cfg, is_cli_call)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/lightly/cli/embed_cli.py", line 85, in _embed_cli
    checkpoint, map_location=device
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 581, in load
    with _open_file_like(f, 'rb') as opened_file:
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 230, in _open_file_like
    return _open_file(name_or_buffer, mode)
  File "/opt/conda/envs/lightly/lib/python3.7/site-packages/torch/serialization.py", line 211, in __init__
    super(_open_file, self).__init__(open(name, mode))
IsADirectoryError: [Errno 21] Is a directory: '/datasets/videos/lightly_outputs/2020-11-26/15-46-37/'

Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.

Fix TOX

At the moment, tox installs the dependencies in the local environment which can overwrite the current installation of required packages.

Update PIP API communication to use the new tag format

Depends on #111

The goal is to make sure the pip package can communicate using the new tag format.

Tasks

  • The Python client is generated with the new OpenAPI spec.
  • The client supports triggering a sampling with the preselected and query tag_id
  • The client reads the tag_id from the JobData
  • The client gets the tag from the tag_id (via the API)
  • The client extracts the sample_ids as bit mask from the tag
  • The client extracts the sample_ids as List[int] from the bit mask.
  • The client reads the filenames (as List[str]) from the API
  • The client maps the sample_ids to a list of filenames

Definition of done

  • A single test is defined to test all tasks
  • The single tests runs successfully with the updated server

Improve Documentation

Let's add some high-level information about the structure of the package. And also explain how the different modules are connected. Maybe even make an illustration?

Add description about high-level pip package structure

To make it easier for other contributors to work on lightly it would be good to outline a bit the structure of the PIP package and the reasoning behind it. There were many internal discussions on how to derive a scalable architecture.

Add batch shuffling to MoCo

In their paper, the authors of MoCo mention that they shuffle their batches in order to prevent a flow of information between the key encoder and the query encoder (if the positive pairs are normed with the same statistics, the model can cheat). As a solution, they shuffle the batches and split them into smaller sub-batches on which the batch norm is then calculated. We can and should implement a similar strategy.

Restructure config files

Currently, all CLI configs are stored in a single file config.yaml. In the future, the file structure should look as follows:

config/
|-- config.yaml
|-- model/
   |-- resnet-18.yaml
   |-- resnet-34.yaml
   |-- ...
|-- data/
  |-- data.yaml
|-- ...

This way, a user can still overwrite the default arguments like so:

lightly-train input_dir=my-dir model.num_ftrs=32

However, one could easily switch between different default settings and even write custom config files

# this will use the default settings from resnet-34.yaml
lightly-train input_dir=my-dir model=resnet-34 
# this will use the settings in the custom config file
lightly-train input_dir=my-dir model=my-model

Implement BYOL

As proposed by user u/extracoffeeplease on Reddit.

Add an implementation of the BYOL framework.

Make output folder optional and easier to find

Problem

When I use the CLI lightly it always creates a new output folder with a timestamp. This is good to make experiments reproducible. However, for some CLI commands such as lightly-upload or lightly-download creating folders seems not adding any value.
Furthermore, I would rename the folder to something more descriptive than just outputs.

Suggestion

  • Make lightly-upload and lightly-download not create new output folders by default.
  • Rename outputs to lightly_outputs or similar to make it clear which folders have been created by the lightly CLI.

remove checkpointing from embedding module

With the current setup the embedding module SelfSupervisedEmbedding automatically creates checkpoints when trained. This also causes problems if checkpoints already exist, basically making it hard to use on its own. I would propose to remove the checkpoint_callback code

self.init_checkpoint_callback()

from the embedding module.

I think that should be a rather small change but it could help with usability.

Tests: add tests to currently untested functions

Following larger function are currently untested:

  • data/_utils.py: check_images() WARNING: This function is never used, should it be deleted?
  • cli/download_cli.py: _download_cli(), download_cli()
  • cli/upload_cli.py: _upload_cli(), upload_cli()
  • core.py: train_embedding_model(), embed_images()

General thoughts:

  • We should have a consistent way of testing the CLI.
  • We should have a consistent way of mocking the server part. E.g. we could create a mock server: https://github.com/stoplightio/prism

Add SwAV loss

Let's add the loss from SwAV to the package such that it can be used with and without a memory bank.

We'll put it in a separate file at lightly/loss/swav.py.

Following closely our implementation of the NTXentropy loss, the backbone should look like this:

class SwAVLoss(MemoryBankModule):

    def __init__(self, 
                      # whatever arguments we need
                      memory_bank_size: int = 3000):

        super(SwAVLoss, self).__init__(size=memory_bank_size)
        ...

    def forward(self, output: torch.Tensor, labels: torch.Tensor = None):
        
        output, negatives = super(SwAVLoss, self).forward(output)
        if negatives is None:
            # calculate loss from batch only
            ...
        else:
            # calculate loss from batch and negatives
            ...

        return loss

Upload stops when PC sleeps for too long (~1min)

When uploading images my PC went sleeping for about a minute. After waking up, the upload stopped with following error:
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='storage.googleapis.com', port=443): Max retries exceeded with url: /boris-platform-dev/google-oauth2%7C108619227381715356556/5ff6ff536580b3000accacaf/training/training/n7/n7039.jpg?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=boris-platform-dev%40boris-250909.iam.gserviceaccount.com%2F20210107%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20210107T125248Z&X-Goog-Expires=3601&X-Goog-SignedHeaders=host&X-Goog-Signature=228f3730fa7f8e31d8540e0a0261d61b8232220a416e663f7f3bb556f253b19f258edeb32a00e482b78a901e4f2f97d5448ba643e00daffdec08f7fb815c93eb1335d556b7074d13974a21ba221224f656db3bed34506607f3e0b69b5e8c21ef71cefe79510d30ab5be186f9d98bd7fb9ffaec7bcce5c1014b8d6aaf096671cc196c35ccc0e2dbc7f34554a01fc778166f958a3552f52162c122f532b4e2857a6bf63f63ad8dc5c58acab304465fa86631ee3395dbcba17df617d99d21f183b950bc6f77741510d0437f9b31c188132c52fc72b8f782ed31f956ddd73ebeaf41d64f55aace58952e75d0067d83ebd5d76e84a1445db846f874ff512b7b970193 (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x15780a400>: Failed to establish a new connection: [Errno 51] Network is unreachable'))

Refactor models

The SimCLR and MoCo architectures are currently implemented as standalone architectures.
Before adding new architectures like BYOL or SimSiam we should probably make use of the existing code, e.g.

  • Divide architectures into more general frameworks (in our case: with momentum updates vs. without momentum updates).
  • Have SimCLR, MoCo, BYOL, SimSiam, etc inherit from the respective generalized architectures.

Can't install and use lightly on Google Colab

When trying to use lightly I get the following error:
image

Steps to reproduce

  1. Create a new Google Colab
  2. Install lightly using !pip install lightly
  3. Import lightly using import lightly

Bundling Experiment Params

To reduce constructor clutter and to allow for easy logging / experiment design, I believe that we should allow common hyper-parameters to be bundled and to make assertions about these parameters in one place.

There are two options: one a top-level params API that bundles one object to be passed to the data-loader and the model. The other, two objects- data params and model params.

I am biased to the former specifically for the framework-wide approach of self-supervision, there is a deep interconnection between data, data transformations, and models - perhaps a bit of which is present with all of deep learning- but I believe this paradigm in particular forces thinking of all of this as very interconnected.

This also forces the good practice of researchers thinking up-front about their entire experimental design, a kind of literate experimental design. With rich logging and enforcing invariants and adding defaults it could also be very beginner friendly.

Requirements

  1. params API that returns params object that bundles data and model parameters and is implementation agnostic (available parameters checked at instantiation time of models/data loader)
  2. rich logging
  3. informed defaults (many of these will span across models but can also add validations that are methods with model names to ensue everything is available "in advance" for using specific models and logging if default is set)
  4. All of this should have a "Builder" design pattern for expressive instantiation

Move image transforms from collate function to the dataset

Currently, the collate function converts each image into a pair of transformed images before concatenating them to a batch. This has led to a lot of confusion. Ideally, the transform could be passed to the LightlyDataset constructor.

This would also have an impact on #68. Furthermore, a LightlyDataset should have a train and inference mode to switch between augmentations for contrastive learning and for infering image representations.

Collate functions can't handle tuple for input image size

The current implementation of collate functions fails when we use a tuple for the desired input image size.

#this works
collate_fn = lightly.data.ImageCollateFunction(
    input_size=32
)

# this breaks
collate_fn = lightly.data.ImageCollateFunction(
    input_size=(32, 32),
)

image

Be more clear about the models and mention the difference in implementation compared to the papers

For SimCLR and MoCo there are two versions. Our implementations are more close to v2 of both from what I've seen. But I'm not sure we use all the changes from the papers. I think it makes sense to clarify which model lightly is using and if there is a difference to the paper we should mention this. Maybe also mention how one could use SimCLRv1 or SimCLRv2 by changing some of the parameters?

data augmentation

support for data augmentation pipelines, optimally data augmentation pipelines that support higher-level optimization like policy search or HPO

data augmentation would have its own abstraction but be bound to a pipeline abstraction and then pipelines would be passed to collate for dual-augmentation of batches specific to many self-supervision tasks, collation could be associated more with descriptive methods for how much divergence is introduced (via randomness) for each of the two "paths".

This would allow researchers to use strategies such as curriculum/active learning with augmentation diverging as the consistency loss reduced (for example)

Update PIP API to follow mapping from filenames to ids

As described in https://github.com/lightly-ai/lightly-core/issues/123, the pip package needs a mapping from the following four representations of the samples belonging to a tag:

  1. bitmask: str / List[bit], length: #NoSamplesInDataset
  2. sample_indexes: List[int], length: #NoSamplesInTag
  3. filenames: List[str], length: #NoSamplesInTag
  4. sampleIDs: List[MongoObjectID] / List[str], length: #NoSamplesInTag

The mapping can be done using the following two lists downloaded from the API:

  • A) all_filenames: List[str], length: #NoSamplesInDataset
  • B) all_ sampleIDs: List[MongoObjectID] / List[str], length: #NoSamplesInDataset

Following mapping functions are needed:

  • from 1. to 2.: implemented in the bitmask class

  • from 2. to 3. by simple indexing, using A)

  • from 2. to 4. by simple indexing, using B)

  • from 4. to 2. by reverse indexing using A)

  • from 4. to 3. by reverse indexing using B)

  • from 2. to 1.: implemented in the bitmask class

Furthermore, the following workflows have to be updated to use these mappings:

  • Upload of embeddings: order them by the order in the initial tag
  • Creating a new tag from a custom selected subset (e.g. defined by filenames)

Tutorial: How to use custom augmentations

Tutorial: How to use custom augmentations

Description

We want to add a tutorial which highlights how a user can use custom augmentations to do self-supervised learning with lightly.

Tasks

  • Find a suitable dataset
  • Write the code for the tutorial
  • Write the text surrounding the code blocks
  • Add cool plots

Acceptance Criteria

  • Code works and results look meaningful

Allow download of full dataset using CLI

At the moment, our CLI only supports two ways of downloading datasets:

  1. We only download the filenames and manually take care of copying the right samples
  2. We download the filenames and automatically copy samples from a source folder to a destination folder.

However, it would be nice to download the full dataset (original images) if they are available from the platform to a destination folder.

Test coverage CI

Use CI to track the test coverage

Tasks:

  • choose a test coverage tool: Codecov
  • run the tool in Github CI
  • report the coverage with every PR
  • show the coverage as badge

Update ResNet to have optional `num_classes`

Currently, the ResNet implementation always adds a classification head but for almost all of the self supervised approaches, you only care about the actual backbone (and so you strip away this linear layer).

I'd propose to make the num_classes argument optional, and if None, omit the final linear layer so you only get the actual backbone. I can open a pull request for this if you're open to this.

Also, It looks like the library's implementation is not totally consistent with the default PyTorch ones (some missing max pools, different kernel sizes). I think a lot of people are likely to use the default PyTorch models for a lot of things, which would make the ResNets trained using Lightly incompatible. Would there be an interest in switching to the default PyTorch implementations?

Add: API for sampling

It should be possible to request a sampling from our API using the package directly (no need to go through the web-app).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.