byol-pytorch

repository·master·Indexed 23 days ago

https://github.com/lucidrains/byol-pytorch

A PyTorch implementation of Bootstrap Your Own Latent (BYOL), a self-supervised learning method that achieves state-of-the-art results without needing contrastive learning or negative pairs. The library provides a BYOL wrapper for image-based neural networks, support for the SimSiam variant via the use_momentum parameter, and a BYOLTrainer class integrated with Hugging Face accelerate for distributed training. It also includes support for Simplicial Embeddings (SEM) in the projector.

Tokens
3.5K
Snippets
8
Records
20
Agent score
82%

What's inside byol-pytorch

  1. Switch from BYOL to SimSiam training

    master

    To implement the SimSiam variant, set use_momentum = False in the BYOL constructor. This removes the need for an exponential moving average target encoder. When using this mode, you do not need to call learner.update_moving_average() during the training loop.

    import torch
    from byol_pytorch import BYOL
    from torchvision import models
    
    resnet = models.resnet50(pretrained=True)
    
    learner = BYOL(
        resnet,
        image_size = 256,
        hidden_layer = 'avgpool',
        use_momentum = False       # turn off momentum in the target encoder
    )
    
    opt = torch.optim.Adam(learner.parameters(), lr=3e-4)
    
    def sample_unlabelled_images():
        return torch.randn(20, 3, 256, 256)
    
    for _ in range(100):
        images = sample_unlabelled_images()
        loss = learner(images)
        opt.zero_grad()
        loss.backward()
        opt.step()
    
    # save your improved network
    torch.save(resnet.state_dict(), './improved-net.pt')
  2. Use the BYOL wrapper for self-supervised training

    master

    The BYOL class wraps an existing image-based neural network to enable self-supervised learning. You must specify the image_size and the hidden_layer (the name or index of the layer whose output serves as the latent representation).

    During training, you must manually call learner.update_moving_average() after each optimizer step to update the target encoder's moving average.

    import torch
    from byol_pytorch import BYOL
    from torchvision import models
    
    resnet = models.resnet50(pretrained=True)
    
    learner = BYOL(
        resnet,
        image_size = 256,
        hidden_layer = 'avgpool'
    )
    
    opt = torch.optim.Adam(learner.parameters(), lr=3e-4)
    
    def sample_unlabelled_images():
        return torch.randn(20, 3, 256, 256)
    
    for _ in range(100):
        images = sample_unlabelled_images()
        loss = learner(images)
        opt.zero_grad()
        loss.backward()
        opt.step()
        learner.update_moving_average() # update moving average of target encoder
    
    # save your improved network
    torch.save(resnet.state_dict(), './improved-net.pt')
  3. Perform distributed training with BYOLTrainer

    master

    For distributed training, use the BYOLTrainer class integrated with Hugging Face accelerate.

    1. Configure your environment using accelerate config.
    2. Initialize BYOLTrainer with your model, a Dataset, and training parameters like learning_rate, num_train_steps, batch_size, and checkpoint_every.
    3. Launch your training script using accelerate launch <script.py>.
    # 1. Setup configuration
    $ accelerate config
    # 2. Craft training script (e.g., ./train.py)
    from torchvision import models
    from byol_pytorch import (
        BYOL,
        BYOLTrainer,
        MockDataset
    )
    
    resnet = models.resnet50(pretrained = True)
    
    dataset = MockDataset(256, 10000)
    
    trainer = BYOLTrainer(
        resnet,
        dataset = dataset,
        image_size = 256,
        hidden_layer = 'avgpool',
        learning_rate = 3e-4,
        num_train_steps = 100_000,
        batch_size = 16,
        checkpoint_every = 1000     # improved model will be saved periodically to ./checkpoints folder
    )
    
    trainer()
    # 3. Launch training
    $ accelerate launch ./train.py
  4. How BYOL and SimSiam differ in this implementation

    master

    The implementation allows switching between BYOL and SimSiam by toggling the use_momentum parameter in the BYOL constructor:

    1. BYOL (use_momentum=True): Uses a target_encoder that is a momentum-updated (EMA) copy of the online_encoder. The loss is calculated between the online_predictor output and the target_encoder projection.
    2. SimSiam (use_momentum=False): The target_encoder is replaced by the online_encoder itself. The online_predictor uses a SimSiamMLP architecture instead of a standard MLP.
  5. Configure BYOL hyperparameters and augmentations

    master

    You can customize the BYOL training process using several keyword arguments:

    • projection_size: The size of the projection.
    • projection_hidden_size: The hidden dimension of the MLP for both the projection and prediction.
    • moving_average_decay: The moving average decay factor for the target encoder.
    • augment_fn: A custom augmentation function for the first view.
    • augment_fn2: A custom augmentation function for the second view (useful for applying different probabilities of effects like Gaussian blur).

    Example of custom hyperparameter and augmentation configuration:

    # Custom hyperparameters
    learner = BYOL(
        resnet,
        image_size = 256,
        hidden_layer = 'avgpool',
        projection_size = 256,
        projection_hidden_size = 4096,
        moving_average_decay = 0.99
    )
    
    # Custom augmentations
    augment_fn = nn.Sequential(
        kornia.augmentation.RandomHorizontalFlip()
    )
    
    augment_fn2 = nn.Sequential(
        kornia.augmentation.RandomHorizontalFlip(),
        kornia.filters.GaussianBlur2d((3, 3), (1.5, 1.5))
    )
    
    learner = BYOL(
        resnet,
        image_size = 256,
        hidden_layer = -2,
        augment_fn = augment_fn,
        augment_fn2 = augment_fn2,
    )
  6. Extract embeddings or projections from BYOL

    master

    To retrieve the latent representations (embeddings) or the projected representations from the learner, pass return_embedding = True when calling the learner instance. It will return a tuple of (projection, embedding).

    import torch
    from byol_pytorch import BYOL
    from torchvision import models
    
    resnet = models.resnet50(pretrained=True)
    
    learner = BYOL(
        resnet,
        image_size = 256,
        hidden_layer = 'avgpool'
    )
    
    imgs = torch.randn(2, 3, 256, 256)
    projection, embedding = learner(imgs, return_embedding = True)
  7. Configure BYOLTrainer parameters

    master

    The BYOLTrainer constructor accepts several configuration options:

    ParameterTypeDescription
    nettorch.nn.ModuleThe base neural network to be trained.
    image_sizeintThe resolution of input images.
    hidden_layerstrThe dimension of the latent space.
    learning_ratefloatLearning rate for the optimizer.
    datasettorch.utils.data.DatasetThe dataset used for training.
    num_train_stepsintTotal number of training iterations.
    batch_sizeint (default: 16)Size of each training batch.
    optimizer_klasstype (default: Adam)The optimizer class to use.
    checkpoint_everyint (default: 1000)Number of steps between saving checkpoints.
    checkpoint_folderstr (default: './checkpoints')Directory where checkpoints are saved.
    byol_kwargsdict (default: {})Keyword arguments passed to the BYOL module.
    optimizer_kwargsdict (default: {})Keyword arguments passed to the optimizer.
    accelerator_kwargsdict (default: {})Keyword arguments passed to the Accelerator.
  8. Configure Simplicial Embeddings (SEM) in the projector

    master

    When use_simplicial_embeddings=True, the projector is augmented with a Simplicial Embedding layer. This layer transforms the representation into a set of simplicial embeddings before passing it to the MLP projector.

    Parameters for SEM:

    • sem_num_simplices: The number of simplices (default: 32).
    • sem_simplex_dim: The dimension of each simplex (default: 8).
    • sem_temperature: Temperature for the softmax in the SEM layer (default: 0.1).

    Note: The input dimension to the projector will be sem_num_simplices * sem_simplex_dim if SEM is enabled.