Implementation of the Barlow Twins Loss from Barlow Twins[0] paper.
This code specifically implements the Figure Algorithm 1 from [0].
[0] Zbontar,J. et.al, 2021, Barlow Twins… https://arxiv.org/abs/2103.03230
Examples
>>> # initialize loss function>>> loss_fn=BarlowTwinsLoss()>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through SimSiam model>>> out0,out1=model(t0,t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)
Implementation of the Decoupled Contrastive Learning Loss from Decoupled Contrastive Learning [0].
This code implements Equation 6 in [0], including the sum over all images i
and views k. The loss is reduced to a mean loss over the mini-batch.
The implementation was inspired by [1].
Weighting function w from the paper. Scales the loss between the
positive views (views from the same image). No weighting is performed
if weight_fn is None. The function must take the two input tensors
passed to the forward call as input and return a weight tensor. The
returned weight tensor must have the same length as the input tensors.
If True, negatives from all GPUs are gathered before the
loss calculation.
Examples
>>> loss_fn=DCLLoss(temperature=0.07)>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # embed images using some model, for example SimCLR>>> out0=model(t0)>>> out1=model(t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)>>>>>> # you can also add a custom weighting function>>> weight_fn=lambdaout0,out1:torch.sum((out0-out1)**2,dim=1)>>> loss_fn=DCLLoss(weight_fn=weight_fn)
Implementation of the Weighted Decoupled Contrastive Learning Loss from
Decoupled Contrastive Learning [0].
This code implements Equation 6 in [0] with a negative Mises-Fisher
weighting function. The loss returns the mean over all images i and
views k in the mini-batch. The implementation was inspired by [1].
If True, negatives from all GPUs are gathered before the
loss calculation.
Examples
>>> loss_fn=DCLWLoss(temperature=0.07)>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # embed images using some model, for example SimCLR>>> out0=model(t0)>>> out1=model(t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)
Two latent representations of the same batch under different views, as generated by BYOL’s [1] prediction branch and additional pooling over the regions of the segmentation.
Two latent representations of the same batch under different views, as generated by BYOL’s target branch and additional pooling over the regions of the segmentation.
Two integer masks that indicate the regions of the segmentation that were used for pooling.
For calculating the contrastive loss, regions under the same mask in the same image
(under a different view) are considered as positives and everything else as
negatives. With \(v_m\) and \(v_{m'}'\) being the pooled feature maps under
mask \(m\) and \(m'\) respectively, and additionally scaled to a norm of
\(\frac{1}{\sqrt{\tau}}\), the formula for the contrastive loss is
where \(\mathbb{1}_{m, m'}\) is 1 if the masks are the same and 0 otherwise.
Since \(v_m\) and \(v_{m'}'\) stem from different branches, the loss is
symmetrized by also calculating the loss with the roles of the views reversed. [1]
Calculate the contrastive loss under the same mask in the same image.
The tensor shapes and value ranges are given by variables \(B, M, D, N\),
where \(B\) is the batch size, \(M\) is the sampled number of image
masks / regions, \(D\) is the embedding size and \(N\) is the total
number of masks.
Parameters:
pred_view0 – Mask-pooled output of the prediction branch for the first view,
a float tensor of shape \((B, M, D)\).
pred_view1 – Mask-pooled output of the prediction branch for the second view,
a float tensor of shape \((B, M, D)\).
target_view0 – Mask-pooled output of the target branch for the first view,
a float tensor of shape \((B, M, D)\).
target_view1 – Mask-pooled output of the target branch for the second view,
a float tensor of shape \((B, M, D)\).
mask_view0 – Indices corresponding to the sampled masks for the first view,
an integer tensor of shape \((B, M)\) with (possibly repeated)
indices in the range \([0, N)\).
mask_view1 – Indices corresponding to the sampled masks for the second view,
an integer tensor of shape (B, M) with (possibly repeated) indices in
the range \([0, N)\).
Returns:
A scalar float tensor containing the contrastive loss.
Two latent representations of the same batch under different views, as generated by SimCLR [3] and additional pooling over the regions of the segmentation.
Two integer masks that indicate the regions of the segmentation that were used for pooling.
For calculating the contrastive loss, regions under the same mask in the same image
(under a different view) are considered as positives and everything else as
negatives. With \(v_m\) and \(v_{m'}'\) being the pooled feature maps under
mask \(m\) and \(m'\) respectively, and additionally scaled to a norm of
\(\frac{1}{\sqrt{\tau}}\), the formula for the contrastive loss is
Calculate the contrastive loss under the same mask in the same image.
The tensor shapes and value ranges are given by variables \(B, M, D, N\),
where \(B\) is the batch size, \(M\) is the sampled number of image
masks / regions, \(D\) is the embedding size and \(N\) is the total
number of masks.
Parameters:
view0 – Mask-pooled output for the first view, a float tensor of shape
\((B, M, D)\).
view1 – Mask-pooled output for the second view, a float tensor of shape
\((B, M, D)\).
mask_view0 – Indices corresponding to the sampled masks for the first view,
an integer tensor of shape \((B, M)\) with (possibly repeated)
indices in the range \([0, N)\).
mask_view1 – Indices corresponding to the sampled masks for the second view,
an integer tensor of shape (B, M) with (possibly repeated) indices in
the range \([0, N)\).
Returns:
A scalar float tensor containing the contrastive loss.
Implementation of the loss described in ‘Emerging Properties in
Self-Supervised Vision Transformers’. [0]
This implementation follows the code published by the authors. [1]
It supports global and local image crops. A linear warmup schedule for the
teacher temperature is implemented to stabilize training at the beginning.
Centering is applied to the teacher output to avoid model collapse.
A linear schedule for the teacher temperature during the warmup phase (for backward compatibility).
Examples
>>> # initialize loss function>>> loss_fn=DINOLoss(128)>>>>>> # generate two views of the images with a random transform>>> view0,view1=transform(images),transform(images)>>>>>> # embed the views with a student and teacher model>>> teacher_out=[teacher(view0),teacher(view1)]>>> student_out=[student(view0),student(view1)]>>>>>> # calculate loss>>> loss=loss_fn(teacher_out,student_out)
Cross-entropy between softmax outputs of the teacher and student networks.
Parameters:
teacher_out – List of tensors with shape (batch_size, output_dim) containing features
from the teacher model. Each tensor must represent one view of the
batch.
student_out – List of tensors with shape (batch_size, output_dim) containing features
from the student model. Each tensor must represent one view of the
batch.
teacher_temp – The temperature used for the teacher output. If None, the default
temperature defined in __init__ is used.
epoch – The current epoch for backward compatibility.
FroSSL is a self-supervised objective that combines a variance/redundancy
regularization term with an invariance term. For every view it maximizes the
entropy of the (trace-normalized) covariance matrix through its squared
Frobenius norm, while an invariance term pulls the views towards their mean.
The loss supports any number of views V>=2.
[0] FroSSL: Frobenius Norm Minimization for Self-Supervised Learning, 2024,
Scaling coefficient for the invariance term of the loss.
Examples
>>> # initialize loss function>>> loss_fn=FroSSLLoss()>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through model>>> z0=model(t0)>>> z1=model(t1)>>>>>> # calculate loss>>> loss=loss_fn([z0,z1])
In order for this loss to function as advertised, an L1-normalization to the hypersphere is required.
This loss function applies this L1-normalization internally in the loss layer.
However, it is recommended that the same normalization is also applied in your architecture,
considering that this L1-loss is also intended to be applied during inference.
Perhaps there may be merit in leaving it out of the inference pathway, but this use has not been tested.
Moreover it is recommended that the layers preceding this loss function are either a linear layer without activation,
a batch-normalization layer, or both. The directly upstream architecture can have a large influence
on the ability of this loss to achieve its stated aim of promoting uniformity on the hypersphere;
and if by contrast the last layer going into the embedding is a RELU or similar nonlinearity,
we may see that we will never get very close to achieving the goal of uniformity on the hypersphere,
but will confine ourselves to the subspace of positive activations.
Similar architectural considerations are relevant to most contrastive loss functions,
but we call it out here explicitly.
Examples
>>> # initialize loss function>>> loss_fn=HypersphereLoss()>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through SimSiam model>>> out0,out1=model(t0,t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)
teacher_out – Tensor with shape (batch_size * sequence_length, embed_dim) containing
the teacher output of the masked tokens.
student_out – Tensor with shape (batch_size * sequence_length, embed_dim) containing
the student output of the masked tokens.
mask – Boolean tensor with shape (batch_size, height, width) containing the
token mask. Exactly batch_size * sequence_length entries must be set to
True in the mask.
teacher_temp – The temperature used for the teacher output. If None, the default
temperature defined in __init__ is used.
Implementation of the iBOT++ patch loss from TIPSv2.
iBOT++ extends the iBOT masked patch loss by applying patch-level
self-distillation to all patch tokens, including visible tokens. This is
useful for dense downstream tasks because all patch features are directly
anchored to the teacher distribution.
The loss expects full teacher and student patch logits with shape
(B,N,K) where B is the batch size, N is the number of patch
tokens, and K is the number of prototypes. Inputs with shape
(B*N,K) are also supported when mask is provided to infer the
batch size.
When mask is provided, the per-token cross-entropy is split into a
masked term and a visible term. The masked term is normalized by the
number of masked tokens per image (matching the original iBOT masked
image modeling signal), and the visible term is normalized by the number
of visible tokens per image and scaled by visible_loss_weight:
Setting visible_loss_weight=0 recovers the exact iBOT behavior, while
visible_loss_weight>0 adds the iBOT++ supervision on visible tokens
without diluting the masked-token signal. When mask is None the
loss falls back to a plain mean over all patch tokens.
Parameters:
teacher_out – Tensor with shape (B,N,K) or (B*N,K) containing
full patch logits from the teacher model.
student_out – Tensor with the same shape as teacher_out containing full
patch logits from the student model.
mask – Optional boolean tensor with shape (B,H,W) or (B,N)
where True marks masked tokens. Used to weight masked vs.
visible tokens, and required when teacher_out has rank 2 so
that the batch size B can be inferred.
teacher_temp – The temperature used for the teacher output. If None, the default
temperature defined in __init__ is used.
visible_loss_weight – Weight applied to the visible-token (unmasked) loss term. Only
used when mask is provided. Defaults to 1.0. Use 0.0
to recover the original iBOT masked-only behavior.
Returns:
The loss value as a scalar tensor.
Raises:
ValueError – If teacher_out and student_out shapes differ, if the
input rank is not 2 or 3, if rank-2 inputs are given without a
mask, or if the mask shape is incompatible with the input.
Sketched Isotropic Gaussian Regularization for projected embeddings.
SIGReg is the LeJEPA regularizer [0] that drives the empirical
distribution of the projected embeddings toward an isotropic Gaussian.
It draws random unit projection vectors (slices) and compares the
empirical characteristic function of the sliced projections against
the ideal Gaussian characteristic function via an Epps-Pulley integral
over a frequency grid.
Buffer of shape (knots,) containing the trapezoidal
integration weights pre-multiplied by phi.
Examples
>>> # initialize the regularizer>>> sigreg=SIGReg()>>>>>> # apply a transform and feed through model>>> view=transform(images)>>> proj=model(view)# shape (N, D)>>>>>> # compute the regularization loss>>> loss=sigreg(proj)
The SIGReg regularization module instantiated with the supplied
sigreg_* parameters.
Examples
>>> # initialize loss function>>> loss_fn=LeJEPALoss()>>>>>> # generate local and global views>>> local_views=[transform(images)for_inrange(n_local)]>>> global_views=[transform(images)for_inrange(n_global)]>>>>>> # project each view and stack to shape (V, N, D)>>> local_proj=torch.stack([model(v)forvinlocal_views])>>> global_proj=torch.stack([model(v)forvinglobal_views])>>>>>> # calculate loss>>> loss=loss_fn(local_proj=local_proj,global_proj=global_proj)
A next-embedding prediction loss between the predicted embeddings and
the embeddings of the observed next frames.
SIGReg, which drives the distribution
of the frame embeddings toward an isotropic Gaussian.
In LeWM, SIGReg is what keeps the encoder from collapsing, so LeWM needs no
stop-gradient, no teacher network and no exponential moving average, and
the encoder can be trained from pixels together with the predictor.
The total loss is prediction+lambda_param*SIGReg(embeddings).
Warning
LeWM is experimental. Its API may change in a minor release.
KoLeo loss is a regularizer that encourages a uniform span of the features in a
batch by penalizing the distance between the features and their nearest
neighbors.
Size of the memory bank as (num_features, dim) tuple. If num_features is 0
then the memory bank is disabled. Pass 0 to disable the memory bank; any
other bare integer is rejected because the feature dimension is required
and cannot be guessed.
If True then negatives from all gpus are gathered before the memory bank
is updated. This results in more frequent updates of the memory bank and
keeps the memory bank contents independent of the number of gpus. But it has
the drawback that synchronization between processes is required and
diversity of the memory bank content is reduced.
If True, the memory bank returns features with shape (dim, num_features).
If False, the memory bank returns features with shape (num_features, dim).
Examples
>>> classMyLossFunction(MemoryBankModule):>>>>>> def__init__(self,memory_bank_size:Tuple[int,int]=(2**16,128)):>>> super().__init__(memory_bank_size)>>>>>> defforward(self,output:Tensor,labels:Optional[Tensor]=None):>>> output,negatives=super().forward(output)>>>>>> ifnegativesisnotNone:>>> pass# evaluate loss with negative samples>>> else:>>> pass# evaluate loss without negative samples
update – If True, the memory bank will be updated with the current output.
Returns:
The output if the memory bank is of size 0, otherwise the output
and the entries from the memory bank. Entries from the memory bank have
shape (dim, num_features) if feature_dim_first is True and
(num_features, dim) otherwise.
Implementation of the loss function from MMCR [0] using Manifold Capacity.
All hyperparameters are set to the default values from the paper for ImageNet.
[0]: Efficient Coding of Natural Images using Maximum Manifold Capacity
Computes the MMCR loss for the online and momentum network outputs.
Parameters:
online – Output of the online network for the current batch. Expected to be
of shape (batch_size, k, embedding_size), where k represents the
number of randomly augmented views for each sample.
momentum – Output of the momentum network for the current batch. Expected to be
of shape (batch_size, k, embedding_size), where k represents the
number of randomly augmented views for each sample.
Implementation of the Contrastive Cross Entropy Loss.
This implementation follows the SimCLR[0] paper. If you enable the memory
bank by setting the memory_bank_size value > 0 the loss behaves like
the one described in the MoCo[1] paper.
Size of the memory bank as (num_features, dim) tuple. num_features are the
number of negative samples stored in the memory bank. If num_features is 0,
the memory bank is disabled. Use 0 for SimCLR. For MoCo we typically use
numbers like 4096 or 65536.
If True then negatives from all GPUs are gathered before the
loss calculation. If a memory bank is used and gather_distributed is True,
then tensors from all gpus are gathered before the memory bank is updated.
Raises:
ValueError – If abs(temperature) < 1e-8 to prevent divide by zero.
Examples
>>> # initialize loss function without memory bank>>> loss_fn=NTXentLoss(memory_bank_size=0)>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through SimCLR or MoCo model>>> out0,out1=model(t0),model(t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)
Forward pass through Contrastive Cross-Entropy Loss.
If used with a memory bank, the samples from the memory bank are used
as negative examples. Otherwise, within-batch samples are used as
negative samples.
Parameters:
out0 – Output projections of the first set of transformed images.
Shape: (batch_size, embedding_size)
out1 – Output projections of the second set of transformed images.
Shape: (batch_size, embedding_size)
Patch kernel alignment loss for dense self-supervised learning.
Aligns the relational structure of student and teacher dense features
rather than asking for exact patch correspondence. For each image it builds
the pairwise linear kernels of the student and teacher tokens and maximizes
their Centered Kernel Alignment (CKA):
where H=I-(1/N)11^T is the centering matrix. CKA is invariant to
isotropic scaling and orthogonal transforms of the features, so the loss
captures region grouping and object-level organization without requiring
nearest-neighbour sorting, clustering, prototypes, or geometric patch
identity. This makes it well suited to detection and segmentation.
The loss is model-agnostic: it operates on dense features (B,N,D)
where N is the number of ViT patch tokens (ConvNet features must be
flattened to (B,N,D) by the caller). Teacher features are detached
internally. Geometry/ROI alignment for a cross-view variant is the caller’s
responsibility; the loss receives already aligned dense features.
max_tokens – If not None and N>max_tokens, randomly subsample
max_tokens tokens per image (preferring valid ones) before
forming the kernel, to bound the O(BN^2D) cost.
Example (same view, e.g. iBOT-style masking):
>>> criterion=PatchKernelAlignmentLoss(max_tokens=512)>>> loss=criterion(... student_features=student_features,# (B, N, D)... teacher_features=teacher_features,# (B, N, D)... )
Example (cross view, student and teacher see different crops):
>>> fromlightly.lossimportroi_resample_to_grid>>> # Reshape patch tokens back to the (B, C, H, W) patch grid per view.>>> student_map=student_tokens.transpose(1,2).reshape(B,C,H,W)>>> teacher_map=teacher_tokens.transpose(1,2).reshape(B,C,H,W)>>> # Resample the shared region of both crops onto a common 7x7 grid so>>> # token i refers to the same location in both views.>>> student=roi_resample_to_grid(student_map,student_boxes,7,7)>>> teacher=roi_resample_to_grid(teacher_map,teacher_boxes,7,7)>>> loss=PatchKernelAlignmentLoss()(student,teacher)# (B, 49, C)
A function that takes the mean anchor probabilities tensor with shape (dim,)
as input and returns a target probability distribution tensor with the same
shape. The returned distribution should sum up to one. The final
regularization loss is calculated as KL(mean_anchor_probs, target_dist)
where KL is the Kullback-Leibler divergence.
Size of the memory bank as (num_features, dim) tuple. num_features is the
number of negatives stored in the bank. If set to 0, the memory bank is
disabled.
Examples
>>> # initialize loss function for MoCo>>> loss_fn=NTXentLoss(memory_bank_size=(4096,128))>>>>>> # initialize CO2 regularizer>>> co2=CO2Regularizer(alpha=1.0,memory_bank_size=(4096,128))>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through the MoCo model>>> out0,out1=model(t0,t1)>>>>>> # calculate loss and apply regularizer>>> loss=loss_fn(out0,out1)+co2(out0,out1)
Dense Structure Estimator regularizer for dense representations.
This experimental regularizer is based on the training regularizer variant from “Exploring
Structural Degradation in Dense Representations for Self-supervised
Learning”, 2025, https://arxiv.org/abs/2510.17299.
The regularizer expects dense representations of shape (B,N,D), where
B is the batch size, N is the number of dense locations such as
patches or spatial positions, and D is the feature dimension. Higher DSE
values indicate better dense structure, so this module returns
-weight*dse and can be added to an existing SSL loss.
Examples
>>> regularizer=DSERegularizer(weight=0.1)>>> ssl_loss=torch.tensor(1.0)>>>>>> # Transformer output: patch_tokens has shape (B, N, D).>>> patch_tokens=torch.randn(8,196,384)>>> loss=ssl_loss+regularizer(patch_tokens)>>>>>> # Convolutional output: features has shape (B, C, H, W).>>> features=torch.randn(8,384,14,14)>>> dense_features=features.flatten(2).transpose(1,2)>>> loss=ssl_loss+regularizer(dense_features)
Coefficient for the EMA update of the covariance
Defaults to 0.9 [0].
rho:
Weight for the covariance term of the loss
Defaults to 8.0 [0].
gather_distributed:
If True, the cross-correlation matrices from all GPUs are
gathered and summed before the loss calculation.
Examples
>>> # initialize loss function>>> loss_fn=TiCoLoss()>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through model>>> out0,out1=model(t0,t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)
>>> # initialize loss function>>> loss_fn=VICRegLoss()>>>>>> # generate two random transforms of images>>> t0=transforms(images)>>> t1=transforms(images)>>>>>> # feed through model>>> out0,out1=model(t0,t1)>>>>>> # calculate loss>>> loss=loss_fn(out0,out1)
Number of local features to match using nearest neighbors.
Examples
>>> # initialize loss function>>> criterion=VICRegLLoss()>>> transform=VICRegLTransform(n_global_views=2,n_local_views=4)>>>>>> # generate two random transforms of images>>> views_and_grids=transform(images)>>> views=views_and_grids[:6]# 2 global views + 4 local views>>> grids=views_and_grids[6:]>>>>>> # feed through model images>>> features=[model(view)forviewinviews]>>>>>> # calculate loss>>> loss=criterion(... global_view_features=features[:2],... global_view_grids=grids[:2],... local_view_features=features[2:],... local_view_grids=grids[2:],... )
Computes the global and local VICRegL loss from the input features.
Parameters:
global_view_features – Sequence of (global_features, local_features) tuples from the global
crop views. global_features must have size
(batch_size, global_feature_dim) and local_features must have size
(batch_size, grid_height, grid_width, local_feature_dim).
global_view_grids – Sequence of grid tensors from the global crop views. Every tensor must
have shape (batch_size, grid_height, grid_width, 2).
local_view_features – Sequence of (global_features, local_features) tuples from the local crop
views. global_features must have size
(batch_size, global_feature_dim) and local_features must have size
(batch_size, grid_height, grid_width, local_feature_dim). Note that
grid_height and grid_width can differ between global_view_features and
local_view_features.
local_view_grids – Sequence of grid tensors from the local crop views. Every tensor must
have shape (batch_size, grid_height, grid_width, 2). Note that
grid_height and grid_width can differ between global_view_features and
local_view_features.
Returns:
Weighted sum of the global and local loss, calculated as – self.alpha * global_loss + (1-self.alpha) * local_loss.
Raises:
ValueError – If the lengths of global_view_features and global_view_grids are not the same.
ValueError – If the lengths of local_view_features and local_view_grids are not the same.
ValueError – If only one of local_view_features or local_view_grids is set.
VISReg regularizes the projected embeddings with three decoupled terms:
a center loss on the batch mean, a scale loss on the per-dimension
standard deviation, and a sliced-Wasserstein shape loss that sketches
the embedding distribution toward an isotropic Gaussian. The
regularization is combined with the LeJEPA multi-view invariance loss:
total=(1-lambda_param)*pred+lambda_param*reg where
reg=lambda_scale*scale+lambda_shape*shape+lambda_center*center.
The implementation follows Algorithm 1 of the paper. The default
lambda_param=0.9 and equal component weights are the best settings
reported for large datasets such as ImageNet-1K (Tables 3 and 12 in
[0]); the paper recommends lambda_param=0.6 for small datasets and
increasing lambda_shape for long-tailed or low-rank data.
In distributed training every device draws its own random slices and
computes the loss on its local batch, so no communication is required
and the effective number of slices grows with the world size (Section
3.2 in [0]). This is the paper’s setting and the default. Note that
this requires the random number generators of the devices to be seeded
differently; identically seeded devices draw identical slices. Set
gather_distributed=True to additionally gather the embeddings from
all devices before computing the regularization statistics, which can
help when the per-device batch is very small.
Numerical stability term for the shape loss normalization.
Examples
>>> # initialize loss function>>> loss_fn=VISRegLoss()>>>>>> # generate local and global views>>> local_views=[transform(images)for_inrange(n_local)]>>> global_views=[transform(images)for_inrange(n_global)]>>>>>> # project each view and stack to shape (V, N, D)>>> local_proj=torch.stack([model(v)forvinlocal_views])>>> global_proj=torch.stack([model(v)forvinglobal_views])>>>>>> # calculate loss>>> loss=loss_fn(local_proj=local_proj,global_proj=global_proj)
Computes the VISReg loss for a batch of multi-view projections.
Parameters:
local_proj – Local-view projected embeddings of shape
(Vl,N,D) where Vl is the number of local views,
N is the batch size, and D is the projection
dimensionality.
global_proj – Global-view projected embeddings of shape
(Vg,N,D) where Vg is the number of global views.
Computes the VISReg loss and returns all components separately.
The prediction term pulls every view, global and local, toward the
centroid of the global views (Eq. 8 in the paper). The
regularization terms are computed over all views with each view’s
batch treated as an independent sample set.
Parameters:
local_proj – Local-view projected embeddings of shape
(Vl,N,D) where Vl is the number of local views,
N is the batch size, and D is the projection
dimensionality.
global_proj – Global-view projected embeddings of shape
(Vg,N,D) where Vg is the number of global views.
Returns:
A VISRegLossComponents tuple with the total loss and the
individual pred, scale, shape, and center losses.
Raises:
ValueError – If the projections have invalid shapes or a batch
size smaller than two.