This is not a fork of somebody else's code. I, @BobMcDear, am the original creator of this project but due to problems with Git was forced to delete and restore it. In other words, gary109/PyTorch-SimSiam is a fork of this repository and not vice versa.
This is an implementation of the self-supervised learning algorithm SimSiam in PyTorch.
Many methods useful for SimSiam are included, and for end-to-end training, all you must provide is an encoder for the SimSiam model plus an optimizer.
Methods:
-
data.py
create_simsiam_transforms
: Returns aCompose
object consisting of SimSiam's transforms and optionally normalization- Args:
size
(int
): Desired image size. Default is224
normalize
(bool
): Whether to normalize with ImageNet's stats. Default isTrue
- Args:
SimSiamDataset
: Dataset for SimSiam that returns two augmented views per image with transforms fromcreate_simsiam_transforms
- Args:
path
(str
): Path to images. Default isimages/
valid_exts
(List[str]
): Valid extensions for images. Default is['jpeg', 'jpg']
size
(int
): Desired image size. Default is224
normalize
(bool
): Whether to normalize with ImageNet's stats. Default isTrue
- Args:
create_simsiam_dataloader
: WrapsSimSiamDataset
inside aDataLoader
- Args:
path
(str
): Path to images. Default isimages/
valid_exts
(List[str]
): Valid extensions for images. Default is['jpeg', 'jpg']
size
(int
): Desired image size. Default is224
normalize
(bool
): Whether to normalize with ImageNet's stats. Default isTrue
batch_size
(int
): Batch size. Default is32
num_workers
(int
): Number of workers. Default is8
- Args:
-
loss.py
:NegativeCosineSimilarity
: Negative cosine similaritySymmetrizedNegativeCosineSimilarity
: Symmetrized negative cosine similarity loss from the SimSiam paper
-
model.py
:-
get_encoder_out_dim
: Returns the number of output channels of an encoder- Args:
encoder
(Module
): Encoder
- Args:
-
LinBnReLU
: Linear layer followed optionally by batch normalization and ReLU- Args:
in_dim
(int
): Number of input featuresout_dim
(int
): Number of output featuresbn
(bool
): Whether to have batch normalization. Default isTrue
relu
(bool
): Whether to have ReLU. Default isTrue
- Args:
-
SimSiamModel
: SimSiam model that uses a provided encoder and returns thez
andp
vectors- Args:
encoder
(Module
): Encoderout_dim
(int
): Number of output features for projection and prediction heads. Default is2048
prediction_head_hidden_dim
(int
): Number of hidden features of prediction head. Default is512
- Args:
-
-
train.py
-
get_normalized_std
: Normalizesz
on a per-row basis, gets the standard deviation of the result on a per-row basis, and returns the average of all rows- Args:
z
(Tensor
):Tensor
- Args:
-
do_training_epoch
: Does one training epoch for a SimSiam model with a providedDataLoader
and returns the loss and the mean normalized standard deviation of projectedz
s (the latter is useful for monitoring model collapse)- Args:
dataloader
(DataLoader
):DataLoader
for trainingmodel
(Module
): SimSiam modelloss_func
(SymmetrizedNegativeCosineSimilarity
):SymmetrizedNegativeCosineSimilarity
objectoptimizer
(Optimizer
):Optimizer
for optimization
- Args:
-
do_validation
: Validates a SimSiam model with a providedDataLoader
and returns the loss and the mean normalized standard deviation of projectedz
s (the latter is useful for monitoring model collapse)- Args:
dataloader
(DataLoader
):DataLoader
for validationmodel
(Module
): SimSiam modelloss_func
(SymmetrizedNegativeCosineSimilarity
):SymmetrizedNegativeCosineSimilarity
object
- Args:
-
train
: Trains and validates a SimSiam model and prints loss and standard deviations- Args:
train_dataloader
(DataLoader
):DataLoader
for trainingvalid_dataloader
(DataLoader
):DataLoader
for validationmodel
(Module
): SimSiam modeloptimizer
(Optimizer
):Optimizer
for optimizationn_epochs
(int
): Number of epochs. Default is10
- Args:
-
The code below trains a ResNet-50 with SimSiam.
from torch.nn import Identity
from torch.optim import Adam
from torchvision.models import resnet50
from data import create_simsiam_dataloader
from model import SimSiamModel
from train import train
# The encoder can be any model that returns a feature vector
encoder = resnet50()
encoder.fc = Identity()
model = SimSiamModel(encoder=encoder,
out_dim=2048,
prediction_head_hidden_dim=512)
optimizer = Adam(params=model.parameters(),
lr=4e-4)
train_dataloader = create_simsiam_dataloader(path='train/',
valid_exts=['jpeg', 'jpg'],
size=224,
normalize=True,
batch_size=32,
num_workers=8)
valid_dataloader = create_simsiam_dataloader(path='valid/',
valid_exts=['jpeg', 'jpg'],
size=224,
normalize=True,
batch_size=32,
num_workers=8)
train(train_dataloader=train_dataloader,
valid_dataloader=valid_dataloader,
model=model,
optimizer=optimizer,
n_epochs=100)