seana-ssl 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- seana_ssl-0.1.0/CITATION.cff +18 -0
- seana_ssl-0.1.0/LICENSE +26 -0
- seana_ssl-0.1.0/MANIFEST.in +7 -0
- seana_ssl-0.1.0/PKG-INFO +313 -0
- seana_ssl-0.1.0/THIRD_PARTY_NOTICES.md +88 -0
- seana_ssl-0.1.0/_seana_api.py +433 -0
- seana_ssl-0.1.0/docs/library.md +283 -0
- seana_ssl-0.1.0/examples/ssl_pipeline.py +85 -0
- seana_ssl-0.1.0/pyproject.toml +50 -0
- seana_ssl-0.1.0/seana.py +1076 -0
- seana_ssl-0.1.0/seana_ssl.egg-info/SOURCES.txt +12 -0
- seana_ssl-0.1.0/setup.cfg +4 -0
- seana_ssl-0.1.0/tests/conftest.py +5 -0
- seana_ssl-0.1.0/tests/test_library.py +194 -0
- seana_ssl-0.1.0/uv.lock +5461 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
message: "If you use SEANA, please cite the accompanying paper. Publication metadata will be updated for the camera-ready release."
|
|
3
|
+
type: software
|
|
4
|
+
title: "SEANA: Noise-Aligned View Generation for Self-Supervised Learning"
|
|
5
|
+
version: 0.1.0
|
|
6
|
+
authors:
|
|
7
|
+
- family-names: Patil
|
|
8
|
+
given-names: Oankar R.
|
|
9
|
+
- family-names: Wang
|
|
10
|
+
given-names: May D.
|
|
11
|
+
preferred-citation:
|
|
12
|
+
type: manuscript
|
|
13
|
+
title: "Breaking Noise Shortcuts in Self-Supervised Learning via Noise-Aligned View Generation"
|
|
14
|
+
authors:
|
|
15
|
+
- family-names: Patil
|
|
16
|
+
given-names: Oankar R.
|
|
17
|
+
- family-names: Wang
|
|
18
|
+
given-names: May D.
|
seana_ssl-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SEANA authors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
Scope: this license covers original SEANA code and documentation. Third-party
|
|
24
|
+
code, dependencies, datasets and weights retain their own terms. In particular,
|
|
25
|
+
cifar10/lejepa.py and denoisers/nsp.py are not covered by this MIT grant; see
|
|
26
|
+
THIRD_PARTY_NOTICES.md.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Library source distribution: experiment repository assets are released separately.
|
|
2
|
+
global-exclude *
|
|
3
|
+
include pyproject.toml MANIFEST.in LICENSE CITATION.cff THIRD_PARTY_NOTICES.md
|
|
4
|
+
include seana.py _seana_api.py uv.lock
|
|
5
|
+
include docs/library.md
|
|
6
|
+
include examples/ssl_pipeline.py
|
|
7
|
+
include tests/conftest.py tests/test_library.py
|
seana_ssl-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: seana-ssl
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Learned variance stabilization and noise-aligned views for self-supervised learning
|
|
5
|
+
Author: Oankar R. Patil, May D. Wang
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: self-supervised-learning,augmentation,denoising,pytorch
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: torch<3,>=2.5.1
|
|
12
|
+
Provides-Extra: drunet
|
|
13
|
+
Requires-Dist: deepinv==0.4.1; extra == "drunet"
|
|
14
|
+
Provides-Extra: experiments
|
|
15
|
+
Requires-Dist: torch==2.5.1; extra == "experiments"
|
|
16
|
+
Requires-Dist: torchvision==0.20.1; extra == "experiments"
|
|
17
|
+
Requires-Dist: lightly==1.5.25; extra == "experiments"
|
|
18
|
+
Requires-Dist: deepinv==0.4.1; extra == "experiments"
|
|
19
|
+
Requires-Dist: numpy<3,>=1.26; extra == "experiments"
|
|
20
|
+
Requires-Dist: pillow<14,>=10; extra == "experiments"
|
|
21
|
+
Provides-Extra: imagenet100
|
|
22
|
+
Requires-Dist: datasets==4.4.1; extra == "imagenet100"
|
|
23
|
+
Provides-Extra: bbbc048
|
|
24
|
+
Requires-Dist: tifffile==2024.8.30; extra == "bbbc048"
|
|
25
|
+
Provides-Extra: demo
|
|
26
|
+
Requires-Dist: ipywidgets<9,>=8; extra == "demo"
|
|
27
|
+
Requires-Dist: matplotlib<4,>=3.8; extra == "demo"
|
|
28
|
+
Requires-Dist: tqdm<5,>=4.66; extra == "demo"
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# SEANA for your SSL pipeline
|
|
32
|
+
|
|
33
|
+
SEANA learns a variance-stabilizing transform (VST) around a frozen Gaussian
|
|
34
|
+
denoiser and generates independently resampled views for self-supervised learning.
|
|
35
|
+
The Python distribution is **`seana-ssl`**; its import is **`seana`**. The core
|
|
36
|
+
implementation remains in `seana.py` at the repository root.
|
|
37
|
+
|
|
38
|
+
## Install with uv
|
|
39
|
+
|
|
40
|
+
Add SEANA to your uv project:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
uv add seana-ssl
|
|
44
|
+
# Optional pretrained DRUNet support:
|
|
45
|
+
uv add 'seana-ssl[drunet]'
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For an existing environment using uv's pip interface:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
uv pip install 'seana-ssl[drunet]'
|
|
52
|
+
# Standard pip works too:
|
|
53
|
+
python -m pip install 'seana-ssl[drunet]'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
For local development from a source checkout:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
uv sync --extra drunet
|
|
60
|
+
uv run --extra drunet python -c "from seana import SEANA; print(SEANA)"
|
|
61
|
+
# Or add the checkout to a different project:
|
|
62
|
+
uv add /path/to/SEANA --extra drunet
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Only **PyTorch** is required by the core library. The `drunet` extra adds
|
|
66
|
+
DeepInverse. Importing `seana` does not import DeepInverse or download weights.
|
|
67
|
+
Choose the PyTorch CPU/CUDA build appropriate for your environment; the library
|
|
68
|
+
does not impose a CUDA index. See [uv's PyTorch guide](https://docs.astral.sh/uv/guides/integration/pytorch/).
|
|
69
|
+
Python 3.10+ is required. Research dependencies retain their Python 3.12 recipe.
|
|
70
|
+
|
|
71
|
+
To reproduce this package release, pin `seana-ssl==0.1.0` (or
|
|
72
|
+
`seana-ssl[drunet]==0.1.0`) in your environment.
|
|
73
|
+
|
|
74
|
+
The wheel and source distribution contain the reusable core/API, without research
|
|
75
|
+
datasets, comparison-model code or cluster artifacts. Experiments remain in the
|
|
76
|
+
full repository checkout. The source distribution also includes this guide, a
|
|
77
|
+
runnable example, library tests and the development lockfile.
|
|
78
|
+
|
|
79
|
+
## Fit once, generate views
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import torch
|
|
83
|
+
from seana import SEANA
|
|
84
|
+
|
|
85
|
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
86
|
+
seana = SEANA.from_drunet(
|
|
87
|
+
sigma_d=0.08, # Gaussian denoiser's noise-level input
|
|
88
|
+
sigma_vst=0.1, # Resampling standard deviation in VST space
|
|
89
|
+
channels=3,
|
|
90
|
+
device=device,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# train_loader yields raw floating [B,3,H,W] images, optionally followed by labels.
|
|
94
|
+
# Fit on training images only, before ImageNet/encoder mean-std normalization.
|
|
95
|
+
seana.fit(train_loader, steps=5000, patch_size=64, seed=0)
|
|
96
|
+
|
|
97
|
+
for images, _ in train_loader:
|
|
98
|
+
source_a, source_b = seana(images.to(device))
|
|
99
|
+
# Apply independent SSL transforms to each source, as shown below.
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
These noise levels demonstrate the API; appropriate values depend on the dataset,
|
|
103
|
+
fitted transform and SSL objective. The library does not automatically tune them
|
|
104
|
+
against downstream labels. `sigma_d` and `sigma_vst` have different roles.
|
|
105
|
+
|
|
106
|
+
Calling `seana(images)` denoises once and returns two independent noise draws
|
|
107
|
+
**at the same spatial geometry**. It does not add an implicit crop or normalization
|
|
108
|
+
policy. For a dataset of already-noisy images, use this order:
|
|
109
|
+
|
|
110
|
+
**Original noisy image → SEANA denoising and independent resampling → independent
|
|
111
|
+
SSL crops/photometric transforms → encoder normalization → SSL model.**
|
|
112
|
+
|
|
113
|
+
The fitting loader and the SSL source loader should yield original noisy images,
|
|
114
|
+
converted to floating tensors at the intended intensity scale, before SSL
|
|
115
|
+
augmentations. Apply your single-view transforms to the two SEANA outputs:
|
|
116
|
+
|
|
117
|
+
```python
|
|
118
|
+
source_a, source_b = seana(images)
|
|
119
|
+
view_a = torch.stack([ssl_view_a(image) for image in source_a])
|
|
120
|
+
view_b = torch.stack([ssl_view_b(image) for image in source_b])
|
|
121
|
+
loss = ssl_loss(encoder(view_a), encoder(view_b))
|
|
122
|
+
loss.backward()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Here `ssl_view_a` and `ssl_view_b` are your single-view augmentation pipelines,
|
|
126
|
+
including normalization as their last step. They can share a stochastic transform
|
|
127
|
+
or use different branch settings, as in BYOL. Calling them per image gives
|
|
128
|
+
independent transform draws across examples as well as across branches.
|
|
129
|
+
|
|
130
|
+
This order lets SEANA denoise the original acquisition noise before resizing,
|
|
131
|
+
blur or color operations alter it. Those operations then act on the resampled
|
|
132
|
+
sources, so noise after the SSL transforms need not retain its pre-transform
|
|
133
|
+
statistics. A crop without interpolation or a flip preserves retained pixel
|
|
134
|
+
values, but a crop still changes the denoiser's available context.
|
|
135
|
+
|
|
136
|
+
The API also permits `.augment(crop)` for an explicitly chosen alternate protocol;
|
|
137
|
+
the orders are not generally equivalent. The captured ImageNet runner uses
|
|
138
|
+
SEANA before SSL transforms. The captured CIFAR runner applies SEANA after its
|
|
139
|
+
view transforms, and microscopy has several explicit order controls. Existing
|
|
140
|
+
research recipes retain those protocols; the library example follows the
|
|
141
|
+
SEANA-first workflow described here.
|
|
142
|
+
|
|
143
|
+
## LightlySSL integration
|
|
144
|
+
|
|
145
|
+
Use a **single-view** Lightly transform on each independently resampled source.
|
|
146
|
+
Its normal final normalization can stay enabled because SEANA runs first:
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from lightly.transforms import SimCLRViewTransform
|
|
150
|
+
|
|
151
|
+
ssl_view = SimCLRViewTransform(input_size=224)
|
|
152
|
+
for images, _ in raw_train_loader:
|
|
153
|
+
source_a, source_b = seana(images.to(device))
|
|
154
|
+
view_a = torch.stack([ssl_view(image) for image in source_a])
|
|
155
|
+
view_b = torch.stack([ssl_view(image) for image in source_b])
|
|
156
|
+
loss = ssl_loss(encoder(view_a), encoder(view_b))
|
|
157
|
+
loss.backward()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`SimCLRViewTransform` includes crop/resize, flipping, color jitter, grayscale,
|
|
161
|
+
blur and normalization. Tensor inputs require torchvision transforms v2, available
|
|
162
|
+
in the tested torchvision 0.20.1 / Lightly 1.5.25 research environment.
|
|
163
|
+
See the [Lightly transform API](https://docs.lightly.ai/self-supervised-learning/lightly.transforms.html#lightly.transforms.simclr_transform.SimCLRViewTransform).
|
|
164
|
+
Keep the raw-image loader free of the usual two-view dataset transform and run
|
|
165
|
+
SEANA in the training process, after batching. Using one SEANA noise draw as the
|
|
166
|
+
shared input to a two-view `SimCLRTransform` would share that draw across both
|
|
167
|
+
views, so it is not the independent-resampling path shown above.
|
|
168
|
+
|
|
169
|
+
The augmenter stays in evaluation mode with frozen parameters, even when it is
|
|
170
|
+
a child of a module on which `.train()` is called. Its outputs are detached
|
|
171
|
+
regular tensors, so the encoder still receives parameter gradients. Do not put
|
|
172
|
+
the complete SSL encoder/loss computation inside `torch.no_grad()`.
|
|
173
|
+
|
|
174
|
+
A complete, download-free example is included:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
uv run examples/ssl_pipeline.py
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
It uses synthetic images, a toy averaging filter and a small contrastive encoder
|
|
181
|
+
to demonstrate integration, not scientific performance. To use pretrained DRUNet:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
uv run --extra drunet examples/ssl_pipeline.py --drunet --device cuda
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
To exercise Lightly's actual transforms after SEANA with the research dependencies:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
uv run --python 3.12 --extra experiments examples/ssl_pipeline.py --lightly \
|
|
191
|
+
--checkpoint runs/library_example/lightly_seana.pt
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Add `--drunet --device cuda` to use pretrained DRUNet in that example. Lightly is
|
|
195
|
+
optional; it is not imported by the core library.
|
|
196
|
+
|
|
197
|
+
The root BBBC048 notebook provides a real-data demo in the full repository.
|
|
198
|
+
|
|
199
|
+
## Supply your own denoiser
|
|
200
|
+
|
|
201
|
+
```python
|
|
202
|
+
seana = SEANA(my_denoiser, channels=1, sigma_vst=0.05, device="cuda")
|
|
203
|
+
seana.fit(train_loader, steps=5000, patch_size=64)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The denoiser must be an `nn.Module` mapping floating `[B,C,H,W]` tensors to the
|
|
207
|
+
same shape/device. Its forward pass must be differentiable with respect to its
|
|
208
|
+
**input** during VST fitting, although its own weights and BatchNorm statistics
|
|
209
|
+
stay frozen. A denoiser whose forward uses `torch.no_grad()` cannot train a VST
|
|
210
|
+
through that method.
|
|
211
|
+
|
|
212
|
+
SEANA owns the module by reference: it moves and freezes it. Pass a separate copy
|
|
213
|
+
if another part of your application trains the same denoiser. Inputs may be CHW
|
|
214
|
+
or BCHW for inference. Denoiser-specific image/patch-size constraints still apply.
|
|
215
|
+
|
|
216
|
+
## Fitting options
|
|
217
|
+
|
|
218
|
+
`fit()` accepts a re-iterable loader of tensors or `(images, labels)` batches.
|
|
219
|
+
For dictionaries, pass `batch_key="image"`; other fields are ignored. One-shot
|
|
220
|
+
generators and empty loaders are rejected. Training images must have the configured
|
|
221
|
+
channel count and be at least as large as `patch_size`.
|
|
222
|
+
|
|
223
|
+
By default, the first 50 training batches calibrate one dataset-level intensity
|
|
224
|
+
range. To use a known range:
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
seana = SEANA(my_denoiser, input_range=(0.0, 1.0), sigma_vst=0.1)
|
|
228
|
+
seana.fit(train_loader, calibrate=False, steps=5000, patch_size=64,
|
|
229
|
+
patch_batch_size=4, stride=4, lr=0.01)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The default spline has 128 knots and uses the captured global fitting objective.
|
|
233
|
+
Use `variant="conditional"` for the captured conditional VST, with the correct
|
|
234
|
+
`channels` specified at construction. Existing low-level imports
|
|
235
|
+
`GlobalNoise2VST`, `ConditionalGlobalNoise2VST` and `DeepInvDRUNetWrapper` remain
|
|
236
|
+
available for research code.
|
|
237
|
+
|
|
238
|
+
An optional `seed` isolates the loop's Python/PyTorch RNG state; separate loader
|
|
239
|
+
generators and stochastic worker transforms remain the caller's responsibility.
|
|
240
|
+
The `progress` callback receives percent completion. Repeated `fit()` calls
|
|
241
|
+
continue the current VST weights; construct a new augmenter for a fresh fit.
|
|
242
|
+
A failed fit remains unusable until fitting succeeds. Fitting needs autograd
|
|
243
|
+
and must run outside `torch.inference_mode()`.
|
|
244
|
+
|
|
245
|
+
## Denoising and reproducible resampling
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
estimate = seana.denoise(images) # No noise draw; does not advance the RNG.
|
|
249
|
+
a, b = seana(images, sigma_vst=0.0) # Equal views with resampling disabled.
|
|
250
|
+
a, b = seana(images, sigma_vst=(0.05, 0.15)) # One scale per image, shared by the pair.
|
|
251
|
+
|
|
252
|
+
generator = torch.Generator(device=device).manual_seed(123)
|
|
253
|
+
a, b = seana(images, sigma_vst=0.1, generator=generator)
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Use a generator on the augmenter's device. Recreating it with the same seed
|
|
257
|
+
repeats the noise; reusing it advances the stream. Each view receives independent
|
|
258
|
+
noise. Per-image strengths may be tensors shaped `[B]` or `[B,1,1,1]`. All
|
|
259
|
+
strengths must be finite and nonnegative. Outputs are clamped to the fitted
|
|
260
|
+
physical intensity range by default; `clamp=False` disables both input and output
|
|
261
|
+
clamps. `denoise()` is an estimate, not clean ground truth.
|
|
262
|
+
|
|
263
|
+
## Save and reload
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
seana.save("weights/seana.pt")
|
|
267
|
+
restored = SEANA.load("weights/seana.pt", device=device)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
For a custom denoiser, supply the same configured module:
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
restored = SEANA.load("weights/seana.pt", denoiser=my_reconstructed_denoiser,
|
|
274
|
+
device=device)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Checkpoints store the VST, denoiser tensors, settings and fit summary. DRUNet
|
|
278
|
+
reloads with `pretrained=None`, without another download. Custom denoisers are
|
|
279
|
+
never dynamically imported or unpickled: the provided class/representation is
|
|
280
|
+
checked and tensor states load strictly. Preserve any custom behavior not encoded
|
|
281
|
+
in `state_dict()` or `extra_repr()` yourself. Loading uses a typed payload and
|
|
282
|
+
`torch.load(weights_only=True)`. Saving refuses an existing file. These are
|
|
283
|
+
inference artifacts, not optimizer-state resume checkpoints.
|
|
284
|
+
|
|
285
|
+
## Development and research checkout
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
uv lock --check
|
|
289
|
+
uv build
|
|
290
|
+
uv sync --group dev
|
|
291
|
+
uv run --group dev pytest -q tests/test_library.py
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`uv.lock` records the development resolution. Consumer projects resolve the
|
|
295
|
+
package dependency bounds in their own environment, using their own lockfile.
|
|
296
|
+
|
|
297
|
+
For the complete research checkout and test suite:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
uv sync --python 3.12 --extra experiments --extra imagenet100 --extra bbbc048 \
|
|
301
|
+
--extra demo --group dev --group notebooks
|
|
302
|
+
uv run --no-sync pytest -q
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Legacy `requirements*.txt` files retain the research/Colab installation paths.
|
|
306
|
+
Run experiment scripts from the full checkout; installing the core into another
|
|
307
|
+
project does not install those scripts or datasets.
|
|
308
|
+
|
|
309
|
+
Original SEANA code is MIT licensed. Dependencies, pretrained weights and the
|
|
310
|
+
repository's comparison methods/datasets retain their own terms. Please cite
|
|
311
|
+
*Breaking Noise Shortcuts in Self-Supervised Learning via Noise-Aligned View
|
|
312
|
+
Generation*, Oankar R. Patil and May D. Wang; the repository's `CITATION.cff`
|
|
313
|
+
tracks publication details.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Third-party components
|
|
2
|
+
|
|
3
|
+
The original SEANA code is MIT licensed. The following components retain separate
|
|
4
|
+
terms. This repository has not yet been published.
|
|
5
|
+
|
|
6
|
+
The `seana-ssl` library wheel contains only the original SEANA core and its
|
|
7
|
+
practitioner API, under MIT. Comparison implementations, datasets and pretrained
|
|
8
|
+
weights are excluded from the library distributions. The following comparison
|
|
9
|
+
and dataset notices apply to their files in the full research repository.
|
|
10
|
+
|
|
11
|
+
## LeJEPA / SIGReg
|
|
12
|
+
|
|
13
|
+
`cifar10/lejepa.py` is adapted from the project's microscopy implementation,
|
|
14
|
+
which identifies its Epps–Pulley and slicing routines as ports of
|
|
15
|
+
[galilai-group/lejepa](https://github.com/galilai-group/lejepa), by Randall
|
|
16
|
+
Balestriero and Yann LeCun. The upstream code is licensed under
|
|
17
|
+
[CC BY-NC 4.0](https://github.com/galilai-group/lejepa/blob/main/LICENSE).
|
|
18
|
+
The full license is retained in [third_party/lejepa-LICENSE.txt](third_party/lejepa-LICENSE.txt).
|
|
19
|
+
It is excluded from the MIT grant for original SEANA code.
|
|
20
|
+
|
|
21
|
+
The release adaptation runs on one process, uses two views at the selected dataset's size, and
|
|
22
|
+
exposes the upstream `(1-lambda)*invariance + lambda*SIGReg` weighting and the
|
|
23
|
+
captured project's `invariance + lambda*SIGReg` weighting as separate settings.
|
|
24
|
+
The upstream weighting is the default. Source reference:
|
|
25
|
+
[minimal example](https://github.com/galilai-group/lejepa/blob/main/MINIMAL.md).
|
|
26
|
+
|
|
27
|
+
## Next-Scale Prediction (NSP)
|
|
28
|
+
|
|
29
|
+
`denoisers/nsp.py` is the project's adaptation of
|
|
30
|
+
[XLearning-SCU/2026-CVPR-NSP](https://github.com/XLearning-SCU/2026-CVPR-NSP),
|
|
31
|
+
by Yiwen Shan, Haiyu Zhao, Peng Hu, Xi Peng and Yuanbiao Gou.
|
|
32
|
+
Its DBSNl architecture also references Wu et al., *Unpaired Learning of Deep
|
|
33
|
+
Image Denoising* (ECCV 2020).
|
|
34
|
+
|
|
35
|
+
No license file was present in the inspected NSP repository on 2026-11-06.
|
|
36
|
+
This local preparation preserves the user's existing adaptation; it does not
|
|
37
|
+
assert redistribution permission. **Resolve upstream redistribution terms before
|
|
38
|
+
publishing this file.** The root MIT license does not cover it. Adaptations
|
|
39
|
+
include `tds=4` for 32x32 images, a shorter fit schedule, functional masked
|
|
40
|
+
convolution, vectorized pair sampling and averaged sub-image inference.
|
|
41
|
+
The new ImageNet-100 recipe uses 160x160 fitting patches and tds=5.
|
|
42
|
+
The BBBC048 and fetal ultrasound recipes retain 64x64 fitting patches and tds=4.
|
|
43
|
+
|
|
44
|
+
## Neighbor2Neighbor (N2N)
|
|
45
|
+
|
|
46
|
+
`denoisers/n2n.py` preserves the project's own SmallUNet and loss. It is inspired
|
|
47
|
+
by Tao Huang, Songjiang Li, Xu Jia, Huchuan Lu and Jianzhuang Liu,
|
|
48
|
+
*Neighbor2Neighbor: Self-Supervised Denoising from Single Noisy Images* (CVPR 2021).
|
|
49
|
+
The [official implementation](https://github.com/TaoHuang2018/Neighbor2Neighbor)
|
|
50
|
+
uses a different sampling/regularization scheme. No official implementation is
|
|
51
|
+
vendored here; [protocol.md](docs/protocol.md) states the project's exact loss.
|
|
52
|
+
|
|
53
|
+
## Dependencies, data and pretrained weights
|
|
54
|
+
|
|
55
|
+
PyTorch is the library's required dependency. DeepInverse is an optional extra;
|
|
56
|
+
torchvision, Lightly, Hugging Face Datasets and tifffile support the research workflows.
|
|
57
|
+
Their source code is not bundled into this repository. Model heads and standard
|
|
58
|
+
losses use Lightly. The SEANA experiment uses DeepInverse's pretrained DRUNet;
|
|
59
|
+
its weights are obtained separately and retain their applicable terms.
|
|
60
|
+
|
|
61
|
+
CIFAR-10 data are obtained through torchvision or supplied by the user and are
|
|
62
|
+
not distributed here. ImageNet-100 is obtained separately through
|
|
63
|
+
[clane9/imagenet-100](https://huggingface.co/datasets/clane9/imagenet-100), whose
|
|
64
|
+
dataset card provides its terms. ImageNet images are not redistributed.
|
|
65
|
+
BBBC048's original pre-merged images and ground-truth list are included in the
|
|
66
|
+
single-file [dataset archive](fluorescence_imaging_bbbc048/dataset/bbbc048_merged_v1.zip).
|
|
67
|
+
The [dataset page](https://bbbc.broadinstitute.org/BBBC048) identifies Andrew Filby
|
|
68
|
+
as the licensor under **CC BY-NC-SA 3.0**. The archive retains that license and
|
|
69
|
+
attribution to the Flow Cytometry Core Facility, Newcastle University, with
|
|
70
|
+
citations to Eulenberg et al. (2017) and Ljosa et al. (2012). See
|
|
71
|
+
[the dataset notice](fluorescence_imaging_bbbc048/dataset/NOTICE.md) and
|
|
72
|
+
[full license](fluorescence_imaging_bbbc048/dataset/LICENSE.txt).
|
|
73
|
+
BBBC048 images are redistributed without pixel changes; SEANA adds the manifest,
|
|
74
|
+
hashes and reproducible split assignments.
|
|
75
|
+
|
|
76
|
+
FETAL_PLANES_DB's prepared native-resolution regions are included as the single
|
|
77
|
+
[fetal dataset file](fetal_ultrasound/dataset/fetal_planes_native192_v1.zip).
|
|
78
|
+
[Burgos-Artizzu et al.'s dataset v1](https://doi.org/10.5281/zenodo.3904280) is
|
|
79
|
+
licensed under **CC BY 4.0**. The file preserves the original metadata and adds
|
|
80
|
+
192x192 grayscale crops, provenance hashes and patient partitions. Cropping
|
|
81
|
+
matches the experiment loader without interpolation; the full source frames
|
|
82
|
+
are not bundled. See [attribution and modification notice](fetal_ultrasound/dataset/NOTICE.md)
|
|
83
|
+
and [full license](fetal_ultrasound/dataset/LICENSE.txt). The GitHub dataset file
|
|
84
|
+
uses Git LFS and is excluded from Python package distributions.
|
|
85
|
+
|
|
86
|
+
Experiment CSVs are the author's measurements.
|
|
87
|
+
The repository's MIT license does not grant rights to
|
|
88
|
+
datasets or pretrained weights.
|