MarcusRich commited on
Commit
d3954b2
·
verified ·
1 Parent(s): a23ca25

Initial Commit

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +12 -0
  2. 3D-SEMMN/.DS_Store +0 -0
  3. 3D-SEMMN/README.md +105 -0
  4. 3D-SEMMN/__pycache__/train.cpython-312.pyc +0 -0
  5. 3D-SEMMN/__pycache__/visualize.cpython-312.pyc +0 -0
  6. 3D-SEMMN/config/default.yaml +51 -0
  7. 3D-SEMMN/config/light.yaml +17 -0
  8. 3D-SEMMN/data/MNIST/raw/t10k-images-idx3-ubyte +3 -0
  9. 3D-SEMMN/data/MNIST/raw/t10k-images-idx3-ubyte.gz +3 -0
  10. 3D-SEMMN/data/MNIST/raw/t10k-labels-idx1-ubyte +0 -0
  11. 3D-SEMMN/data/MNIST/raw/t10k-labels-idx1-ubyte.gz +3 -0
  12. 3D-SEMMN/data/MNIST/raw/train-images-idx3-ubyte +3 -0
  13. 3D-SEMMN/data/MNIST/raw/train-images-idx3-ubyte.gz +3 -0
  14. 3D-SEMMN/data/MNIST/raw/train-labels-idx1-ubyte +0 -0
  15. 3D-SEMMN/data/MNIST/raw/train-labels-idx1-ubyte.gz +3 -0
  16. 3D-SEMMN/outputs/.DS_Store +0 -0
  17. 3D-SEMMN/outputs/best.pt +3 -0
  18. 3D-SEMMN/outputs/figures/manifold_pca.png +3 -0
  19. 3D-SEMMN/outputs/figures/metrics.png +0 -0
  20. 3D-SEMMN/outputs/figures/neuron_clusters_3d.png +3 -0
  21. 3D-SEMMN/outputs/figures/neuron_grid_interactive.html +0 -0
  22. 3D-SEMMN/outputs/figures/neuron_module_audio.png +3 -0
  23. 3D-SEMMN/outputs/figures/neuron_module_hub.png +3 -0
  24. 3D-SEMMN/outputs/figures/neuron_module_other.png +3 -0
  25. 3D-SEMMN/outputs/figures/neuron_module_vision.png +3 -0
  26. 3D-SEMMN/outputs/figures/neuron_modules_all.png +3 -0
  27. 3D-SEMMN/outputs/figures/route_edges.csv +13 -0
  28. 3D-SEMMN/outputs/figures/route_map_audio_2d.png +3 -0
  29. 3D-SEMMN/outputs/figures/route_map_interactive.html +7 -0
  30. 3D-SEMMN/outputs/figures/route_map_vision_2d.png +3 -0
  31. 3D-SEMMN/outputs/figures/route_nodes.csv +241 -0
  32. 3D-SEMMN/outputs/history.json +37 -0
  33. 3D-SEMMN/requirements.txt +10 -0
  34. 3D-SEMMN/semmn/__init__.py +6 -0
  35. 3D-SEMMN/semmn/__pycache__/__init__.cpython-312.pyc +0 -0
  36. 3D-SEMMN/semmn/__pycache__/columns.cpython-312.pyc +0 -0
  37. 3D-SEMMN/semmn/__pycache__/config.cpython-312.pyc +0 -0
  38. 3D-SEMMN/semmn/__pycache__/connectivity.cpython-312.pyc +0 -0
  39. 3D-SEMMN/semmn/__pycache__/dataset.cpython-312.pyc +0 -0
  40. 3D-SEMMN/semmn/__pycache__/encoders.cpython-312.pyc +0 -0
  41. 3D-SEMMN/semmn/__pycache__/grid.cpython-312.pyc +0 -0
  42. 3D-SEMMN/semmn/__pycache__/hub.cpython-312.pyc +0 -0
  43. 3D-SEMMN/semmn/__pycache__/losses.cpython-312.pyc +0 -0
  44. 3D-SEMMN/semmn/__pycache__/manifold.cpython-312.pyc +0 -0
  45. 3D-SEMMN/semmn/__pycache__/model.cpython-312.pyc +0 -0
  46. 3D-SEMMN/semmn/columns.py +33 -0
  47. 3D-SEMMN/semmn/config.py +121 -0
  48. 3D-SEMMN/semmn/connectivity.py +98 -0
  49. 3D-SEMMN/semmn/dataset.py +135 -0
  50. 3D-SEMMN/semmn/encoders.py +66 -0
.gitattributes CHANGED
@@ -33,3 +33,15 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ 3D_SEMMN_final.pdf filter=lfs diff=lfs merge=lfs -text
37
+ 3D-SEMMN/data/MNIST/raw/t10k-images-idx3-ubyte filter=lfs diff=lfs merge=lfs -text
38
+ 3D-SEMMN/data/MNIST/raw/train-images-idx3-ubyte filter=lfs diff=lfs merge=lfs -text
39
+ 3D-SEMMN/outputs/figures/manifold_pca.png filter=lfs diff=lfs merge=lfs -text
40
+ 3D-SEMMN/outputs/figures/neuron_clusters_3d.png filter=lfs diff=lfs merge=lfs -text
41
+ 3D-SEMMN/outputs/figures/neuron_module_audio.png filter=lfs diff=lfs merge=lfs -text
42
+ 3D-SEMMN/outputs/figures/neuron_module_hub.png filter=lfs diff=lfs merge=lfs -text
43
+ 3D-SEMMN/outputs/figures/neuron_module_other.png filter=lfs diff=lfs merge=lfs -text
44
+ 3D-SEMMN/outputs/figures/neuron_module_vision.png filter=lfs diff=lfs merge=lfs -text
45
+ 3D-SEMMN/outputs/figures/neuron_modules_all.png filter=lfs diff=lfs merge=lfs -text
46
+ 3D-SEMMN/outputs/figures/route_map_audio_2d.png filter=lfs diff=lfs merge=lfs -text
47
+ 3D-SEMMN/outputs/figures/route_map_vision_2d.png filter=lfs diff=lfs merge=lfs -text
3D-SEMMN/.DS_Store ADDED
Binary file (8.2 kB). View file
 
