neurofixer 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.
Files changed (33) hide show
  1. neurofixer-0.1.0/LICENSE +37 -0
  2. neurofixer-0.1.0/PKG-INFO +159 -0
  3. neurofixer-0.1.0/README.md +141 -0
  4. neurofixer-0.1.0/neurofixer/__init__.py +24 -0
  5. neurofixer-0.1.0/neurofixer/build/__init__.py +11 -0
  6. neurofixer-0.1.0/neurofixer/build/cnn.py +69 -0
  7. neurofixer-0.1.0/neurofixer/build/vit.py +82 -0
  8. neurofixer-0.1.0/neurofixer/demo/__init__.py +4 -0
  9. neurofixer-0.1.0/neurofixer/demo/arguments.py +15 -0
  10. neurofixer-0.1.0/neurofixer/demo/functions.py +23 -0
  11. neurofixer-0.1.0/neurofixer/demo/parameters.py +14 -0
  12. neurofixer-0.1.0/neurofixer/demo/run_demo.py +22 -0
  13. neurofixer-0.1.0/neurofixer/models/__init__.py +11 -0
  14. neurofixer-0.1.0/neurofixer/models/neurofuser_demo/__init__.py +17 -0
  15. neurofixer-0.1.0/neurofixer/models/neurofuser_demo/cnn.py +69 -0
  16. neurofixer-0.1.0/neurofixer/models/neurofuser_demo/vit.py +82 -0
  17. neurofixer-0.1.0/neurofixer/models/registry.py +28 -0
  18. neurofixer-0.1.0/neurofixer/modules/__init__.py +12 -0
  19. neurofixer-0.1.0/neurofixer/modules/controller.py +87 -0
  20. neurofixer-0.1.0/neurofixer/modules/encoding_gate.py +58 -0
  21. neurofixer-0.1.0/neurofixer/modules/encoding_module.py +68 -0
  22. neurofixer-0.1.0/neurofixer/modules/fusion_bridge.py +74 -0
  23. neurofixer-0.1.0/neurofixer/utils/__init__.py +3 -0
  24. neurofixer-0.1.0/neurofixer/utils/token_ops.py +32 -0
  25. neurofixer-0.1.0/neurofixer.egg-info/PKG-INFO +159 -0
  26. neurofixer-0.1.0/neurofixer.egg-info/SOURCES.txt +31 -0
  27. neurofixer-0.1.0/neurofixer.egg-info/dependency_links.txt +1 -0
  28. neurofixer-0.1.0/neurofixer.egg-info/entry_points.txt +2 -0
  29. neurofixer-0.1.0/neurofixer.egg-info/requires.txt +1 -0
  30. neurofixer-0.1.0/neurofixer.egg-info/top_level.txt +1 -0
  31. neurofixer-0.1.0/pyproject.toml +30 -0
  32. neurofixer-0.1.0/setup.cfg +4 -0
  33. neurofixer-0.1.0/tests/test_smoke.py +30 -0
@@ -0,0 +1,37 @@
1
+ NeuroFixer Research Preview License
2
+
3
+ Copyright (c) 2026 Serdar Erişen
4
+
5
+ This repository is released as a public research preview and demonstration
6
+ implementation of NeuroFuser-inspired, backbone-agnostic attention-fusion modules.
7
+
8
+ Permission is granted to view, clone, run, and evaluate this repository for
9
+ personal, academic, and non-commercial research purposes.
10
+
11
+ The following uses are not permitted without prior written permission from the
12
+ copyright holder:
13
+
14
+ 1. Commercial use, including integration into commercial products or services.
15
+ 2. Redistribution of modified or unmodified copies as a competing library.
16
+ 3. Repackaging, relicensing, sublicensing, or selling the software.
17
+ 4. Use of the repository name, NeuroFixer, NeuroFuser, or related project names
18
+ to imply endorsement, official collaboration, or authorship.
19
+ 5. Uploading trained weights, private experimental assets, unpublished datasets,
20
+ or journal-specific confidential material derived from the author's research
21
+ without permission.
22
+
23
+ Academic citation and attribution are required when this repository, its modules,
24
+ or its design ideas are used in research, prototypes, demonstrations, derivative
25
+ works, reports, or publications.
26
+
27
+ This repository is provided "as is", without warranty of any kind, express or
28
+ implied, including but not limited to the warranties of merchantability, fitness
29
+ for a particular purpose, and non-infringement. In no event shall the copyright
30
+ holder be liable for any claim, damages, or other liability arising from the use
31
+ of this repository.
32
+
33
+ For commercial licensing, collaboration, or permission requests, please contact:
34
+
35
+ Serdar Erişen
36
+ GitHub: https://github.com/serdarch
37
+ Repository: https://github.com/serdarch/NeuroFixer
@@ -0,0 +1,159 @@
1
+ Metadata-Version: 2.4
2
+ Name: neurofixer
3
+ Version: 0.1.0
4
+ Summary: Backbone-agnostic build and support tools for NeuroFuser-style attention fusion.
5
+ Author: Serdar Erişen
6
+ Project-URL: Homepage, https://github.com/serdarch/NeuroFixer
7
+ Project-URL: Repository, https://github.com/serdarch/NeuroFixer
8
+ Project-URL: Paper, https://doi.org/10.1016/j.patcog.2026.114167
9
+ Keywords: semantic segmentation,attention,neurofuser,cnn,vit,computer vision
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: torch>=2.0
17
+ Dynamic: license-file
18
+
19
+ # NeuroFixer
20
+
21
+ **NeuroFixer** is the public companion demo and library-oriented repository for the Pattern Recognition article:
22
+
23
+ **NeuroFuser: Resource-Aware Neuromodulation of Multi-scale Fusion Attention for Domain Adaptive Segmentation**
24
+ Serdar Erişen and André Borrmann
25
+ *Pattern Recognition*, 2026
26
+ DOI: **10.1016/j.patcog.2026.114167**
27
+
28
+ NeuroFixer provides a lightweight, backbone-agnostic PyTorch implementation path for NeuroFuser-style attention-fusion modules. It is designed as a public-demo safe repository that can grow toward a future installable package:
29
+
30
+ ```bash
31
+ pip install neurofixer
32
+ ```
33
+
34
+ The current version provides dependency-light PyTorch implementations of the core NeuroFuser-inspired modules:
35
+
36
+ * `EncodingGate` — per-location/channel gated feature calibration with residual flow.
37
+ * `EncodingModule` — latent-grid alignment with grouped dilation modulation.
38
+ * `FusionBridge` — branch-normalized multi-scale fusion for decoder/skip pathways.
39
+ * `NeuromodulationController` — differentiable resource-aware controls for gates, heads, dilations, and fusion weights.
40
+ * Buildable CNN and ViT demo networks without custom dependencies.
41
+
42
+ ## Relation to the paper
43
+
44
+ The published NeuroFuser paper introduces resource-aware neuromodulation of multi-scale fusion attention for domain-adaptive semantic segmentation. NeuroFixer is a public-facing, lightweight implementation and experimentation repository inspired by the paper’s main design principles: backbone-agnostic fusion, controllable attention modulation, CNN/ViT compatibility, and dependency-light modularity.
45
+
46
+ This repository is intentionally released as a public demo and development base. It does not include private training assets, pretrained weights, full experimental pipelines, journal submission files, or confidential reviewer-related material.
47
+
48
+ ## Design principles
49
+
50
+ 1. **Backbone-agnostic:** CNN feature maps and ViT token grids can both use the same EG/EM/FBr interfaces.
51
+ 2. **Minimal dependencies:** PyTorch is the only required runtime dependency.
52
+ 3. **Public-demo safe:** no pretrained weights, no private backbones, and no journal-specific experimental assets are included.
53
+ 4. **Research extensible:** the modules are intentionally modular so user feedback can guide future additions.
54
+ 5. **Future package-ready:** the repository structure is prepared for gradual development toward an installable `neurofixer` package.
55
+
56
+ ## Quick start from source
57
+
58
+ ```bash
59
+ pip install -e .
60
+ python -m neurofixer.demo.run_demo --backbone cnn
61
+ python -m neurofixer.demo.run_demo --backbone vit
62
+ ```
63
+
64
+ Expected output:
65
+
66
+ ```python
67
+ {'backbone': 'cnn', 'input_shape': (1, 3, 128, 128), 'output_shape': (1, 19, 128, 128)}
68
+ ```
69
+
70
+ ## Python usage
71
+
72
+ ```python
73
+ import torch
74
+ from neurofixer import build_cnn_neurofixer, build_vit_neurofixer
75
+
76
+ x = torch.randn(1, 3, 128, 128)
77
+
78
+ model = build_cnn_neurofixer(num_classes=19)
79
+ logits = model(x)
80
+ print(logits.shape)
81
+
82
+ vit_model = build_vit_neurofixer(num_classes=19, patch_size=8)
83
+ vit_logits = vit_model(x)
84
+ print(vit_logits.shape)
85
+ ```
86
+
87
+ ## Repository layout
88
+
89
+ ```text
90
+ neurofixer/
91
+ modules/ # EG, EM, FBr, neuromodulation controller
92
+ build/ # CNN and ViT demo builders
93
+ demo/ # CLI demo and smoke-test helpers
94
+ utils/ # token/grid helpers for CNN-ViT interoperability
95
+
96
+ functions/ # compatibility wrappers for the early folder plan
97
+ build/ # compatibility build entry points
98
+ neurofuser_demo/ # compatibility demo wrappers
99
+ tests/ # smoke tests
100
+ ```
101
+
102
+
103
+ ## Model families
104
+
105
+ NeuroFixer is organized as a lightweight library for reusable attention-fusion modules and model-family demos. The first model family is:
106
+
107
+ ```text
108
+ neurofixer.models.neurofuser_demo
109
+ ```
110
+
111
+ This folder contains lightweight CNN and ViT demonstration networks that use the NeuroFuser-inspired `EncodingGate`, `EncodingModule`, `FusionBridge`, and `NeuromodulationController` components. Future attention projects can be added under `neurofixer/models/` as separate model families without changing the core module API.
112
+
113
+ Example imports:
114
+
115
+ ```python
116
+ from neurofixer.models.neurofuser_demo import build_cnn_neurofixer
117
+ from neurofixer.models.neurofuser_demo import build_vit_neurofixer
118
+ from neurofixer.models.registry import list_models, build_model
119
+ ```
120
+
121
+ ## Development roadmap
122
+
123
+ * Add config dataclasses for larger CNN/ViT variants.
124
+ * Add optional FlashAttention/xFormers adapters only as optional extras, never as required dependencies.
125
+ * Add palette-alignment utilities for training-free domain transfer.
126
+ * Add public examples for Cityscapes-like and ADE20K-like class counts without releasing private weights.
127
+ * Add GitHub Actions smoke tests for CPU-only import and demo execution.
128
+ * Prepare future package metadata for `pip install neurofixer`.
129
+
130
+ ## Citation
131
+
132
+ If you use NeuroFixer, NeuroFuser-inspired modules, or the design ideas in this repository, please cite the associated Pattern Recognition article:
133
+
134
+ ```bibtex
135
+ @article{erisen2026neurofuser,
136
+ title = {NeuroFuser: Resource-Aware Neuromodulation of Multi-scale Fusion Attention for Domain Adaptive Segmentation},
137
+ author = {Eri{\c{s}}en, Serdar and Borrmann, Andr{\'e}},
138
+ journal = {Pattern Recognition},
139
+ year = {2026},
140
+ doi = {10.1016/j.patcog.2026.114167}
141
+ }
142
+ ```
143
+
144
+ ## License and rights
145
+
146
+ Copyright © Serdar Erişen, 2026. All rights reserved.
147
+
148
+ NeuroFixer is released under a custom **Research Preview License**.
149
+
150
+ You may view, clone, run, and evaluate the repository for personal, academic, and non-commercial research purposes. Commercial use, redistribution as a competing library, relicensing, sublicensing, or use of the project names to imply endorsement require prior written permission from the copyright holder.
151
+
152
+ See [LICENSE](LICENSE) for the full terms.
153
+
154
+ ## Contact
155
+
156
+ For academic collaboration, licensing, or repository-related questions, please contact the repository owner through GitHub:
157
+
158
+ **GitHub:** `@serdarch`
159
+ **Repository:** `serdarch/NeuroFixer`
@@ -0,0 +1,141 @@
1
+ # NeuroFixer
2
+
3
+ **NeuroFixer** is the public companion demo and library-oriented repository for the Pattern Recognition article:
4
+
5
+ **NeuroFuser: Resource-Aware Neuromodulation of Multi-scale Fusion Attention for Domain Adaptive Segmentation**
6
+ Serdar Erişen and André Borrmann
7
+ *Pattern Recognition*, 2026
8
+ DOI: **10.1016/j.patcog.2026.114167**
9
+
10
+ NeuroFixer provides a lightweight, backbone-agnostic PyTorch implementation path for NeuroFuser-style attention-fusion modules. It is designed as a public-demo safe repository that can grow toward a future installable package:
11
+
12
+ ```bash
13
+ pip install neurofixer
14
+ ```
15
+
16
+ The current version provides dependency-light PyTorch implementations of the core NeuroFuser-inspired modules:
17
+
18
+ * `EncodingGate` — per-location/channel gated feature calibration with residual flow.
19
+ * `EncodingModule` — latent-grid alignment with grouped dilation modulation.
20
+ * `FusionBridge` — branch-normalized multi-scale fusion for decoder/skip pathways.
21
+ * `NeuromodulationController` — differentiable resource-aware controls for gates, heads, dilations, and fusion weights.
22
+ * Buildable CNN and ViT demo networks without custom dependencies.
23
+
24
+ ## Relation to the paper
25
+
26
+ The published NeuroFuser paper introduces resource-aware neuromodulation of multi-scale fusion attention for domain-adaptive semantic segmentation. NeuroFixer is a public-facing, lightweight implementation and experimentation repository inspired by the paper’s main design principles: backbone-agnostic fusion, controllable attention modulation, CNN/ViT compatibility, and dependency-light modularity.
27
+
28
+ This repository is intentionally released as a public demo and development base. It does not include private training assets, pretrained weights, full experimental pipelines, journal submission files, or confidential reviewer-related material.
29
+
30
+ ## Design principles
31
+
32
+ 1. **Backbone-agnostic:** CNN feature maps and ViT token grids can both use the same EG/EM/FBr interfaces.
33
+ 2. **Minimal dependencies:** PyTorch is the only required runtime dependency.
34
+ 3. **Public-demo safe:** no pretrained weights, no private backbones, and no journal-specific experimental assets are included.
35
+ 4. **Research extensible:** the modules are intentionally modular so user feedback can guide future additions.
36
+ 5. **Future package-ready:** the repository structure is prepared for gradual development toward an installable `neurofixer` package.
37
+
38
+ ## Quick start from source
39
+
40
+ ```bash
41
+ pip install -e .
42
+ python -m neurofixer.demo.run_demo --backbone cnn
43
+ python -m neurofixer.demo.run_demo --backbone vit
44
+ ```
45
+
46
+ Expected output:
47
+
48
+ ```python
49
+ {'backbone': 'cnn', 'input_shape': (1, 3, 128, 128), 'output_shape': (1, 19, 128, 128)}
50
+ ```
51
+
52
+ ## Python usage
53
+
54
+ ```python
55
+ import torch
56
+ from neurofixer import build_cnn_neurofixer, build_vit_neurofixer
57
+
58
+ x = torch.randn(1, 3, 128, 128)
59
+
60
+ model = build_cnn_neurofixer(num_classes=19)
61
+ logits = model(x)
62
+ print(logits.shape)
63
+
64
+ vit_model = build_vit_neurofixer(num_classes=19, patch_size=8)
65
+ vit_logits = vit_model(x)
66
+ print(vit_logits.shape)
67
+ ```
68
+
69
+ ## Repository layout
70
+
71
+ ```text
72
+ neurofixer/
73
+ modules/ # EG, EM, FBr, neuromodulation controller
74
+ build/ # CNN and ViT demo builders
75
+ demo/ # CLI demo and smoke-test helpers
76
+ utils/ # token/grid helpers for CNN-ViT interoperability
77
+
78
+ functions/ # compatibility wrappers for the early folder plan
79
+ build/ # compatibility build entry points
80
+ neurofuser_demo/ # compatibility demo wrappers
81
+ tests/ # smoke tests
82
+ ```
83
+
84
+
85
+ ## Model families
86
+
87
+ NeuroFixer is organized as a lightweight library for reusable attention-fusion modules and model-family demos. The first model family is:
88
+
89
+ ```text
90
+ neurofixer.models.neurofuser_demo
91
+ ```
92
+
93
+ This folder contains lightweight CNN and ViT demonstration networks that use the NeuroFuser-inspired `EncodingGate`, `EncodingModule`, `FusionBridge`, and `NeuromodulationController` components. Future attention projects can be added under `neurofixer/models/` as separate model families without changing the core module API.
94
+
95
+ Example imports:
96
+
97
+ ```python
98
+ from neurofixer.models.neurofuser_demo import build_cnn_neurofixer
99
+ from neurofixer.models.neurofuser_demo import build_vit_neurofixer
100
+ from neurofixer.models.registry import list_models, build_model
101
+ ```
102
+
103
+ ## Development roadmap
104
+
105
+ * Add config dataclasses for larger CNN/ViT variants.
106
+ * Add optional FlashAttention/xFormers adapters only as optional extras, never as required dependencies.
107
+ * Add palette-alignment utilities for training-free domain transfer.
108
+ * Add public examples for Cityscapes-like and ADE20K-like class counts without releasing private weights.
109
+ * Add GitHub Actions smoke tests for CPU-only import and demo execution.
110
+ * Prepare future package metadata for `pip install neurofixer`.
111
+
112
+ ## Citation
113
+
114
+ If you use NeuroFixer, NeuroFuser-inspired modules, or the design ideas in this repository, please cite the associated Pattern Recognition article:
115
+
116
+ ```bibtex
117
+ @article{erisen2026neurofuser,
118
+ title = {NeuroFuser: Resource-Aware Neuromodulation of Multi-scale Fusion Attention for Domain Adaptive Segmentation},
119
+ author = {Eri{\c{s}}en, Serdar and Borrmann, Andr{\'e}},
120
+ journal = {Pattern Recognition},
121
+ year = {2026},
122
+ doi = {10.1016/j.patcog.2026.114167}
123
+ }
124
+ ```
125
+
126
+ ## License and rights
127
+
128
+ Copyright © Serdar Erişen, 2026. All rights reserved.
129
+
130
+ NeuroFixer is released under a custom **Research Preview License**.
131
+
132
+ You may view, clone, run, and evaluate the repository for personal, academic, and non-commercial research purposes. Commercial use, redistribution as a competing library, relicensing, sublicensing, or use of the project names to imply endorsement require prior written permission from the copyright holder.
133
+
134
+ See [LICENSE](LICENSE) for the full terms.
135
+
136
+ ## Contact
137
+
138
+ For academic collaboration, licensing, or repository-related questions, please contact the repository owner through GitHub:
139
+
140
+ **GitHub:** `@serdarch`
141
+ **Repository:** `serdarch/NeuroFixer`
@@ -0,0 +1,24 @@
1
+ """NeuroFixer: lightweight attention-fusion modules and model-family demos."""
2
+
3
+ from neurofixer.modules import (
4
+ EncodingGate,
5
+ EncodingModule,
6
+ FusionBridge,
7
+ NeuromodulationController,
8
+ )
9
+
10
+ from neurofixer.models.neurofuser_demo import (
11
+ build_cnn_neurofixer,
12
+ build_vit_neurofixer,
13
+ )
14
+
15
+ __version__ = "0.1.0"
16
+
17
+ __all__ = [
18
+ "EncodingGate",
19
+ "EncodingModule",
20
+ "FusionBridge",
21
+ "NeuromodulationController",
22
+ "build_cnn_neurofixer",
23
+ "build_vit_neurofixer",
24
+ ]
@@ -0,0 +1,11 @@
1
+ from .cnn import CNNNeuroFuserDemo, SimpleCNNEncoder, build_cnn_neurofixer
2
+ from .vit import SimpleViTGridEncoder, ViTNeuroFuserDemo, build_vit_neurofixer
3
+
4
+ __all__ = [
5
+ "CNNNeuroFuserDemo",
6
+ "SimpleCNNEncoder",
7
+ "build_cnn_neurofixer",
8
+ "SimpleViTGridEncoder",
9
+ "ViTNeuroFuserDemo",
10
+ "build_vit_neurofixer",
11
+ ]
@@ -0,0 +1,69 @@
1
+ """Small CNN demo backbone and NeuroFuser-style decoder."""
2
+ from __future__ import annotations
3
+
4
+ from typing import List, Sequence
5
+
6
+ import torch
7
+ from torch import nn
8
+ import torch.nn.functional as F
9
+
10
+ from neurofixer.modules import EncodingGate, EncodingModule, FusionBridge
11
+
12
+
13
+ class SimpleCNNEncoder(nn.Module):
14
+ """Dependency-free CNN encoder for public demos and smoke tests."""
15
+
16
+ def __init__(self, in_channels: int = 3, channels: Sequence[int] = (32, 64, 128, 256)) -> None:
17
+ super().__init__()
18
+ layers = []
19
+ prev = in_channels
20
+ for i, c in enumerate(channels):
21
+ stride = 1 if i == 0 else 2
22
+ layers.append(nn.Sequential(
23
+ nn.Conv2d(prev, c, 3, stride=stride, padding=1, bias=False),
24
+ nn.BatchNorm2d(c),
25
+ nn.GELU(),
26
+ nn.Conv2d(c, c, 3, padding=1, bias=False),
27
+ nn.BatchNorm2d(c),
28
+ nn.GELU(),
29
+ ))
30
+ prev = c
31
+ self.stages = nn.ModuleList(layers)
32
+ self.channels = tuple(channels)
33
+
34
+ def forward(self, x: torch.Tensor) -> List[torch.Tensor]:
35
+ feats = []
36
+ for stage in self.stages:
37
+ x = stage(x)
38
+ feats.append(x)
39
+ return feats
40
+
41
+
42
+ class CNNNeuroFuserDemo(nn.Module):
43
+ """Buildable CNN NeuroFixer demo using EG, EM, and FBr."""
44
+
45
+ def __init__(self, num_classes: int = 19, in_channels: int = 3, latent_dim: int = 128) -> None:
46
+ super().__init__()
47
+ self.encoder = SimpleCNNEncoder(in_channels=in_channels)
48
+ ch = self.encoder.channels
49
+ self.gates = nn.ModuleList([EncodingGate(c, num_classes=None) for c in ch])
50
+ self.align = nn.ModuleList([EncodingModule(c, latent_dim=latent_dim) for c in ch])
51
+ self.fuse43 = FusionBridge([latent_dim, latent_dim], latent_dim)
52
+ self.fuse32 = FusionBridge([latent_dim, latent_dim], latent_dim)
53
+ self.fuse21 = FusionBridge([latent_dim, latent_dim], latent_dim)
54
+ self.head = nn.Conv2d(latent_dim, num_classes, 1)
55
+
56
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
57
+ image_size = x.shape[-2:]
58
+ feats = [gate(f) for gate, f in zip(self.gates, self.encoder(x))]
59
+ latent = [em(f) for em, f in zip(self.align, feats)]
60
+ y = latent[-1]
61
+ y = self.fuse43([F.interpolate(y, size=latent[-2].shape[-2:], mode="bilinear", align_corners=False), latent[-2]])
62
+ y = self.fuse32([F.interpolate(y, size=latent[-3].shape[-2:], mode="bilinear", align_corners=False), latent[-3]])
63
+ y = self.fuse21([F.interpolate(y, size=latent[-4].shape[-2:], mode="bilinear", align_corners=False), latent[-4]])
64
+ logits = self.head(y)
65
+ return F.interpolate(logits, size=image_size, mode="bilinear", align_corners=False)
66
+
67
+
68
+ def build_cnn_neurofixer(num_classes: int = 19, in_channels: int = 3, latent_dim: int = 128) -> CNNNeuroFuserDemo:
69
+ return CNNNeuroFuserDemo(num_classes=num_classes, in_channels=in_channels, latent_dim=latent_dim)
@@ -0,0 +1,82 @@
1
+ """Small ViT-style demo backbone and NeuroFuser-style decoder."""
2
+ from __future__ import annotations
3
+
4
+ from typing import List, Sequence, Tuple
5
+
6
+ import torch
7
+ from torch import nn
8
+ import torch.nn.functional as F
9
+
10
+ from neurofixer.modules import EncodingGate, EncodingModule, FusionBridge
11
+
12
+
13
+ class PatchEmbed(nn.Module):
14
+ def __init__(self, in_channels: int = 3, embed_dim: int = 128, patch_size: int = 8) -> None:
15
+ super().__init__()
16
+ self.patch_size = patch_size
17
+ self.proj = nn.Conv2d(in_channels, embed_dim, patch_size, stride=patch_size)
18
+
19
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
20
+ return self.proj(x)
21
+
22
+
23
+ class SimpleViTGridEncoder(nn.Module):
24
+ """Grid-preserving ViT-like encoder using PyTorch Transformer blocks.
25
+
26
+ It keeps the demo installable without timm or HuggingFace dependencies.
27
+ """
28
+
29
+ def __init__(self, in_channels: int = 3, embed_dim: int = 128, patch_size: int = 8, depth: int = 4, heads: int = 4) -> None:
30
+ super().__init__()
31
+ self.patch = PatchEmbed(in_channels, embed_dim, patch_size)
32
+ self.blocks = nn.ModuleList([
33
+ nn.TransformerEncoderLayer(
34
+ d_model=embed_dim,
35
+ nhead=heads,
36
+ dim_feedforward=embed_dim * 4,
37
+ batch_first=True,
38
+ activation="gelu",
39
+ norm_first=True,
40
+ )
41
+ for _ in range(depth)
42
+ ])
43
+ self.norms = nn.ModuleList([nn.LayerNorm(embed_dim) for _ in range(depth)])
44
+ self.channels = tuple([embed_dim] * depth)
45
+
46
+ def forward(self, x: torch.Tensor) -> List[torch.Tensor]:
47
+ grid = self.patch(x)
48
+ b, c, h, w = grid.shape
49
+ tokens = grid.flatten(2).transpose(1, 2)
50
+ feats = []
51
+ for block, norm in zip(self.blocks, self.norms):
52
+ tokens = block(tokens)
53
+ z = norm(tokens).transpose(1, 2).reshape(b, c, h, w).contiguous()
54
+ feats.append(z)
55
+ return feats
56
+
57
+
58
+ class ViTNeuroFuserDemo(nn.Module):
59
+ """Buildable ViT NeuroFixer demo using EG, EM, and FBr."""
60
+
61
+ def __init__(self, num_classes: int = 19, in_channels: int = 3, latent_dim: int = 128, patch_size: int = 8) -> None:
62
+ super().__init__()
63
+ self.encoder = SimpleViTGridEncoder(in_channels=in_channels, embed_dim=latent_dim, patch_size=patch_size)
64
+ ch = self.encoder.channels
65
+ self.gates = nn.ModuleList([EncodingGate(c, num_classes=None) for c in ch])
66
+ self.align = nn.ModuleList([EncodingModule(c, latent_dim=latent_dim) for c in ch])
67
+ self.fuse = nn.ModuleList([FusionBridge([latent_dim, latent_dim], latent_dim) for _ in range(len(ch) - 1)])
68
+ self.head = nn.Conv2d(latent_dim, num_classes, 1)
69
+
70
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
71
+ image_size = x.shape[-2:]
72
+ feats = [gate(f) for gate, f in zip(self.gates, self.encoder(x))]
73
+ latent = [em(f) for em, f in zip(self.align, feats)]
74
+ y = latent[-1]
75
+ for skip, fuse in zip(reversed(latent[:-1]), self.fuse):
76
+ y = fuse([y, skip])
77
+ logits = self.head(y)
78
+ return F.interpolate(logits, size=image_size, mode="bilinear", align_corners=False)
79
+
80
+
81
+ def build_vit_neurofixer(num_classes: int = 19, in_channels: int = 3, latent_dim: int = 128, patch_size: int = 8) -> ViTNeuroFuserDemo:
82
+ return ViTNeuroFuserDemo(num_classes=num_classes, in_channels=in_channels, latent_dim=latent_dim, patch_size=patch_size)
@@ -0,0 +1,4 @@
1
+ from .functions import build_demo_model, run_smoke_demo
2
+ from .parameters import DemoParameters
3
+
4
+ __all__ = ["DemoParameters", "build_demo_model", "run_smoke_demo"]
@@ -0,0 +1,15 @@
1
+ """Command-line arguments for NeuroFixer demos."""
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+
6
+
7
+ def build_parser() -> argparse.ArgumentParser:
8
+ parser = argparse.ArgumentParser(description="Run a NeuroFixer CNN/ViT smoke demo.")
9
+ parser.add_argument("--backbone", choices=["cnn", "vit"], default="cnn")
10
+ parser.add_argument("--num-classes", type=int, default=19)
11
+ parser.add_argument("--latent-dim", type=int, default=128)
12
+ parser.add_argument("--image-size", type=int, default=128)
13
+ parser.add_argument("--patch-size", type=int, default=8)
14
+ parser.add_argument("--device", default="cpu")
15
+ return parser
@@ -0,0 +1,23 @@
1
+ """Demo helpers."""
2
+ from __future__ import annotations
3
+
4
+ import torch
5
+
6
+ from neurofixer.build import build_cnn_neurofixer, build_vit_neurofixer
7
+
8
+
9
+ def build_demo_model(backbone: str = "cnn", num_classes: int = 19, latent_dim: int = 128, patch_size: int = 8):
10
+ if backbone == "cnn":
11
+ return build_cnn_neurofixer(num_classes=num_classes, latent_dim=latent_dim)
12
+ if backbone == "vit":
13
+ return build_vit_neurofixer(num_classes=num_classes, latent_dim=latent_dim, patch_size=patch_size)
14
+ raise ValueError("backbone must be 'cnn' or 'vit'")
15
+
16
+
17
+ @torch.no_grad()
18
+ def run_smoke_demo(backbone: str = "cnn", num_classes: int = 19, latent_dim: int = 128, image_size: int = 128, patch_size: int = 8, device: str = "cpu"):
19
+ model = build_demo_model(backbone, num_classes=num_classes, latent_dim=latent_dim, patch_size=patch_size).to(device)
20
+ model.eval()
21
+ x = torch.randn(1, 3, image_size, image_size, device=device)
22
+ y = model(x)
23
+ return {"backbone": backbone, "input_shape": tuple(x.shape), "output_shape": tuple(y.shape)}
@@ -0,0 +1,14 @@
1
+ """Default demo parameters."""
2
+ from __future__ import annotations
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class DemoParameters:
9
+ backbone: str = "cnn" # "cnn" or "vit"
10
+ num_classes: int = 19
11
+ in_channels: int = 3
12
+ latent_dim: int = 128
13
+ image_size: int = 128
14
+ patch_size: int = 8
@@ -0,0 +1,22 @@
1
+ """Executable smoke demo: python -m neurofixer.demo.run_demo --backbone cnn"""
2
+ from __future__ import annotations
3
+
4
+ from .arguments import build_parser
5
+ from .functions import run_smoke_demo
6
+
7
+
8
+ def main() -> None:
9
+ args = build_parser().parse_args()
10
+ result = run_smoke_demo(
11
+ backbone=args.backbone,
12
+ num_classes=args.num_classes,
13
+ latent_dim=args.latent_dim,
14
+ image_size=args.image_size,
15
+ patch_size=args.patch_size,
16
+ device=args.device,
17
+ )
18
+ print(result)
19
+
20
+
21
+ if __name__ == "__main__":
22
+ main()
@@ -0,0 +1,11 @@
1
+ """Model families available in NeuroFixer."""
2
+
3
+ from neurofixer.models.neurofuser_demo import (
4
+ build_cnn_neurofixer,
5
+ build_vit_neurofixer,
6
+ )
7
+
8
+ __all__ = [
9
+ "build_cnn_neurofixer",
10
+ "build_vit_neurofixer",
11
+ ]
@@ -0,0 +1,17 @@
1
+ """NeuroFuser-style public demo models for NeuroFixer."""
2
+
3
+ from neurofixer.models.neurofuser_demo.cnn import (
4
+ CNNNeuroFuserDemo,
5
+ build_cnn_neurofixer,
6
+ )
7
+ from neurofixer.models.neurofuser_demo.vit import (
8
+ ViTNeuroFuserDemo,
9
+ build_vit_neurofixer,
10
+ )
11
+
12
+ __all__ = [
13
+ "CNNNeuroFuserDemo",
14
+ "ViTNeuroFuserDemo",
15
+ "build_cnn_neurofixer",
16
+ "build_vit_neurofixer",
17
+ ]