Lightly
Lightly is a Python library and computer vision framework for self-supervised learning, built on top of PyTorch and PyTorch Lightning. It enables training deep learning models without manual data labels, focusing on understanding and filtering raw image data for efficient active learning and data curation pipelines. The current version is 1.5.23, and it maintains an active development and release cadence.
Common errors
-
ModuleNotFoundError: No module named 'lightly.models.resnet'
cause Attempting to import a model from an incorrect or deprecated path. Lightly's models are often organized into submodules like `self_supervised` or use `torchvision` backbones.fixCheck the official documentation for the correct import path for the specific model. For self-supervised models, they are typically in `lightly.models.self_supervised`. For standard backbones, use `torchvision.models` and pass them to Lightly's model wrappers. -
RuntimeError: Expected all tensors to be on the same device, but found tensors on both cpu and cuda:0
cause A common PyTorch error indicating that some tensors are on the CPU while others are on the GPU, preventing operations between them. This often happens if a model or data is not explicitly moved to the correct device.fixEnsure both your model and your input data are on the same device. For example, after defining `model = MoCo(...)`, move it to GPU with `model.to(device)` (where `device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')`). Similarly, move input tensors `x0.to(device), x1.to(device)` within your training loop. -
TypeError: 'NoneType' object is not callable
cause This usually indicates that a variable you are trying to call as a function or method (e.g., `model(...)`) was assigned `None` because its initialization failed or returned `None`.fixReview the initialization of your `lightly` model, loss function, or transforms. Ensure all required arguments are provided and that no step in their construction inadvertently results in a `None` value being assigned where an object is expected. For example, if a `LightlyDataset` or `collate_fn` cannot find data, it might behave unexpectedly.
Warnings
- breaking Lightly adheres to Semantic Versioning. Major version bumps (e.g., from 1.x to 2.x) indicate breaking changes, which may require code modifications during upgrades. Always review the release notes before upgrading major versions.
- gotcha Python 3.13 is not yet officially supported by Lightly, as its core dependency PyTorch currently lacks compatibility with Python 3.13. Users should stick to Python versions 3.7 through 3.12.
- gotcha Lightly has specific minimum version requirements for its core dependencies (PyTorch, Torchvision, PyTorch Lightning) to ensure all features work correctly. Older versions of these dependencies might lead to unexpected behavior or feature unavailability.
Install
-
pip install lightly
Imports
- lightly
import lightly
- LightlyDataset
from lightly.data.datasets import LightlyDataset
from lightly.data import LightlyDataset
- MoCo
from lightly.models import MoCo
from lightly.models.self_supervised import MoCo
- MoCoLoss
from lightly.loss import MoCoLoss
Quickstart
import torch
import pytorch_lightning as pl
from lightly.data import LightlyDataset, collate
from lightly.loss import MoCoLoss
from lightly.models.self_supervised import MoCo
from lightly.transforms.byol_transform import BYOLTransform
# 1. Define the input dataset
# Using a dummy dataset path for demonstration; replace with your actual image directory
# For real use, ensure 'path_to_your_dataset' contains images
dataset = LightlyDataset(input_dir="./path_to_your_dataset")
# 2. Define the data augmentations and collate function
transform = BYOLTransform(input_size=32)
collate_fn = collate(transform)
# 3. Create the PyTorch DataLoader
dataloader = torch.utils.data.DataLoader(
dataset,
batch_size=256,
collate_fn=collate_fn,
shuffle=True,
drop_last=True,
num_workers=4,
)
# 4. Define the self-supervised model
model = MoCo(memory_bank_size=4096)
# 5. Define the loss function
criterion = MoCoLoss()
# 6. Define the Lightning Module for training
class MoCoLightningModule(pl.LightningModule):
def __init__(self, model, criterion):
super().__init__()
self.model = model
self.criterion = criterion
def training_step(self, batch, batch_idx):
(x0, x1), _, _ = batch
y0, y1 = self.model(x0, x1)
loss = self.criterion(y0, y1)
self.log("train_loss_ssl", loss)
return loss
def configure_optimizers(self):
optimizer = torch.optim.SGD(self.model.parameters(), lr=0.06)
return optimizer
# 7. Train the model
# Ensure you have a GPU available or set accelerator='cpu'
lightning_model = MoCoLightningModule(model, criterion)
trainer = pl.Trainer(max_epochs=1, accelerator="auto", devices=1)
print("Starting Lightly self-supervised training...")
# Create a dummy folder if it doesn't exist to avoid errors for the quickstart
import os
if not os.path.exists("./path_to_your_dataset"):
os.makedirs("./path_to_your_dataset")
# Optionally, create a dummy image to make it runnable without user data
from PIL import Image
Image.new('RGB', (32, 32), color = 'red').save('./path_to_your_dataset/dummy_image.png')
trainer.fit(lightning_model, dataloader)
print("Training finished. Check the logs for 'train_loss_ssl'.")