3D-SEMMN/README.md ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 3D-SEMMN (Prototype)
2
+
3
+ Minimal but fully functional PyTorch 2.3+ prototype of a **3D Spatially-Embedded Multimodal Manifold Network** with:
4
+
5
+ - fixed 3D neuron coordinates (`100 x 100 x 50` in `config/default.yaml`)
6
+ - 100 columnar modules (dense intra-column, sparse inter-column)
7
+ - exponential distance-penalized sparse connectivity (`torch.sparse`)
8
+ - Hebbian/STDP update every 100 steps
9
+ - shared perceptual manifold hub with cross-modal attention
10
+ - manifold regularization (latent `d=8`) + geometric twist layer (Cayley rotation)
11
+ - multimodal losses: classification + contrastive + reconstruction + imagination cycle
12
+ - ablations for spatial penalty and manifold loss
13
+
14
+ This code is designed for readability and modular experimentation rather than full biological fidelity.
15
+
16
+ ## Biological Inspirations
17
+
18
+ - **seRNN (Achterberg et al., 2023)**: spatial embedding + wiring-cost constraints for modular sparse topology.
19
+ - **MSeNN-style multimodal ideas (2021)**: cross-modal coupling and biologically motivated integration.
20
+ - **Gallego et al. (2017)**: low-dimensional population manifolds.
21
+
22
+ ## Project Layout
23
+
24
+ - `semmn/config.py`: dataclass config + YAML loader
25
+ - `semmn/grid.py`: 3D coordinates, lobe masks, column assignment
26
+ - `semmn/connectivity.py`: sparse distance-decay edges + STDP + energy proxy
27
+ - `semmn/columns.py`: low-rank dense intra-column dynamics
28
+ - `semmn/encoders.py`: vision CNN and audio 1D-conv encoder
29
+ - `semmn/manifold.py`: manifold autoencoder and geometric twist
30
+ - `semmn/hub.py`: shared manifold hub + attention + imagination decoders
31
+ - `semmn/losses.py`: full training objective
32
+ - `semmn/model.py`: full SEMMN forward pass
33
+ - `semmn/dataset.py`: AV-MNIST loading with synthetic fallback
34
+ - `train.py`: training/eval/checkpointing
35
+ - `visualize.py`: 3D grid, manifold PCA, metrics plots
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ python -m venv .venv
41
+ source .venv/bin/activate
42
+ pip install -r requirements.txt
43
+ ```
44
+
45
+ Train (light config, recommended first):
46
+
47
+ ```bash
48
+ python train.py --config config/light.yaml --device cuda
49
+ ```
50
+
51
+ Train (full 500K-neuron spatial grid metadata):
52
+
53
+ ```bash
54
+ python train.py --config config/default.yaml --device cuda
55
+ ```
56
+
57
+ Generate figures:
58
+
59
+ ```bash
60
+ python visualize.py \
61
+ --config config/light.yaml \
62
+ --checkpoint outputs/best.pt \
63
+ --history outputs/history.json \
64
+ --device cuda
65
+ ```
66
+
67
+ ## Config Notes
68
+
69
+ - `config/default.yaml`: full spatial grid (`100x100x50`)
70
+ - `config/light.yaml`: faster profile (`100x100x10`) for rapid iteration
71
+ - Ablations:
72
+ - `loss.use_spatial_penalty: false`
73
+ - `loss.use_manifold_loss: false`
74
+
75
+ ## Reported Metrics
76
+
77
+ `train.py` logs:
78
+
79
+ - classification loss and total loss
80
+ - validation classification accuracy
81
+ - cross-modal retrieval accuracy (vision->audio nearest match in batch)
82
+ - active sparse parameters (`nnz` proxy)
83
+ - energy proxy (`mean(|w| * distance)`)
84
+
85
+ ## Extension Notes
86
+
87
+ ### Full spiking variant (Brian2 / snnTorch)
88
+
89
+ 1. Replace rate-based state updates (`tanh`) with LIF/AdEx neuron dynamics.
90
+ 2. Convert STDP update from rate Hebbian correlation to spike-timing windows.
91
+ 3. Keep 3D coordinates and sparse wiring graph unchanged for fair ablations.
92
+
93
+ ### Neuromorphic export direction
94
+
95
+ 1. Map columns to compute cores (Loihi/SpiNNaker style partitioning).
96
+ 2. Convert sparse inter-column edges to routing tables.
97
+ 3. Quantize state variables and weights (8-bit or mixed precision).
98
+ 4. Use event-driven updates for power-efficient deployment.
99
+
100
+ ## Practical Runtime Guidance
101
+
102
+ - Start with `config/light.yaml` to confirm setup and debug quickly.
103
+ - Increase `training.batch_size` and `model.recurrent_steps` gradually.
104
+ - Keep STDP interval at `100` to limit plasticity overhead.
105
+ - Use mixed precision (`training.amp: true`) on CUDA devices.
3D-SEMMN/__pycache__/train.cpython-312.pyc ADDED
Binary file (8.79 kB). View file
 
3D-SEMMN/__pycache__/visualize.cpython-312.pyc ADDED
Binary file (28 kB). View file
 
3D-SEMMN/config/default.yaml ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ seed: 42
2
+ grid:
3
+ dims: [100, 100, 50]
4
+ n_columns_xy: [10, 10]
5
+ vision_y_ratio: 0.30
6
+ audio_y_ratio: 0.70
7
+ hub_y_range: [0.40, 0.60]
8
+ hub_z_range: [0.30, 0.70]
9
+
10
+ model:
11
+ state_dim: 32
12
+ latent_dim: 8
13
+ vision_feature_dim: 256
14
+ audio_feature_dim: 256
15
+ recurrent_steps: 6
16
+ attention_heads: 4
17
+
18
+ connectivity:
19
+ lambda_decay: 5.0
20
+ inter_density: 0.08
21
+ intra_density_boost: 2.0
22
+ min_weight: 0.0
23
+ max_weight: 1.5
24
+ init_weight_scale: 0.15
25
+ stdp_interval: 100
26
+ stdp_lr: 0.01
27
+ anti_hebbian: 0.05
28
+
29
+ loss:
30
+ contrastive_weight: 1.0
31
+ reconstruction_weight: 0.5
32
+ imagination_weight: 0.3
33
+ manifold_weight: 0.1
34
+ spatial_penalty_weight: 0.0005
35
+ temperature: 0.1
36
+ use_spatial_penalty: true
37
+ use_manifold_loss: true
38
+
39
+ training:
40
+ dataset_source: synthetic
41
+ batch_size: 64
42
+ epochs: 10
43
+ lr: 0.001
44
+ weight_decay: 0.0001
45
+ num_workers: 4
46
+ log_interval: 50
47
+ val_batches: 100
48
+ amp: true
49
+
50
+ paths:
51
+ output_dir: outputs
3D-SEMMN/config/light.yaml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ seed: 42
2
+ grid:
3
+ dims: [100, 100, 10]
4
+ n_columns_xy: [10, 10]
5
+
6
+ model:
7
+ recurrent_steps: 4
8
+ state_dim: 24
9
+
10
+ connectivity:
11
+ inter_density: 0.10
12
+
13
+ training:
14
+ batch_size: 128
15
+ epochs: 10
16
+ num_workers: 2
17
+ log_interval: 20
3D-SEMMN/data/MNIST/raw/t10k-images-idx3-ubyte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0fa7898d509279e482958e8ce81c8e77db3f2f8254e26661ceb7762c4d494ce7
3
+ size 7840016
3D-SEMMN/data/MNIST/raw/t10k-images-idx3-ubyte.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8d422c7b0a1c1c79245a5bcf07fe86e33eeafee792b84584aec276f5a2dbc4e6
3
+ size 1648877
3D-SEMMN/data/MNIST/raw/t10k-labels-idx1-ubyte ADDED
Binary file (10 kB). View file
 
3D-SEMMN/data/MNIST/raw/t10k-labels-idx1-ubyte.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f7ae60f92e00ec6debd23a6088c31dbd2371eca3ffa0defaefb259924204aec6
3
+ size 4542
3D-SEMMN/data/MNIST/raw/train-images-idx3-ubyte ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:ba891046e6505d7aadcbbe25680a0738ad16aec93bde7f9b65e87a2fc25776db
3
+ size 47040016
3D-SEMMN/data/MNIST/raw/train-images-idx3-ubyte.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:440fcabf73cc546fa21475e81ea370265605f56be210a4024d2ca8f203523609
3
+ size 9912422
3D-SEMMN/data/MNIST/raw/train-labels-idx1-ubyte ADDED
Binary file (60 kB). View file
 
3D-SEMMN/data/MNIST/raw/train-labels-idx1-ubyte.gz ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3552534a0a558bbed6aed32b30c495cca23d567ec52cac8be1a0730e8010255c
3
+ size 28881
3D-SEMMN/outputs/.DS_Store ADDED
Binary file (8.2 kB). View file
 
3D-SEMMN/outputs/best.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:66d1a8bbb97532ad3ea4005ad99e6dbda5b5cced507c3d5c6961fb52b0b1b1a2
3
+ size 7554761
3D-SEMMN/outputs/figures/manifold_pca.png ADDED

Git LFS Details

  • SHA256: cac438e82d7ca1cf2f52af7708f6b9335a8663479adcb74ee24df4a83944a50b
  • Pointer size: 131 Bytes
  • Size of remote file: 118 kB
3D-SEMMN/outputs/figures/metrics.png ADDED
3D-SEMMN/outputs/figures/neuron_clusters_3d.png ADDED

Git LFS Details

  • SHA256: ed62b63fe58c290a70037de84ad4f7b1b4c8f239d8028ce374f85477dac6affc
  • Pointer size: 132 Bytes
  • Size of remote file: 1.42 MB
3D-SEMMN/outputs/figures/neuron_grid_interactive.html ADDED
The diff for this file is too large to render. See raw diff
 
3D-SEMMN/outputs/figures/neuron_module_audio.png ADDED

Git LFS Details

  • SHA256: 7308eb43137af236f224879b820d2ad4f4a590183f2638c8831e30a8e5751e1e
  • Pointer size: 132 Bytes
  • Size of remote file: 1.22 MB
3D-SEMMN/outputs/figures/neuron_module_hub.png ADDED

Git LFS Details

  • SHA256: 5240e02ec0f7f6a58e6e92131a12a049696ba8f4e6a5fcbb3fd1c0ff7122f5a9
  • Pointer size: 131 Bytes
  • Size of remote file: 939 kB
3D-SEMMN/outputs/figures/neuron_module_other.png ADDED

Git LFS Details

  • SHA256: 63ec4360740e7f10fa93ef706ff71d719540624bcbbdd0690b473c0b04bc908c
  • Pointer size: 132 Bytes
  • Size of remote file: 1.21 MB
3D-SEMMN/outputs/figures/neuron_module_vision.png ADDED

Git LFS Details

  • SHA256: b0b2041bcf4e54f8b43f4e42ee2f1991c0e82a0e731cc54a5d76f0c58f60facf
  • Pointer size: 132 Bytes
  • Size of remote file: 1.23 MB
3D-SEMMN/outputs/figures/neuron_modules_all.png ADDED

Git LFS Details

  • SHA256: 98172e67fae1ad85784bf5ed071e9189946dcc665a28508e947b5a59c4415ca8
  • Pointer size: 132 Bytes
  • Size of remote file: 1.8 MB
3D-SEMMN/outputs/figures/route_edges.csv ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ step,source,target,strength,modality
2
+ 0.0,80.0,90.0,0.014531210064888,vision
3
+ 0.0,10.0,0.0,0.0044663818553090096,vision
4
+ 0.0,22.0,11.0,0.003179906401783228,vision
5
+ 1.0,80.0,90.0,0.013347183354198933,vision
6
+ 1.0,10.0,0.0,0.004102454055100679,vision
7
+ 1.0,22.0,11.0,0.002920802216976881,vision
8
+ 2.0,80.0,90.0,0.012341569177806377,vision
9
+ 2.0,10.0,0.0,0.0037933634594082832,vision
10
+ 2.0,22.0,11.0,0.0027007409371435642,vision
11
+ 3.0,80.0,90.0,0.011476870626211166,vision
12
+ 3.0,10.0,0.0,0.0035275856498628855,vision
13
+ 3.0,22.0,11.0,0.0025115162134170532,vision
3D-SEMMN/outputs/figures/route_map_audio_2d.png ADDED

Git LFS Details

  • SHA256: 44696dc9efe5a2209bea6e43bdfb463b229acd0ded4a869b0351626791ae4fd0
  • Pointer size: 131 Bytes
  • Size of remote file: 112 kB
3D-SEMMN/outputs/figures/route_map_interactive.html ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head><meta charset="utf-8" /></head>
3
+ <body>
4
+ <div> <script type="text/javascript">window.PlotlyConfig = {MathJaxConfig: 'local'};</script>
5
+ <script charset="utf-8" src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script> <div id="8c11a467-ec1f-422e-a480-88b89e6970e8" class="plotly-graph-div" style="height:100%; width:100%;"></div> <script type="text/javascript"> window.PLOTLYENV=window.PLOTLYENV || {}; if (document.getElementById("8c11a467-ec1f-422e-a480-88b89e6970e8")) { Plotly.newPlot( "8c11a467-ec1f-422e-a480-88b89e6970e8", [{"hovertemplate":"column=%{text}\u003cextra\u003e\u003c\u002fextra\u003e","marker":{"color":"#D0D0D0","opacity":0.35,"size":7},"mode":"markers","name":"all_columns","text":["0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","96","97","98","99"],"x":[4.5,4.5,4.5,4.5,4.5,4.5,4.5,4.5,4.5,4.5,14.5,14.5,14.5,14.5,14.5,14.5,14.5,14.5,14.5,14.5,24.5,24.5,24.5,24.5,24.5,24.5,24.5,24.5,24.5,24.5,34.5,34.5,34.5,34.5,34.5,34.5,34.5,34.5,34.5,34.5,44.5,44.5,44.5,44.5,44.5,44.5,44.5,44.5,44.5,44.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,54.5,64.5,64.5,64.5,64.5,64.5,64.5,64.5,64.5,64.5,64.5,74.5,74.5,74.5,74.5,74.5,74.5,74.5,74.5,74.5,74.5,84.5,84.5,84.5,84.5,84.5,84.5,84.5,84.5,84.5,84.5,94.5,94.5,94.5,94.5,94.5,94.5,94.5,94.5,94.5,94.5],"y":[4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5,4.5,14.5,24.5,34.5,44.5,54.5,64.5,74.5,84.5,94.5],"type":"scatter"},{"hoverinfo":"skip","line":{"color":"#1f77b4","width":2},"mode":"lines","name":"vision_route","opacity":0.75,"x":[84.5,94.5,null,14.5,4.5,null,24.5,14.5,null,84.5,94.5,null,14.5,4.5,null,24.5,14.5,null,84.5,94.5,null,14.5,4.5,null,24.5,14.5,null,84.5,94.5,null,14.5,4.5,null,24.5,14.5,null],"y":[4.5,4.5,null,4.5,4.5,null,24.5,14.5,null,4.5,4.5,null,4.5,4.5,null,24.5,14.5,null,4.5,4.5,null,4.5,4.5,null,24.5,14.5,null,4.5,4.5,null,4.5,4.5,null,24.5,14.5,null],"type":"scatter"},{"hoverinfo":"skip","line":{"color":"#ff7f0e","width":2},"mode":"lines","name":"audio_route","opacity":0.75,"x":[],"y":[],"type":"scatter"}], {"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmapgl":[{"type":"heatmapgl","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}},"legend":{"orientation":"h"},"title":{"text":"2D Route Simulation Across Column Graph (digit 7)"},"xaxis":{"title":{"text":"Column X"}},"yaxis":{"title":{"text":"Column Y"}},"updatemenus":[{"buttons":[{"args":[{"visible":[true,true,true]}],"label":"Show both","method":"update"},{"args":[{"visible":[true,true,false]}],"label":"Vision route","method":"update"},{"args":[{"visible":[true,false,true]}],"label":"Audio route","method":"update"}],"type":"dropdown","x":0.01,"y":1.12}]}, {"responsive": true} ) }; </script> </div>
6
+ </body>
7
+ </html>
3D-SEMMN/outputs/figures/route_map_vision_2d.png ADDED

Git LFS Details

  • SHA256: 9836e9a5370eb3bd45986e10bd2868effe1def45ff34aa6e2feaca7ed80e0543
  • Pointer size: 131 Bytes
  • Size of remote file: 118 kB
3D-SEMMN/outputs/figures/route_nodes.csv ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ step,column,activity,modality
2
+ 0.0,0.0,0.02956058643758297,vision
3
+ 0.0,1.0,0.0409482941031456,vision
4
+ 0.0,2.0,0.026564355939626694,vision
5
+ 0.0,10.0,0.040411435067653656,vision
6
+ 0.0,11.0,0.02947550266981125,vision
7
+ 0.0,12.0,0.0309763066470623,vision
8
+ 0.0,20.0,0.027739018201828003,vision
9
+ 0.0,21.0,0.023138199001550674,vision
10
+ 0.0,22.0,0.03138161823153496,vision
11
+ 0.0,30.0,0.03375103697180748,vision
12
+ 0.0,31.0,0.034890495240688324,vision
13
+ 0.0,32.0,0.025857770815491676,vision
14
+ 0.0,40.0,0.03491085767745972,vision
15
+ 0.0,41.0,0.04038066044449806,vision
16
+ 0.0,42.0,0.030116962268948555,vision
17
+ 0.0,50.0,0.029867637902498245,vision
18
+ 0.0,51.0,0.036975305527448654,vision
19
+ 0.0,52.0,0.04041629657149315,vision
20
+ 0.0,60.0,0.03777403011918068,vision
21
+ 0.0,61.0,0.02775333821773529,vision
22
+ 0.0,62.0,0.03777413070201874,vision
23
+ 0.0,70.0,0.029612775892019272,vision
24
+ 0.0,71.0,0.03889508917927742,vision
25
+ 0.0,72.0,0.03445589914917946,vision
26
+ 0.0,80.0,0.03937682509422302,vision
27
+ 0.0,81.0,0.027864739298820496,vision
28
+ 0.0,82.0,0.027492109686136246,vision
29
+ 0.0,90.0,0.036627497524023056,vision
30
+ 0.0,91.0,0.03462231159210205,vision
31
+ 0.0,92.0,0.04038887843489647,vision
32
+ 1.0,0.0,0.04356175288558006,vision
33
+ 1.0,1.0,0.03761175647377968,vision
34
+ 1.0,2.0,0.02439984865486622,vision
35
+ 1.0,10.0,0.03711864724755287,vision
36
+ 1.0,11.0,0.038757000118494034,vision
37
+ 1.0,12.0,0.028452306985855103,vision
38
+ 1.0,20.0,0.025478797033429146,vision
39
+ 1.0,21.0,0.021252859383821487,vision
40
+ 1.0,22.0,0.028824592009186745,vision
41
+ 1.0,30.0,0.03100094571709633,vision
42
+ 1.0,31.0,0.03204755857586861,vision
43
+ 1.0,32.0,0.02375083602964878,vision
44
+ 1.0,40.0,0.032066263258457184,vision
45
+ 1.0,41.0,0.037090376019477844,vision
46
+ 1.0,42.0,0.027662981301546097,vision
47
+ 1.0,50.0,0.02743397280573845,vision
48
+ 1.0,51.0,0.033962495625019073,vision
49
+ 1.0,52.0,0.03712311014533043,vision
50
+ 1.0,60.0,0.03469613939523697,vision
51
+ 1.0,61.0,0.025491949170827866,vision
52
+ 1.0,62.0,0.03469623252749443,vision
53
+ 1.0,70.0,0.0271998792886734,vision
54
+ 1.0,71.0,0.035725854337215424,vision
55
+ 1.0,72.0,0.03164837509393692,vision
56
+ 1.0,80.0,0.03616833686828613,vision
57
+ 1.0,81.0,0.025594275444746017,vision
58
+ 1.0,82.0,0.025252006947994232,vision
59
+ 1.0,90.0,0.0870317593216896,vision
60
+ 1.0,91.0,0.03180122748017311,vision
61
+ 1.0,92.0,0.03709792718291283,vision
62
+ 2.0,0.0,0.055453140288591385,vision
63
+ 2.0,1.0,0.03477798402309418,vision
64
+ 2.0,2.0,0.02256149612367153,vision
65
+ 2.0,10.0,0.03432202339172363,vision
66
+ 2.0,11.0,0.04663990065455437,vision
67
+ 2.0,12.0,0.026308631524443626,vision
68
+ 2.0,20.0,0.023559153079986572,vision
69
+ 2.0,21.0,0.019651610404253006,vision
70
+ 2.0,22.0,0.026652866974473,vision
71
+ 2.0,30.0,0.028665248304605484,vision
72
+ 2.0,31.0,0.02963300608098507,vision
73
+ 2.0,32.0,0.021961383521556854,vision
74
+ 2.0,40.0,0.02965030074119568,vision
75
+ 2.0,41.0,0.034295883029699326,vision
76
+ 2.0,42.0,0.025578774511814117,vision
77
+ 2.0,50.0,0.025367021560668945,vision
78
+ 2.0,51.0,0.031403668224811554,vision
79
+ 2.0,52.0,0.03432615101337433,vision
80
+ 2.0,60.0,0.03208203613758087,vision
81
+ 2.0,61.0,0.0235713142901659,vision
82
+ 2.0,62.0,0.032082121819257736,vision
83
+ 2.0,70.0,0.025150563567876816,vision
84
+ 2.0,71.0,0.03303416818380356,vision
85
+ 2.0,72.0,0.029263898730278015,vision
86
+ 2.0,80.0,0.03344331309199333,vision
87
+ 2.0,81.0,0.023665931075811386,vision
88
+ 2.0,82.0,0.023349450901150703,vision
89
+ 2.0,90.0,0.12984082102775574,vision
90
+ 2.0,91.0,0.02940523438155651,vision
91
+ 2.0,92.0,0.03430286794900894,vision
92
+ 3.0,0.0,0.06567821651697159,vision
93
+ 3.0,1.0,0.03234130144119263,vision
94
+ 3.0,2.0,0.020980749279260635,vision
95
+ 3.0,10.0,0.03191728889942169,vision
96
+ 3.0,11.0,0.05341819301247597,vision
97
+ 3.0,12.0,0.024465344846248627,vision
98
+ 3.0,20.0,0.021908504888415337,vision
99
+ 3.0,21.0,0.018274743109941483,vision
100
+ 3.0,22.0,0.024785460904240608,vision
101
+ 3.0,30.0,0.026656849309802055,vision
102
+ 3.0,31.0,0.027556801214814186,vision
103
+ 3.0,32.0,0.020422684028744698,vision
104
+ 3.0,40.0,0.027572883293032646,vision
105
+ 3.0,41.0,0.03189297765493393,vision
106
+ 3.0,42.0,0.023786624893546104,vision
107
+ 3.0,50.0,0.023589707911014557,vision
108
+ 3.0,51.0,0.029203403741121292,vision
109
+ 3.0,52.0,0.03192112594842911,vision
110
+ 3.0,60.0,0.029834242537617683,vision
111
+ 3.0,61.0,0.021919816732406616,vision
112
+ 3.0,62.0,0.0298343226313591,vision
113
+ 3.0,70.0,0.023388417437672615,vision
114
+ 3.0,71.0,0.030719663947820663,vision
115
+ 3.0,72.0,0.027213554829359055,vision
116
+ 3.0,80.0,0.031100144609808922,vision
117
+ 3.0,81.0,0.02200780250132084,vision
118
+ 3.0,82.0,0.02171349711716175,vision
119
+ 3.0,90.0,0.1666511446237564,vision
120
+ 3.0,91.0,0.02734498865902424,vision
121
+ 3.0,92.0,0.03189947456121445,vision
122
+ 0.0,7.0,0.03473106026649475,audio
123
+ 0.0,8.0,0.02794949896633625,audio
124
+ 0.0,9.0,0.027408087626099586,audio
125
+ 0.0,17.0,0.038603682070970535,audio
126
+ 0.0,18.0,0.036946672946214676,audio
127
+ 0.0,19.0,0.02548990212380886,audio
128
+ 0.0,27.0,0.03835974261164665,audio
129
+ 0.0,28.0,0.04123900458216667,audio
130
+ 0.0,29.0,0.030051397159695625,audio
131
+ 0.0,37.0,0.03510997071862221,audio
132
+ 0.0,38.0,0.03655286878347397,audio
133
+ 0.0,39.0,0.024867547675967216,audio
134
+ 0.0,47.0,0.039415426552295685,audio
135
+ 0.0,48.0,0.0356949046254158,audio
136
+ 0.0,49.0,0.04190101474523544,audio
137
+ 0.0,57.0,0.033966340124607086,audio
138
+ 0.0,58.0,0.03714350610971451,audio
139
+ 0.0,59.0,0.03321348875761032,audio
140
+ 0.0,67.0,0.030020426958799362,audio
141
+ 0.0,68.0,0.034492406994104385,audio
142
+ 0.0,69.0,0.02616014890372753,audio
143
+ 0.0,77.0,0.03146708384156227,audio
144
+ 0.0,78.0,0.04283866658806801,audio
145
+ 0.0,79.0,0.02919699251651764,audio
146
+ 0.0,87.0,0.03697360306978226,audio
147
+ 0.0,88.0,0.03308973088860512,audio
148
+ 0.0,89.0,0.02546405978500843,audio
149
+ 0.0,97.0,0.03400813415646553,audio
150
+ 0.0,98.0,0.02903173305094242,audio
151
+ 0.0,99.0,0.028612902387976646,audio
152
+ 1.0,7.0,0.03473105654120445,audio
153
+ 1.0,8.0,0.0279494971036911,audio
154
+ 1.0,9.0,0.027408085763454437,audio
155
+ 1.0,17.0,0.03860367834568024,audio
156
+ 1.0,18.0,0.03694666922092438,audio
157
+ 1.0,19.0,0.02548990026116371,audio
158
+ 1.0,27.0,0.038359738886356354,audio
159
+ 1.0,28.0,0.04123900085687637,audio
160
+ 1.0,29.0,0.030051395297050476,audio
161
+ 1.0,37.0,0.03510996699333191,audio
162
+ 1.0,38.0,0.03655286505818367,audio
163
+ 1.0,39.0,0.024867547675967216,audio
164
+ 1.0,47.0,0.039415426552295685,audio
165
+ 1.0,48.0,0.035694900900125504,audio
166
+ 1.0,49.0,0.04190101474523544,audio
167
+ 1.0,57.0,0.03396633639931679,audio
168
+ 1.0,58.0,0.03714350238442421,audio
169
+ 1.0,59.0,0.03321348503232002,audio
170
+ 1.0,67.0,0.030020423233509064,audio
171
+ 1.0,68.0,0.03449240326881409,audio
172
+ 1.0,69.0,0.026160147041082382,audio
173
+ 1.0,77.0,0.03146708011627197,audio
174
+ 1.0,78.0,0.04283866286277771,audio
175
+ 1.0,79.0,0.02919699065387249,audio
176
+ 1.0,87.0,0.03697359934449196,audio
177
+ 1.0,88.0,0.03308972716331482,audio
178
+ 1.0,89.0,0.02546405978500843,audio
179
+ 1.0,97.0,0.03400813415646553,audio
180
+ 1.0,98.0,0.02903173118829727,audio
181
+ 1.0,99.0,0.028612900525331497,audio
182
+ 2.0,7.0,0.03473105654120445,audio
183
+ 2.0,8.0,0.02794949896633625,audio
184
+ 2.0,9.0,0.027408087626099586,audio
185
+ 2.0,17.0,0.038603682070970535,audio
186
+ 2.0,18.0,0.036946672946214676,audio
187
+ 2.0,19.0,0.02548990212380886,audio
188
+ 2.0,27.0,0.03835974261164665,audio
189
+ 2.0,28.0,0.04123900458216667,audio
190
+ 2.0,29.0,0.030051397159695625,audio
191
+ 2.0,37.0,0.03510997071862221,audio
192
+ 2.0,38.0,0.03655286878347397,audio
193
+ 2.0,39.0,0.024867551401257515,audio
194
+ 2.0,47.0,0.03941543027758598,audio
195
+ 2.0,48.0,0.035694900900125504,audio
196
+ 2.0,49.0,0.04190101847052574,audio
197
+ 2.0,57.0,0.033966340124607086,audio
198
+ 2.0,58.0,0.03714350610971451,audio
199
+ 2.0,59.0,0.03321348503232002,audio
200
+ 2.0,67.0,0.030020425096154213,audio
201
+ 2.0,68.0,0.034492406994104385,audio
202
+ 2.0,69.0,0.02616014890372753,audio
203
+ 2.0,77.0,0.03146708384156227,audio
204
+ 2.0,78.0,0.04283866658806801,audio
205
+ 2.0,79.0,0.02919699251651764,audio
206
+ 2.0,87.0,0.03697360306978226,audio
207
+ 2.0,88.0,0.03308973088860512,audio
208
+ 2.0,89.0,0.02546406351029873,audio
209
+ 2.0,97.0,0.03400813788175583,audio
210
+ 2.0,98.0,0.02903173305094242,audio
211
+ 2.0,99.0,0.028612902387976646,audio
212
+ 3.0,7.0,0.03473105654120445,audio
213
+ 3.0,8.0,0.0279495008289814,audio
214
+ 3.0,9.0,0.027408087626099586,audio
215
+ 3.0,17.0,0.038603682070970535,audio
216
+ 3.0,18.0,0.036946672946214676,audio
217
+ 3.0,19.0,0.02548990212380886,audio
218
+ 3.0,27.0,0.03835974261164665,audio
219
+ 3.0,28.0,0.04123900458216667,audio
220
+ 3.0,29.0,0.030051397159695625,audio
221
+ 3.0,37.0,0.03510997071862221,audio
222
+ 3.0,38.0,0.03655286878347397,audio
223
+ 3.0,39.0,0.024867551401257515,audio
224
+ 3.0,47.0,0.03941543027758598,audio
225
+ 3.0,48.0,0.035694900900125504,audio
226
+ 3.0,49.0,0.04190101847052574,audio
227
+ 3.0,57.0,0.033966340124607086,audio
228
+ 3.0,58.0,0.03714350610971451,audio
229
+ 3.0,59.0,0.03321348503232002,audio
230
+ 3.0,67.0,0.030020426958799362,audio
231
+ 3.0,68.0,0.034492406994104385,audio
232
+ 3.0,69.0,0.02616015076637268,audio
233
+ 3.0,77.0,0.03146708384156227,audio
234
+ 3.0,78.0,0.04283866658806801,audio
235
+ 3.0,79.0,0.02919699251651764,audio
236
+ 3.0,87.0,0.03697360306978226,audio
237
+ 3.0,88.0,0.03308973088860512,audio
238
+ 3.0,89.0,0.02546406351029873,audio
239
+ 3.0,97.0,0.03400813788175583,audio
240
+ 3.0,98.0,0.02903173491358757,audio
241
+ 3.0,99.0,0.028612902387976646,audio
3D-SEMMN/outputs/history.json ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "epoch": 0,
4
+ "step": 0,
5
+ "loss_total": 6.665867805480957,
6
+ "loss_cls": 2.322234630584717,
7
+ "loss_contrastive": 4.330072402954102,
8
+ "loss_manifold": 0.007405777927488089,
9
+ "active_params": 2.0,
10
+ "energy_proxy": 0.17007668316364288
11
+ },
12
+ {
13
+ "epoch": 0,
14
+ "step": 10,
15
+ "loss_total": 5.909451484680176,
16
+ "loss_cls": 2.2938742637634277,
17
+ "loss_contrastive": 3.5930726528167725,
18
+ "loss_manifold": 0.001445187022909522,
19
+ "active_params": 6.0,
20
+ "energy_proxy": 0.12415368109941483
21
+ },
22
+ {
23
+ "epoch": 0,
24
+ "step": 20,
25
+ "loss_total": 5.335961818695068,
26
+ "loss_cls": 2.2907979488372803,
27
+ "loss_contrastive": 3.0338499546051025,
28
+ "loss_manifold": 0.0009116176515817642,
29
+ "active_params": 6.0,
30
+ "energy_proxy": 0.07187842577695847
31
+ },
32
+ {
33
+ "epoch": 0,
34
+ "val_accuracy": 0.0,
35
+ "val_cross_modal_retrieval": 0.0
36
+ }
37
+ ]
3D-SEMMN/requirements.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ torch>=2.3
2
+ torchvision>=0.18
3
+ numpy>=1.25
4
+ pandas>=2.2
5
+ PyYAML>=6.0
6
+ matplotlib>=3.8
7
+ plotly>=5.22
8
+ scikit-learn>=1.4
9
+ tqdm>=4.66
10
+ datasets>=2.20
3D-SEMMN/semmn/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ """3D-SEMMN package."""
2
+
3
+ from semmn.config import SEMMNConfig
4
+ from semmn.model import SEMMNModel
5
+
6
+ __all__ = ["SEMMNConfig", "SEMMNModel"]
3D-SEMMN/semmn/__pycache__/__init__.cpython-312.pyc ADDED
Binary file (314 Bytes). View file
 
3D-SEMMN/semmn/__pycache__/columns.cpython-312.pyc ADDED
Binary file (2.38 kB). View file
 
3D-SEMMN/semmn/__pycache__/config.cpython-312.pyc ADDED
Binary file (7.13 kB). View file
 
3D-SEMMN/semmn/__pycache__/connectivity.cpython-312.pyc ADDED
Binary file (7.7 kB). View file
 
3D-SEMMN/semmn/__pycache__/dataset.cpython-312.pyc ADDED
Binary file (8.56 kB). View file
 
3D-SEMMN/semmn/__pycache__/encoders.cpython-312.pyc ADDED
Binary file (4.64 kB). View file
 
3D-SEMMN/semmn/__pycache__/grid.cpython-312.pyc ADDED
Binary file (5.31 kB). View file
 
3D-SEMMN/semmn/__pycache__/hub.cpython-312.pyc ADDED
Binary file (4.54 kB). View file
 
3D-SEMMN/semmn/__pycache__/losses.cpython-312.pyc ADDED
Binary file (3.45 kB). View file
 
3D-SEMMN/semmn/__pycache__/manifold.cpython-312.pyc ADDED
Binary file (4.13 kB). View file
 
3D-SEMMN/semmn/__pycache__/model.cpython-312.pyc ADDED
Binary file (6.95 kB). View file
 
3D-SEMMN/semmn/columns.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Columnar dynamics modules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+
8
+
9
+ class ColumnarDynamics(nn.Module):
10
+ """Dense intra-column dynamics with low-rank factors."""
11
+
12
+ def __init__(self, num_columns: int, state_dim: int, rank: int = 8) -> None:
13
+ super().__init__()
14
+ self.num_columns = num_columns
15
+ self.state_dim = state_dim
16
+ self.rank = rank
17
+
18
+ self.u = nn.Parameter(torch.randn(num_columns, state_dim, rank) * 0.05)
19
+ self.v = nn.Parameter(torch.randn(num_columns, rank, state_dim) * 0.05)
20
+ self.bias = nn.Parameter(torch.zeros(num_columns, state_dim))
21
+ self.norm = nn.LayerNorm(state_dim)
22
+
23
+ def forward(self, states: torch.Tensor, inter_messages: torch.Tensor) -> torch.Tensor:
24
+ # W_col = U @ V in factored form to keep parameters compact.
25
+ w = torch.matmul(self.u, self.v) # (C, D, D)
26
+ intra = torch.einsum("bcd,cde->bce", states, w)
27
+ updated = intra + inter_messages + self.bias.unsqueeze(0)
28
+ return torch.tanh(self.norm(updated))
29
+
30
+
31
+ def pool_columns(states: torch.Tensor) -> torch.Tensor:
32
+ """Convert `(B, C, D)` into `(B, C)` pooled activity."""
33
+ return states.mean(dim=-1)
3D-SEMMN/semmn/config.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Configuration handling for 3D-SEMMN."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass, field
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+ import yaml
10
+
11
+
12
+ @dataclass
13
+ class GridConfig:
14
+ dims: tuple[int, int, int] = (100, 100, 50)
15
+ n_columns_xy: tuple[int, int] = (10, 10)
16
+ vision_y_ratio: float = 0.30
17
+ audio_y_ratio: float = 0.70
18
+ hub_y_range: tuple[float, float] = (0.40, 0.60)
19
+ hub_z_range: tuple[float, float] = (0.30, 0.70)
20
+
21
+
22
+ @dataclass
23
+ class ModelConfig:
24
+ state_dim: int = 32
25
+ latent_dim: int = 8
26
+ vision_feature_dim: int = 256
27
+ audio_feature_dim: int = 256
28
+ recurrent_steps: int = 6
29
+ attention_heads: int = 4
30
+
31
+
32
+ @dataclass
33
+ class ConnectivityConfig:
34
+ lambda_decay: float = 5.0
35
+ inter_density: float = 0.08
36
+ intra_density_boost: float = 2.0
37
+ min_weight: float = 0.0
38
+ max_weight: float = 1.5
39
+ init_weight_scale: float = 0.15
40
+ stdp_interval: int = 100
41
+ stdp_lr: float = 0.01
42
+ anti_hebbian: float = 0.05
43
+
44
+
45
+ @dataclass
46
+ class LossConfig:
47
+ contrastive_weight: float = 1.0
48
+ reconstruction_weight: float = 0.5
49
+ imagination_weight: float = 0.3
50
+ manifold_weight: float = 0.1
51
+ spatial_penalty_weight: float = 5e-4
52
+ temperature: float = 0.1
53
+ use_spatial_penalty: bool = True
54
+ use_manifold_loss: bool = True
55
+
56
+
57
+ @dataclass
58
+ class TrainingConfig:
59
+ dataset_source: str = "synthetic"
60
+ batch_size: int = 64
61
+ epochs: int = 10
62
+ lr: float = 1e-3
63
+ weight_decay: float = 1e-4
64
+ num_workers: int = 4
65
+ log_interval: int = 50
66
+ val_batches: int = 100
67
+ amp: bool = True
68
+
69
+
70
+ @dataclass
71
+ class PathsConfig:
72
+ output_dir: str = "outputs"
73
+
74
+
75
+ @dataclass
76
+ class SEMMNConfig:
77
+ seed: int = 42
78
+ grid: GridConfig = field(default_factory=GridConfig)
79
+ model: ModelConfig = field(default_factory=ModelConfig)
80
+ connectivity: ConnectivityConfig = field(default_factory=ConnectivityConfig)
81
+ loss: LossConfig = field(default_factory=LossConfig)
82
+ training: TrainingConfig = field(default_factory=TrainingConfig)
83
+ paths: PathsConfig = field(default_factory=PathsConfig)
84
+
85
+ @property
86
+ def n_columns(self) -> int:
87
+ return self.grid.n_columns_xy[0] * self.grid.n_columns_xy[1]
88
+
89
+ @property
90
+ def n_neurons(self) -> int:
91
+ return self.grid.dims[0] * self.grid.dims[1] * self.grid.dims[2]
92
+
93
+ @classmethod
94
+ def from_yaml(cls, path: str | Path) -> "SEMMNConfig":
95
+ with Path(path).open("r", encoding="utf-8") as f:
96
+ raw = yaml.safe_load(f) or {}
97
+ return cls.from_dict(raw)
98
+
99
+ @classmethod
100
+ def from_dict(cls, raw: dict[str, Any]) -> "SEMMNConfig":
101
+ return cls(
102
+ seed=raw.get("seed", 42),
103
+ grid=_merge_dataclass(GridConfig(), raw.get("grid", {})),
104
+ model=_merge_dataclass(ModelConfig(), raw.get("model", {})),
105
+ connectivity=_merge_dataclass(
106
+ ConnectivityConfig(), raw.get("connectivity", {})
107
+ ),
108
+ loss=_merge_dataclass(LossConfig(), raw.get("loss", {})),
109
+ training=_merge_dataclass(TrainingConfig(), raw.get("training", {})),
110
+ paths=_merge_dataclass(PathsConfig(), raw.get("paths", {})),
111
+ )
112
+
113
+
114
+ def _merge_dataclass(default_obj: Any, overrides: dict[str, Any]) -> Any:
115
+ current = default_obj.__dict__.copy()
116
+ for key, value in overrides.items():
117
+ if isinstance(current.get(key), tuple) and isinstance(value, list):
118
+ current[key] = tuple(value)
119
+ else:
120
+ current[key] = value
121
+ return type(default_obj)(**current)
3D-SEMMN/semmn/connectivity.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Sparse distance-penalized connectivity and STDP rules."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+
8
+ from semmn.config import ConnectivityConfig
9
+
10
+
11
+ class SparseInterColumnConnectivity(nn.Module):
12
+ """Sparse inter-column graph with distance-decay sampling.
13
+
14
+ Inspired by seRNN wiring constraints: long-range links carry a larger cost,
15
+ so we initialize and regularize them with an exponential distance penalty.
16
+ """
17
+
18
+ def __init__(
19
+ self,
20
+ column_centers: torch.Tensor,
21
+ state_dim: int,
22
+ config: ConnectivityConfig,
23
+ ) -> None:
24
+ super().__init__()
25
+ self.state_dim = state_dim
26
+ self.config = config
27
+ self.num_columns = int(column_centers.shape[0])
28
+ self.register_buffer("column_centers", column_centers.clone())
29
+
30
+ row_idx, col_idx, distances, weights = self._build_sparse_edges()
31
+ self.register_buffer("row_idx", row_idx)
32
+ self.register_buffer("col_idx", col_idx)
33
+ self.register_buffer("edge_distances", distances)
34
+ self.edge_weights = nn.Parameter(weights)
35
+ self.inter_gain = nn.Parameter(torch.ones(state_dim))
36
+
37
+ def _build_sparse_edges(self) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
38
+ centers = self.column_centers
39
+ c = centers.shape[0]
40
+ dist = torch.cdist(centers, centers, p=2)
41
+ decay = torch.exp(-dist / max(self.config.lambda_decay, 1e-6))
42
+ eye_mask = ~torch.eye(c, dtype=torch.bool, device=centers.device)
43
+ prob = (decay * self.config.inter_density).clamp(0.0, 1.0)
44
+ sampled = (torch.rand_like(prob) < prob) & eye_mask
45
+ row_idx, col_idx = torch.where(sampled)
46
+
47
+ if row_idx.numel() == 0:
48
+ row_idx = torch.arange(0, c - 1, device=centers.device)
49
+ col_idx = torch.arange(1, c, device=centers.device)
50
+
51
+ distances = dist[row_idx, col_idx]
52
+ weights = torch.randn(row_idx.numel(), device=centers.device) * self.config.init_weight_scale
53
+ weights = weights.clamp(self.config.min_weight, self.config.max_weight)
54
+ return row_idx.long(), col_idx.long(), distances.float(), weights.float()
55
+
56
+ def sparse_matrix(self) -> torch.Tensor:
57
+ indices = torch.stack([self.row_idx, self.col_idx], dim=0)
58
+ return torch.sparse_coo_tensor(
59
+ indices=indices,
60
+ values=self.edge_weights,
61
+ size=(self.num_columns, self.num_columns),
62
+ device=self.edge_weights.device,
63
+ ).coalesce()
64
+
65
+ def forward(self, states: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
66
+ """Apply sparse inter-column message passing.
67
+
68
+ Args:
69
+ states: `(B, C, D)` column states.
70
+ Returns:
71
+ inter_messages: `(B, C, D)` sparse messages.
72
+ scalar_activity: `(B, C)` pooled activity used for STDP.
73
+ """
74
+ scalar_activity = states.mean(dim=-1) # (B, C)
75
+ sparse_w = self.sparse_matrix()
76
+ propagated = torch.sparse.mm(sparse_w, scalar_activity.transpose(0, 1)).transpose(0, 1)
77
+ inter_messages = propagated.unsqueeze(-1) * self.inter_gain.view(1, 1, -1)
78
+ return inter_messages, scalar_activity
79
+
80
+ @torch.no_grad()
81
+ def stdp_update(self, pre_activity: torch.Tensor, post_activity: torch.Tensor) -> None:
82
+ """Hebbian/STDP-like update on sparse edge values."""
83
+ if pre_activity.numel() == 0:
84
+ return
85
+ pre = pre_activity.mean(dim=0) # (C,)
86
+ post = post_activity.mean(dim=0) # (C,)
87
+ corr = torch.outer(post, pre)
88
+ edge_corr = corr[self.row_idx, self.col_idx]
89
+ anti = self.config.anti_hebbian * self.edge_weights.abs()
90
+ delta = self.config.stdp_lr * (edge_corr - anti)
91
+ new_w = self.edge_weights + delta
92
+ self.edge_weights.copy_(new_w.clamp(self.config.min_weight, self.config.max_weight))
93
+
94
+ def spatial_wiring_cost(self) -> torch.Tensor:
95
+ return (self.edge_weights.abs() * self.edge_distances).mean()
96
+
97
+ def active_parameters(self) -> int:
98
+ return int((self.edge_weights.abs() > 1e-8).sum().item())
3D-SEMMN/semmn/dataset.py ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Multimodal AV-MNIST dataset helpers."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+
7
+ import torch
8
+ import torch.nn.functional as F
9
+ from torch.utils.data import DataLoader, Dataset
10
+ from torchvision import datasets, transforms
11
+
12
+ from semmn.config import SEMMNConfig
13
+
14
+
15
+ @dataclass
16
+ class Batch:
17
+ vision: torch.Tensor
18
+ audio: torch.Tensor
19
+ label: torch.Tensor
20
+
21
+
22
+ class SyntheticAVMNIST(Dataset):
23
+ """Pair MNIST vision with synthetic spectrogram-like audio."""
24
+
25
+ def __init__(self, root: str, train: bool = True) -> None:
26
+ tfm = transforms.ToTensor()
27
+ self.mnist = datasets.MNIST(root=root, train=train, download=True, transform=tfm)
28
+
29
+ def __len__(self) -> int:
30
+ return len(self.mnist)
31
+
32
+ def __getitem__(self, idx: int) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
33
+ vision, label = self.mnist[idx]
34
+ audio = self._label_to_spectrogram(int(label), idx)
35
+ return vision, audio, torch.tensor(label, dtype=torch.long)
36
+
37
+ def _label_to_spectrogram(self, label: int, seed: int) -> torch.Tensor:
38
+ g = torch.Generator().manual_seed(seed)
39
+ t = torch.linspace(0, 1, steps=224)
40
+ base_freq = 110.0 + 22.0 * float(label)
41
+ sine = (
42
+ torch.sin(2.0 * torch.pi * base_freq * t)
43
+ + 0.3 * torch.sin(2.0 * torch.pi * 2.0 * base_freq * t)
44
+ + 0.2 * torch.randn(224, generator=g)
45
+ )
46
+ spec = torch.stft(
47
+ sine,
48
+ n_fft=64,
49
+ hop_length=16,
50
+ win_length=64,
51
+ return_complex=True,
52
+ ).abs()
53
+ spec = spec.unsqueeze(0) # (1, F, T)
54
+ spec = F.interpolate(spec.unsqueeze(0), size=(112, 112), mode="bilinear", align_corners=False)
55
+ spec = spec.squeeze(0)
56
+ spec = spec / (spec.max().clamp_min(1e-6))
57
+ return spec
58
+
59
+
60
+ class HuggingFaceAVMNIST(Dataset):
61
+ """Attempt to read BLOSSOM-framework/AV-MNIST with robust key fallback."""
62
+
63
+ def __init__(self, split: str = "train") -> None:
64
+ from datasets import load_dataset # lazy import
65
+
66
+ self.ds = load_dataset("BLOSSOM-framework/AV-MNIST", split=split)
67
+
68
+ def __len__(self) -> int:
69
+ return len(self.ds)
70
+
71
+ def __getitem__(self, idx: int) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
72
+ row = self.ds[idx]
73
+ vision = _to_tensor_image(row.get("image") or row.get("vision") or row.get("mnist"))
74
+ audio = _to_tensor_audio(row.get("audio") or row.get("spectrogram") or row.get("sound"))
75
+ label = int(row.get("label") or row.get("digit") or row.get("class"))
76
+ return vision, audio, torch.tensor(label, dtype=torch.long)
77
+
78
+
79
+ def _to_tensor_image(value) -> torch.Tensor:
80
+ if isinstance(value, torch.Tensor):
81
+ x = value.float()
82
+ else:
83
+ x = torch.tensor(value, dtype=torch.float32)
84
+ if x.ndim == 2:
85
+ x = x.unsqueeze(0)
86
+ x = F.interpolate(x.unsqueeze(0), size=(28, 28), mode="bilinear", align_corners=False).squeeze(0)
87
+ return x.clamp(0.0, 1.0)
88
+
89
+
90
+ def _to_tensor_audio(value) -> torch.Tensor:
91
+ if isinstance(value, dict) and "array" in value:
92
+ arr = torch.tensor(value["array"], dtype=torch.float32)
93
+ spec = torch.stft(arr, n_fft=128, hop_length=32, return_complex=True).abs()
94
+ x = spec.unsqueeze(0)
95
+ elif isinstance(value, torch.Tensor):
96
+ x = value.float()
97
+ else:
98
+ x = torch.tensor(value, dtype=torch.float32)
99
+ while x.ndim < 3:
100
+ x = x.unsqueeze(0)
101
+ if x.shape[0] != 1:
102
+ x = x[:1]
103
+ x = F.interpolate(x.unsqueeze(0), size=(112, 112), mode="bilinear", align_corners=False).squeeze(0)
104
+ x = x / (x.max().clamp_min(1e-6))
105
+ return x
106
+
107
+
108
+ def build_dataloaders(config: SEMMNConfig) -> tuple[DataLoader, DataLoader]:
109
+ root = "./data"
110
+ if config.training.dataset_source == "hf":
111
+ try:
112
+ train_ds = HuggingFaceAVMNIST(split="train")
113
+ val_ds = HuggingFaceAVMNIST(split="test")
114
+ except Exception:
115
+ train_ds = SyntheticAVMNIST(root=root, train=True)
116
+ val_ds = SyntheticAVMNIST(root=root, train=False)
117
+ else:
118
+ train_ds = SyntheticAVMNIST(root=root, train=True)
119
+ val_ds = SyntheticAVMNIST(root=root, train=False)
120
+
121
+ train_loader = DataLoader(
122
+ train_ds,
123
+ batch_size=config.training.batch_size,
124
+ shuffle=True,
125
+ num_workers=config.training.num_workers,
126
+ pin_memory=True,
127
+ )
128
+ val_loader = DataLoader(
129
+ val_ds,
130
+ batch_size=config.training.batch_size,
131
+ shuffle=False,
132
+ num_workers=max(1, config.training.num_workers // 2),
133
+ pin_memory=True,
134
+ )
135
+ return train_loader, val_loader
3D-SEMMN/semmn/encoders.py ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Vision/audio encoders and lobe injection."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+
8
+
9
+ class VisionEncoder(nn.Module):
10
+ def __init__(self, out_dim: int = 256) -> None:
11
+ super().__init__()
12
+ self.net = nn.Sequential(
13
+ nn.Conv2d(1, 32, kernel_size=3, padding=1),
14
+ nn.ReLU(inplace=True),
15
+ nn.MaxPool2d(2),
16
+ nn.Conv2d(32, 64, kernel_size=3, padding=1),
17
+ nn.ReLU(inplace=True),
18
+ nn.MaxPool2d(2),
19
+ nn.Flatten(),
20
+ nn.Linear(64 * 7 * 7, out_dim),
21
+ nn.ReLU(inplace=True),
22
+ )
23
+
24
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
25
+ return self.net(x)
26
+
27
+
28
+ class AudioEncoder1D(nn.Module):
29
+ """1D Conv encoder over spectrogram time sequences."""
30
+
31
+ def __init__(self, out_dim: int = 256, freq_bins: int = 112) -> None:
32
+ super().__init__()
33
+ self.net = nn.Sequential(
34
+ nn.Conv1d(freq_bins, 128, kernel_size=5, padding=2),
35
+ nn.ReLU(inplace=True),
36
+ nn.Conv1d(128, 128, kernel_size=5, padding=2),
37
+ nn.ReLU(inplace=True),
38
+ nn.AdaptiveAvgPool1d(1),
39
+ nn.Flatten(),
40
+ nn.Linear(128, out_dim),
41
+ nn.ReLU(inplace=True),
42
+ )
43
+
44
+ def forward(self, spec: torch.Tensor) -> torch.Tensor:
45
+ # Input expected `(B, 1, F, T)`; use `(B, F, T)` for Conv1d.
46
+ x = spec.squeeze(1)
47
+ return self.net(x)
48
+
49
+
50
+ class LobeInjector(nn.Module):
51
+ """Project modality features into selected columns."""
52
+
53
+ def __init__(self, in_dim: int, num_columns: int, state_dim: int, target_columns: torch.Tensor) -> None:
54
+ super().__init__()
55
+ self.num_columns = num_columns
56
+ self.state_dim = state_dim
57
+ self.register_buffer("target_columns", target_columns.long())
58
+ out_dim = max(1, self.target_columns.numel()) * state_dim
59
+ self.project = nn.Linear(in_dim, out_dim)
60
+
61
+ def forward(self, features: torch.Tensor) -> torch.Tensor:
62
+ b = features.shape[0]
63
+ injected = features.new_zeros(b, self.num_columns, self.state_dim)
64
+ projected = self.project(features).view(b, -1, self.state_dim)
65
+ injected[:, self.target_columns, :] = projected[:, : self.target_columns.numel(), :]
66
+ return injected