Skip to content

Add VISRegLoss (VISReg paper)#1968

Merged
gabrielfruet merged 4 commits into
lightly-ai:masterfrom
saud5150:add-visreg-loss
Jul 9, 2026
Merged

Add VISRegLoss (VISReg paper)#1968
gabrielfruet merged 4 commits into
lightly-ai:masterfrom
saud5150:add-visreg-loss

Conversation

@saud5150

@saud5150 saud5150 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Related to #1960 (PR 1 of 2).

Description

  • My change is breaking

Adds lightly/loss/visreg_loss.py implementing VISReg (Wu et al., 2026) per Algorithm 1, structured like lejepa_loss.py. Covers the open points from #1960:

  1. Distributed: per-device slices, no broadcast/all_reduce (Section 3.2, avoiding [BUG] SIGReg with gather_distributed=True produces gradient which is off by 1/world_size under DDP #1920). gather_distributed=True optionally gathers embeddings for the statistics via the same autograd-aware path as VICRegLoss.
  2. Component losses: visreg_center/scale/shape_loss helpers plus forward_components() returning a (total, pred, scale, shape, center) NamedTuple (per Feature Request: Return all losses with multi-loss methods e.g., VICReg #1422). forward() returns a scalar.
  3. No new head: reuses lejepa_invariance_loss; intended for LeJEPAProjectionHead.
  4. Hyperparameters: paper's ImageNet-1K defaults (lambda_param=0.9, num_slices=4096, equal weights).

Implemented from the paper's math only (official repo is CC BY-NC). Three choices worth review: forward(*, local_proj, global_proj) rather than the issue's forward(z) sketch (the prediction term needs the global views); prediction and regularization run over all views per Eq. 8 / Section 3.1 (differs from LeJEPALoss's local-only, pinned by a test); and Algorithm 1's (N,K)-(N,) broadcasting bug is fixed with an unsqueeze.

Tests

  • My change is covered by existing tests.
  • My change needs new tests.
  • I have added/adapted the tests accordingly.
  • I have manually tested the change. if_yes_describe_how

37 tests in tests/loss/test_visreg_loss.py (patterns from test_lejepa_loss.py): shape loss pinned against a naive Algorithm 1 transcription, non-vanishing gradient under collapse, stop-gradient behavior, all-views regularization scope, no-collectives on the default distributed path, and gather matching the global-batch loss. make format, make static-checks, and make test pass (1693 passed; 4 failures are pre-existing macOS/Python-3.9 env issues, not hit by CI).

Documentation

  • I have added docstrings to all public functions/methods.
  • My change requires a change to the documentation ( .rst files).
  • I have updated the documentation accordingly.
  • The autodocs update the documentation accordingly.

VISRegLoss autoclass entry added to docs/source/lightly.loss.rst (with :special-members: __init__). PDF of the rendered page attached.

Implications / comments / further issues

Implements the variance-invariance-sketching regularization loss from
https://arxiv.org/abs/2606.02572 per Algorithm 1, with per-component
losses, per-device random slices for distributed training, and the
Eq. 8 prediction term over both global and local views. Part 1 of lightly-ai#1960.
@saud5150

saud5150 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

VISRegLoss_docs_page.pdf

@gabrielfruet

Copy link
Copy Markdown
Contributor

Thank you so much for the nice contribution!!!

@gabrielfruet

Copy link
Copy Markdown
Contributor

/review

@gabrielfruet

Copy link
Copy Markdown
Contributor

/codex review

The tensor subtraction resolves to Any with the pinned torch stubs used
in CI, tripping mypy's no-any-return. Annotate the return explicitly,
matching visreg_scale_loss.

@gabrielfruet gabrielfruet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation is looking good to me :). Very nice and clean PR. I just think it's missing the test_forward__cuda. Thank you for the nice PR!

Comment thread tests/loss/test_visreg_loss.py
Comment thread tests/loss/test_visreg_loss.py
Comment thread tests/loss/test_visreg_loss.py
@gabrielfruet

Copy link
Copy Markdown
Contributor

The test failure is not related to your changes FYI.

Other loss tests include a skip-guarded CUDA forward test; add the
matching one for VISRegLoss to verify the tensors created inside the
shape loss (slices, quantiles) land on the input's device. Addresses
review feedback on lightly-ai#1968.
@saud5150

saud5150 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for the review! Added test_forward__cuda in 03d90e3, following the other loss tests.

gabrielfruet added a commit that referenced this pull request Jul 9, 2026
… noise (#1970)

* test(models): loosen tolerance in test_singular_mask for FP noise

pool_masked uses scatter_reduce_(reduce="mean"), whose CPU summation order
differs from torch.mean by ~1e-7 in float32. With the default
torch.allclose(atol=1e-8, rtol=1e-5) tolerance this fails intermittently
(~4% of random seeds), surfacing in CI on PR #1968. The result is
mathematically equivalent; loosen the tolerance to atol=1e-5, rtol=1e-3
which is still ~100x tighter than typical float32 noise.

* test(models): apply ruff formatting

---------

Co-authored-by: gabrielfruet <gabrielfruet@users.noreply.github.com>
Co-authored-by: Lionel Peer <lionel@lightly.ai>
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 98.76543% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 86.54%. Comparing base (fc6bf30) to head (f76caa4).

Files with missing lines Patch % Lines
lightly/loss/visreg_loss.py 98.75% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1968      +/-   ##
==========================================
+ Coverage   86.40%   86.54%   +0.13%     
==========================================
  Files         173      174       +1     
  Lines        7386     7467      +81     
==========================================
+ Hits         6382     6462      +80     
- Misses       1004     1005       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@gabrielfruet gabrielfruet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you for the nice contribution :)

@gabrielfruet
gabrielfruet merged commit fc3df0d into lightly-ai:master Jul 9, 2026
14 checks passed
@saud5150 saud5150 mentioned this pull request Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants