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.
- neurofixer-0.1.0/LICENSE +37 -0
- neurofixer-0.1.0/PKG-INFO +159 -0
- neurofixer-0.1.0/README.md +141 -0
- neurofixer-0.1.0/neurofixer/__init__.py +24 -0
- neurofixer-0.1.0/neurofixer/build/__init__.py +11 -0
- neurofixer-0.1.0/neurofixer/build/cnn.py +69 -0
- neurofixer-0.1.0/neurofixer/build/vit.py +82 -0
- neurofixer-0.1.0/neurofixer/demo/__init__.py +4 -0
- neurofixer-0.1.0/neurofixer/demo/arguments.py +15 -0
- neurofixer-0.1.0/neurofixer/demo/functions.py +23 -0
- neurofixer-0.1.0/neurofixer/demo/parameters.py +14 -0
- neurofixer-0.1.0/neurofixer/demo/run_demo.py +22 -0
- neurofixer-0.1.0/neurofixer/models/__init__.py +11 -0
- neurofixer-0.1.0/neurofixer/models/neurofuser_demo/__init__.py +17 -0
- neurofixer-0.1.0/neurofixer/models/neurofuser_demo/cnn.py +69 -0
- neurofixer-0.1.0/neurofixer/models/neurofuser_demo/vit.py +82 -0
- neurofixer-0.1.0/neurofixer/models/registry.py +28 -0
- neurofixer-0.1.0/neurofixer/modules/__init__.py +12 -0
- neurofixer-0.1.0/neurofixer/modules/controller.py +87 -0
- neurofixer-0.1.0/neurofixer/modules/encoding_gate.py +58 -0
- neurofixer-0.1.0/neurofixer/modules/encoding_module.py +68 -0
- neurofixer-0.1.0/neurofixer/modules/fusion_bridge.py +74 -0
- neurofixer-0.1.0/neurofixer/utils/__init__.py +3 -0
- neurofixer-0.1.0/neurofixer/utils/token_ops.py +32 -0
- neurofixer-0.1.0/neurofixer.egg-info/PKG-INFO +159 -0
- neurofixer-0.1.0/neurofixer.egg-info/SOURCES.txt +31 -0
- neurofixer-0.1.0/neurofixer.egg-info/dependency_links.txt +1 -0
- neurofixer-0.1.0/neurofixer.egg-info/entry_points.txt +2 -0
- neurofixer-0.1.0/neurofixer.egg-info/requires.txt +1 -0
- neurofixer-0.1.0/neurofixer.egg-info/top_level.txt +1 -0
- neurofixer-0.1.0/pyproject.toml +30 -0
- neurofixer-0.1.0/setup.cfg +4 -0
- neurofixer-0.1.0/tests/test_smoke.py +30 -0
neurofixer-0.1.0/LICENSE
ADDED
|
@@ -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,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,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
|
+
]
|