ngclearn 3.2.2__tar.gz → 3.2.4__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 (192) hide show
  1. {ngclearn-3.2.2/ngclearn.egg-info → ngclearn-3.2.4}/PKG-INFO +13 -14
  2. {ngclearn-3.2.2 → ngclearn-3.2.4}/README.md +12 -13
  3. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/__init__.py +8 -0
  4. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/rateCell.py +20 -8
  5. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/__init__.py +7 -0
  6. ngclearn-3.2.4/ngclearn/components/synapses/attention/__init__.py +5 -0
  7. ngclearn-3.2.4/ngclearn/components/synapses/attention/attentionPatchedSynapse.py +295 -0
  8. ngclearn-3.2.4/ngclearn/components/synapses/attention/hebbianAttentionPatchedSynapse.py +398 -0
  9. ngclearn-3.2.4/ngclearn/components/synapses/attention/scoreAttentionPatchedSynapse.py +377 -0
  10. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/patched/__init__.py +1 -0
  11. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/patched/hebbianPatchedSynapse.py +20 -16
  12. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/patched/patchedSynapse.py +58 -31
  13. ngclearn-3.2.4/ngclearn/components/synapses/patched/scorePatchedSynapse.py +352 -0
  14. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/patched/staticPatchedSynapse.py +2 -2
  15. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/distribution_generator.py +64 -3
  16. {ngclearn-3.2.2 → ngclearn-3.2.4/ngclearn.egg-info}/PKG-INFO +13 -14
  17. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn.egg-info/SOURCES.txt +5 -0
  18. {ngclearn-3.2.2 → ngclearn-3.2.4}/pyproject.toml +1 -1
  19. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/patched/test_hebbianPatchedSynapse.py +1 -1
  20. {ngclearn-3.2.2 → ngclearn-3.2.4}/AUTHORS +0 -0
  21. {ngclearn-3.2.2 → ngclearn-3.2.4}/LICENSE +0 -0
  22. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/__init__.py +0 -0
  23. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/TTFSCell.py +0 -0
  24. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/__init__.py +0 -0
  25. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/bernoulliCell.py +0 -0
  26. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/ganglionCell.py +0 -0
  27. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/latencyCell.py +0 -0
  28. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/phasorCell.py +0 -0
  29. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/input_encoders/poissonCell.py +0 -0
  30. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/jaxComponent.py +0 -0
  31. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/__init__.py +0 -0
  32. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/__init__.py +0 -0
  33. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/bernoulliErrorCell.py +0 -0
  34. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/gaussianErrorCell.py +0 -0
  35. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/laplacianErrorCell.py +0 -0
  36. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/leakyNoiseCell.py +0 -0
  37. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/graded/rewardErrorCell.py +0 -0
  38. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/IFCell.py +0 -0
  39. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/LIFCell.py +0 -0
  40. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/LIFSRM.py +0 -0
  41. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/RAFCell.py +0 -0
  42. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/RAFSRM.py +0 -0
  43. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/WTASCell.py +0 -0
  44. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/__init__.py +0 -0
  45. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/adExCell.py +0 -0
  46. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/fitzhughNagumoCell.py +0 -0
  47. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/hodgkinHuxleyCell.py +0 -0
  48. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/izhikevichCell.py +0 -0
  49. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/quadLIFCell.py +0 -0
  50. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/neurons/spiking/sLIFCell.py +0 -0
  51. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/other/__init__.py +0 -0
  52. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/other/expKernel.py +0 -0
  53. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/other/varTrace.py +0 -0
  54. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/STPDenseSynapse.py +0 -0
  55. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/alphaSynapse.py +0 -0
  56. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/competitive/ART2ASynapse.py +0 -0
  57. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/competitive/SOMSynapse.py +0 -0
  58. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/competitive/__init__.py +0 -0
  59. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/competitive/hopfieldSynapse.py +0 -0
  60. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/competitive/vectorQuantizeSynapse.py +0 -0
  61. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/__init__.py +0 -0
  62. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/convSynapse.py +0 -0
  63. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/deconvSynapse.py +0 -0
  64. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/hebbianConvSynapse.py +0 -0
  65. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/hebbianDeconvSynapse.py +0 -0
  66. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/ngcconv.py +0 -0
  67. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/staticConvSynapse.py +0 -0
  68. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/staticDeconvSynapse.py +0 -0
  69. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/traceSTDPConvSynapse.py +0 -0
  70. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/convolution/traceSTDPDeconvSynapse.py +0 -0
  71. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/denseSynapse.py +0 -0
  72. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/doubleExpSynapse.py +0 -0
  73. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/exponentialSynapse.py +0 -0
  74. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/BCMSynapse.py +0 -0
  75. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/STDPSynapse.py +0 -0
  76. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/__init__.py +0 -0
  77. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/eventSTDPSynapse.py +0 -0
  78. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/expSTDPSynapse.py +0 -0
  79. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/gerstnerHebbianSynapse.py +0 -0
  80. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/hebbianSynapse.py +0 -0
  81. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/inhibitorySTDPSynapse.py +0 -0
  82. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/ojaTensorSynapse.py +0 -0
  83. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/hebbian/traceSTDPSynapse.py +0 -0
  84. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/modulated/MSTDPETSynapse.py +0 -0
  85. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/modulated/REINFORCESynapse.py +0 -0
  86. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/modulated/__init__.py +0 -0
  87. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/mpsSynapse.py +0 -0
  88. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/sparseTensorSynapse.py +0 -0
  89. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/staticSparseTensorSynapse.py +0 -0
  90. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/components/synapses/staticSynapse.py +0 -0
  91. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/modules/__init__.py +0 -0
  92. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/modules/regression/__init__.py +0 -0
  93. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/modules/regression/elastic_net.py +0 -0
  94. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/modules/regression/lasso.py +0 -0
  95. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/modules/regression/ridge.py +0 -0
  96. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/operations/__init__.py +0 -0
  97. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/JaxProcessesMixin.py +0 -0
  98. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/__init__.py +0 -0
  99. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/__init__.py +0 -0
  100. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/attentive_probe.py +0 -0
  101. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/effective_dim.py +0 -0
  102. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/kmeans_probe.py +0 -0
  103. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/knn_probe.py +0 -0
  104. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/linear_probe.py +0 -0
  105. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/analysis/probe.py +0 -0
  106. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/data_loader.py +0 -0
  107. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/density/__init__.py +0 -0
  108. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/density/bernoulliMixture.py +0 -0
  109. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/density/exponentialMixture.py +0 -0
  110. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/density/gaussianMixture.py +0 -0
  111. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/density/mixture.py +0 -0
  112. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/diffeq/__init__.py +0 -0
  113. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/diffeq/ode_utils.py +0 -0
  114. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/diffeq/odes.py +0 -0
  115. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/feature_dictionaries/__init__.py +0 -0
  116. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/feature_dictionaries/polynomialLibrary.py +0 -0
  117. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/filters/__init__.py +0 -0
  118. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/filters/cortical_gauss_filter.py +0 -0
  119. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/filters/gauss_filter.py +0 -0
  120. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/io_utils.py +0 -0
  121. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/masks/__init__.py +0 -0
  122. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/masks/multiblock2d.py +0 -0
  123. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/matrix_utils.py +0 -0
  124. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/metric_utils.py +0 -0
  125. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/model_utils.py +0 -0
  126. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/optim/__init__.py +0 -0
  127. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/optim/adam.py +0 -0
  128. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/optim/nag.py +0 -0
  129. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/optim/optim_utils.py +0 -0
  130. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/optim/sgd.py +0 -0
  131. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/patch.py +0 -0
  132. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/patch_utils.py +0 -0
  133. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/surrogate_fx.py +0 -0
  134. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/__init__.py +0 -0
  135. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/classification_analysis.py +0 -0
  136. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/compartment_plot.py +0 -0
  137. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/compartment_raster.py +0 -0
  138. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/dim_reduce.py +0 -0
  139. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/raster.py +0 -0
  140. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/spike_plot.py +0 -0
  141. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn/utils/viz/synapse_plot.py +0 -0
  142. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn.egg-info/dependency_links.txt +0 -0
  143. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn.egg-info/requires.txt +0 -0
  144. {ngclearn-3.2.2 → ngclearn-3.2.4}/ngclearn.egg-info/top_level.txt +0 -0
  145. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/components/input_encoders/eventSensorCell.py +0 -0
  146. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/components/input_encoders/gridCell.py +0 -0
  147. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/components/input_encoders/placeCell.py +0 -0
  148. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/components/input_encoders/populationCoderCell.py +0 -0
  149. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/components/synapses/competitive/simple_ART2ASynapse.py +0 -0
  150. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/components/synapses/hebbian/canonicalSTDPSynapse.py +0 -0
  151. {ngclearn-3.2.2 → ngclearn-3.2.4}/prototypes/utils/filters/whitening_filter.py +0 -0
  152. {ngclearn-3.2.2 → ngclearn-3.2.4}/requirements.txt +0 -0
  153. {ngclearn-3.2.2 → ngclearn-3.2.4}/setup.cfg +0 -0
  154. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/input_encoders/test_bernoulliCell.py +0 -0
  155. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/input_encoders/test_latencyCell.py +0 -0
  156. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/input_encoders/test_phasorCell.py +0 -0
  157. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/input_encoders/test_poissonCell.py +0 -0
  158. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/graded/test_RateCell.py +0 -0
  159. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/graded/test_bernoulliErrorCell.py +0 -0
  160. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/graded/test_gaussianErrorCell.py +0 -0
  161. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/graded/test_laplacianErrorCell.py +0 -0
  162. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/graded/test_leakyNoiseCell.py +0 -0
  163. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/graded/test_rewardErrorCell.py +0 -0
  164. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_IFCell.py +0 -0
  165. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_LIFCell.py +0 -0
  166. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_RAFCell.py +0 -0
  167. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_WTASCell.py +0 -0
  168. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_adExCell.py +0 -0
  169. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_fitzhughNagumoCell.py +0 -0
  170. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_hodgkinHuxleyCell.py +0 -0
  171. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_izhikevichCell.py +0 -0
  172. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_quadLIFCell.py +0 -0
  173. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/neurons/spiking/test_sLIFCell.py +0 -0
  174. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/other/test_expKernel.py +0 -0
  175. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/other/test_varTrace.py +0 -0
  176. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/competitve/test_SOMSynapse.py +0 -0
  177. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/convolution/test_hebbianConvSynapse.py +0 -0
  178. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/convolution/test_hebbianDeconvSynapse.py +0 -0
  179. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/convolution/test_traceSTDPConvSynapse.py +0 -0
  180. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/convolution/test_traceSTDPDeconvSynapse.py +0 -0
  181. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/hebbian/test_BCMSynapse.py +0 -0
  182. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/hebbian/test_eventSTDPSynapse.py +0 -0
  183. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/hebbian/test_expSTDPSynapse.py +0 -0
  184. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/hebbian/test_hebbianSynapse.py +0 -0
  185. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/hebbian/test_traceSTDPSynapse.py +0 -0
  186. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/modulated/test_MSTDPETSynapse.py +0 -0
  187. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/modulated/test_REINFORCESynapse.py +0 -0
  188. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/patched/test_patchedSynapse.py +0 -0
  189. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/test_STPDenseSynapse.py +0 -0
  190. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/test_exponentialSynapse.py +0 -0
  191. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/components/synapses/test_mpsSynapse.py +0 -0
  192. {ngclearn-3.2.2 → ngclearn-3.2.4}/tests/test___init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ngclearn
3
- Version: 3.2.2
3
+ Version: 3.2.4
4
4
  Summary: Simulation software for building and analyzing computational neuroscience models, brain-inspired computing systems, and NeuroAI agents.
5
5
  Author-email: Alexander Ororbia <ago@cs.rit.edu>, William Gebhardt <wdg1351@rit.edu>
6
6
  License-Expression: BSD-3-Clause
@@ -40,7 +40,8 @@ Dynamic: license-file
40
40
 
41
41
  [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11-blue.svg)](https://www.python.org/downloads)[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)[![Documentation Status](https://readthedocs.org/projects/ngc-learn/badge/?version=latest)](http://ngc-learn.readthedocs.io/en/latest/?badge=latest)[![DOI](https://zenodo.org/badge/483413212.svg)](https://zenodo.org/badge/latestdoi/483413212)
42
42
 
43
- <img src="docs/images/ngc-learn-logo.png" width="300">
43
+ <!-- <img src="docs/images/ngc-learn-logo.png" width="300"> -->
44
+ <img src="https://raw.githubusercontent.com/NACLab/ngc-learn/main/docs/images/ngc-learn-logo.png" width="300">
44
45
 
45
46
  <b>ngc-learn</b> is a Python library for building, simulating, and analyzing biophysical / neurobiological systems, spiking neuronal networks, predictive coding circuitry, and biomimetic (NeuroAI) agents that learn in a biologically-plausible manner. This simulation toolkit, meant to support computational neuroscience and brain-inspired computing research, is built on top of JAX and is distributed under the 3-Clause BSD license.
46
47
 
@@ -66,24 +67,22 @@ chosen as one of the <i>Editors' Highlights for Applied Physics and Mathematics<
66
67
  ### Dependencies
67
68
 
68
69
  ngc-learn requires:
69
- 1) Python (>=3.10)
70
- 2) NumPy (>=1.22.0)
71
- 3) SciPy (>=1.7.0)
70
+ 1) Python (>=3.12)
71
+ 2) NumPy (>=2.5.2)
72
+ 3) SciPy (>=1.18.1)
72
73
  4) ngcsimlib (>=3.1.1), (visit official page <a href="https://github.com/NACLab/ngc-sim-lib">here</a>)
73
- 5) JAX (>=0.4.28) (to enable GPU use, make sure to install one of the CUDA variants)
74
+ 5) JAX (>=0.11.1) (to enable GPU use, make sure to install one of the CUDA variants)
74
75
  <!--
75
- 5) scikit-learn (>=1.3.1) if using `ngclearn.utils.density`
76
- 6) matplotlib (>=3.4.3) if using `ngclearn.utils.viz`
77
76
  6) networkx (>=2.6.3) (currently optional but required if using `ngclearn.utils.experimental.viz_utils`)
78
77
  7) pyviz (>=0.2.0) (currently optional but required if using `ngclearn.utils.experimental.viz_utils`)
79
78
  -->
80
79
 
81
80
  ---
82
- ngc-learn 3.2.1 and later require Python 3.10 or newer as well as ngcsimlib >=3.1.1.
81
+ ngc-learn 3.2.4 and later require Python 3.12 or newer as well as ngcsimlib >=3.1.1.
83
82
  ngc-learn's plotting capabilities (routines within `ngclearn.utils.viz`) require
84
- Matplotlib (>=3.8.0) and imageio (>=2.31.5) and both plotting and density estimation
85
- tools (routines within ``ngclearn.utils.density``) will require Scikit-learn (>=0.24.2).
86
- Many of the tutorials will require Matplotlib (>=3.8.0), imageio (>=2.31.5), and Scikit-learn (>=0.24.2).
83
+ Matplotlib (>=3.11.1) and imageio (>=2.37.4) and both plotting and density estimation
84
+ tools (routines within ``ngclearn.utils.density``) will require Scikit-learn (>=1.9.0).
85
+ Many of the tutorials will require Matplotlib (>=3.11.1), imageio (>=2.37.4), and Scikit-learn (>=1.9.0).
87
86
 
88
87
  <i>Note</i>: If you are working with Cuda 12 and want to use jax/jaxlib versions > 0.4.28, you might need to
89
88
  check that you are working with the right version of Cudnn (e.g., `nvidia-cudnn-cu12==9.10.2.21`) to ensure
@@ -133,7 +132,7 @@ Python 3.12.13 (main, MONTH DAY YEAR, TIME) [GCC XX.X.X] on linux
133
132
  Type "help", "copyright", "credits" or "license" for more information.
134
133
  >>> import ngclearn
135
134
  >>> ngclearn.__version__
136
- '3.2.1'
135
+ '3.2.4'
137
136
  ```
138
137
 
139
138
  <i>Note:</i> For access to the previous Tensorflow-2 version of ngc-learn (of
@@ -180,7 +179,7 @@ $ python install -e .
180
179
  </pre>
181
180
 
182
181
  **Version:**<br>
183
- 3.2.2
182
+ 3.2.4
184
183
 
185
184
  Author:
186
185
  Alexander G. Ororbia II<br>
@@ -1,6 +1,7 @@
1
1
  [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11-blue.svg)](https://www.python.org/downloads)[![License](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)[![Documentation Status](https://readthedocs.org/projects/ngc-learn/badge/?version=latest)](http://ngc-learn.readthedocs.io/en/latest/?badge=latest)[![DOI](https://zenodo.org/badge/483413212.svg)](https://zenodo.org/badge/latestdoi/483413212)
2
2
 
3
- <img src="docs/images/ngc-learn-logo.png" width="300">
3
+ <!-- <img src="docs/images/ngc-learn-logo.png" width="300"> -->
4
+ <img src="https://raw.githubusercontent.com/NACLab/ngc-learn/main/docs/images/ngc-learn-logo.png" width="300">
4
5
 
5
6
  <b>ngc-learn</b> is a Python library for building, simulating, and analyzing biophysical / neurobiological systems, spiking neuronal networks, predictive coding circuitry, and biomimetic (NeuroAI) agents that learn in a biologically-plausible manner. This simulation toolkit, meant to support computational neuroscience and brain-inspired computing research, is built on top of JAX and is distributed under the 3-Clause BSD license.
6
7
 
@@ -26,24 +27,22 @@ chosen as one of the <i>Editors' Highlights for Applied Physics and Mathematics<
26
27
  ### Dependencies
27
28
 
28
29
  ngc-learn requires:
29
- 1) Python (>=3.10)
30
- 2) NumPy (>=1.22.0)
31
- 3) SciPy (>=1.7.0)
30
+ 1) Python (>=3.12)
31
+ 2) NumPy (>=2.5.2)
32
+ 3) SciPy (>=1.18.1)
32
33
  4) ngcsimlib (>=3.1.1), (visit official page <a href="https://github.com/NACLab/ngc-sim-lib">here</a>)
33
- 5) JAX (>=0.4.28) (to enable GPU use, make sure to install one of the CUDA variants)
34
+ 5) JAX (>=0.11.1) (to enable GPU use, make sure to install one of the CUDA variants)
34
35
  <!--
35
- 5) scikit-learn (>=1.3.1) if using `ngclearn.utils.density`
36
- 6) matplotlib (>=3.4.3) if using `ngclearn.utils.viz`
37
36
  6) networkx (>=2.6.3) (currently optional but required if using `ngclearn.utils.experimental.viz_utils`)
38
37
  7) pyviz (>=0.2.0) (currently optional but required if using `ngclearn.utils.experimental.viz_utils`)
39
38
  -->
40
39
 
41
40
  ---
42
- ngc-learn 3.2.1 and later require Python 3.10 or newer as well as ngcsimlib >=3.1.1.
41
+ ngc-learn 3.2.4 and later require Python 3.12 or newer as well as ngcsimlib >=3.1.1.
43
42
  ngc-learn's plotting capabilities (routines within `ngclearn.utils.viz`) require
44
- Matplotlib (>=3.8.0) and imageio (>=2.31.5) and both plotting and density estimation
45
- tools (routines within ``ngclearn.utils.density``) will require Scikit-learn (>=0.24.2).
46
- Many of the tutorials will require Matplotlib (>=3.8.0), imageio (>=2.31.5), and Scikit-learn (>=0.24.2).
43
+ Matplotlib (>=3.11.1) and imageio (>=2.37.4) and both plotting and density estimation
44
+ tools (routines within ``ngclearn.utils.density``) will require Scikit-learn (>=1.9.0).
45
+ Many of the tutorials will require Matplotlib (>=3.11.1), imageio (>=2.37.4), and Scikit-learn (>=1.9.0).
47
46
 
48
47
  <i>Note</i>: If you are working with Cuda 12 and want to use jax/jaxlib versions > 0.4.28, you might need to
49
48
  check that you are working with the right version of Cudnn (e.g., `nvidia-cudnn-cu12==9.10.2.21`) to ensure
@@ -93,7 +92,7 @@ Python 3.12.13 (main, MONTH DAY YEAR, TIME) [GCC XX.X.X] on linux
93
92
  Type "help", "copyright", "credits" or "license" for more information.
94
93
  >>> import ngclearn
95
94
  >>> ngclearn.__version__
96
- '3.2.1'
95
+ '3.2.4'
97
96
  ```
98
97
 
99
98
  <i>Note:</i> For access to the previous Tensorflow-2 version of ngc-learn (of
@@ -140,7 +139,7 @@ $ python install -e .
140
139
  </pre>
141
140
 
142
141
  **Version:**<br>
143
- 3.2.2
142
+ 3.2.4
144
143
 
145
144
  Author:
146
145
  Alexander G. Ororbia II<br>
@@ -73,5 +73,13 @@ from .synapses.modulated.REINFORCESynapse import REINFORCESynapse
73
73
  ## point to patched component types
74
74
  from .synapses.patched.patchedSynapse import PatchedSynapse
75
75
  from .synapses.patched.staticPatchedSynapse import StaticPatchedSynapse
76
+ from .synapses.patched.scorePatchedSynapse import ScorePatchedSynapse
76
77
  from .synapses.patched.hebbianPatchedSynapse import HebbianPatchedSynapse
77
78
 
79
+ ## point to attention patched synaptic components
80
+ from .synapses.attention.attentionPatchedSynapse import AttentionPatchedSynapse
81
+ from .synapses.attention.hebbianAttentionPatchedSynapse import HebbianAttentionPatchedSynapse
82
+ from .synapses.attention.scoreAttentionPatchedSynapse import ScoreAttentionPatchedSynapse
83
+
84
+
85
+
@@ -49,7 +49,6 @@ def _modulate(j, dfx_val):
49
49
  """
50
50
  return j * dfx_val
51
51
 
52
- # @partial(jit, static_argnames=["integType", "priorType"])
53
52
  def _run_cell(dt, j, j_td, z, tau_m, leak_gamma=0., integType=0, priorType=0):
54
53
  """
55
54
  Runs leaky rate-coded state dynamics one step in time.
@@ -166,7 +165,7 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
166
165
 
167
166
  use_lateral: determines wheter the RateCell uses lateral pressure during inference (Default: False)
168
167
 
169
- n_patch: the number of local patches in each layer (equivalent to n_sub_models in PatchedSynapse) (Default: 1)
168
+ n_patch: the number of local patches in each layer (equivalent to n_patch in PatchedSynapse) (Default: 1)
170
169
 
171
170
  adaptive_lateral: if True, lateral synaptic is adaptive using HebbianPatchedSynapse component,
172
171
  if False, lateral synaptic is a static using StaticPatchedSynapse component
@@ -265,7 +264,7 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
265
264
 
266
265
  if adaptive_lateral:
267
266
  self.Wl = HebbianPatchedSynapse(f"Wl_{name}", shape=(n_units, n_units),
268
- n_sub_models=n_patch,
267
+ n_patch=n_patch,
269
268
  weight_init=dist.diag_offdiag(on_diag=exc, off_diag=inh),
270
269
  eta=Wl_eta,
271
270
  prior=Wl_prior,
@@ -275,7 +274,7 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
275
274
  )
276
275
  else:
277
276
  self.Wl = StaticPatchedSynapse(f"Wl_{name}", shape=(n_units, n_units),
278
- n_sub_models=n_patch,
277
+ n_patch=n_patch,
279
278
  weight_init=dist.diag_offdiag(on_diag=exc, off_diag=inh),
280
279
  batch_size=batch_size,
281
280
  )
@@ -288,6 +287,8 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
288
287
  self.zF = Compartment(restVals, display_name="Transformed Rate Activity") # rate-coded output - activity
289
288
  self.j_td = Compartment(restVals, display_name="Modulatory Stimulus Current", units="mA") # top-down electrical current - pressure
290
289
  self.z = Compartment(restVals, display_name="Rate Activity", units="mA") # rate activity
290
+ self.mu_top = Compartment(restVals, display_name="Rate Activity", units="mA") # rate activity
291
+ self.mu_top_zF = Compartment(restVals, display_name="Transformed Rate Activity") # rate-coded output - activity
291
292
  ## lateral compartments
292
293
  if use_lateral:
293
294
  self.j_lat = Compartment(restVals, display_name="Lateral Stimulus Current", units="mA") # lateral current
@@ -309,6 +310,7 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
309
310
  j = self.j.get()
310
311
  j_td = self.j_td.get()
311
312
  z = self.z.get()
313
+ mu_top = self.mu_top.get()
312
314
 
313
315
  if self.is_stateful:
314
316
  ## ════════════════════════════════════════════════════════════════
@@ -320,7 +322,6 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
320
322
  dfx_val = self.dfx(z)
321
323
  j = _modulate(j, dfx_val)
322
324
  j = j * self.resist_scale
323
-
324
325
  ## ══════════════════════════
325
326
  ## Calculate lateral pressure
326
327
  if self.use_lateral:
@@ -355,6 +356,7 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
355
356
  ## ════════════════════════════════════════════════════════════════
356
357
  ## run in "stateless" mode (when no membrane time constant provided)
357
358
  z = _run_cell_stateless(j + j_td) ## (j+j_td) >> z
359
+ mu_top = _run_cell_stateless(mu_top)
358
360
 
359
361
  ## ═══════════════════════════════════════════════
360
362
  ## fx(z) >> zF post-activation function value(s)
@@ -363,11 +365,16 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
363
365
  zF_lat = self.fx_lat(z) * self.output_scale
364
366
 
365
367
  ## ════════════════════
368
+ mu_top_zF = self.fx(mu_top) * self.output_scale
369
+
370
+ ## ═══════════════════════════════════════════════
366
371
  ## Update compartments
367
372
  self.j.set(j)
368
373
  self.j_td.set(j_td)
369
374
  self.z.set(z)
370
375
  self.zF.set(zF)
376
+ self.mu_top.set(mu_top)
377
+ self.mu_top_zF.set(mu_top_zF)
371
378
  if self.use_lateral:
372
379
  self.j_lat.set(j_lat)
373
380
  self.zF_lat.set(zF_lat)
@@ -391,6 +398,8 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
391
398
  self.j_td.set(restVals)
392
399
  self.z.set(restVals)
393
400
  self.zF.set(restVals)
401
+ self.mu_top.set(restVals)
402
+ self.mu_top_zF.set(restVals)
394
403
 
395
404
  if self.use_lateral:
396
405
  self.Wl.reset()
@@ -417,13 +426,16 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
417
426
  "inputs":
418
427
  {"j": "External input stimulus value(s)",
419
428
  "j_td": "External top-down input stimulus value(s); these get "
420
- "multiplied by the derivative of f(x), i.e., df(x)"},
429
+ "multiplied by the derivative of f(x), i.e., df(x)",
430
+ "mu_top": "Top-down Prediction"},
421
431
  "states":
422
432
  {"z": "Update to rate-coded continuous dynamics; value at time t"},
423
433
  "outputs":
424
434
  {"zF": "Nonlinearity/function applied to rate-coded dynamics; f(z)",
425
435
  "zF_lat": "(if use_lateral is True) zF for lateral fx_lat(z)",
426
- "j_lat": "(if use_lateral is True) lateral pressure"},
436
+ "j_lat": "(if use_lateral is True) lateral pressure",
437
+ "mu_top_zF": "Nonlinearity/function applied to the top-down prediction",
438
+ },
427
439
  }
428
440
  hyperparams = {
429
441
  "n_units": "Number of neuronal cells to model in this layer",
@@ -434,7 +446,7 @@ class RateCell(JaxComponent): ## Rate-coded/real-valued cell
434
446
  "threshold": "What kind of iterative thresholding function to place over neuronal dynamics?",
435
447
  "integration_type": "Type of numerical integration to use for the cell dynamics",
436
448
  "use_lateral": "If lateral synaptic is active for inference",
437
- "n_patch": "Number of block-diagonal local lateral synaptic patch (n_sub_models of `Wl`)",
449
+ "n_patch": "Number of block-diagonal local lateral synaptic patch (n_patch of `Wl`)",
438
450
  "adaptive_lateral": "Adaptive lateral synapses (HebbianPatchedSynapse) or static lateral synaptic (StaticPatchedSynapse)",
439
451
  "Wl_eta": "Learning rate for the lateral synapses",
440
452
  "exc_inh": "(exc, inh) lateral synapses initial values. On-diagonal takes exc>0 and off-diagonal takes inh<0",
@@ -39,5 +39,12 @@ from .modulated.MSTDPETSynapse import MSTDPETSynapse
39
39
  ## patched synaptic components
40
40
  from .patched.patchedSynapse import PatchedSynapse
41
41
  from .patched.staticPatchedSynapse import StaticPatchedSynapse
42
+ from .patched.scorePatchedSynapse import ScorePatchedSynapse
42
43
  from .patched.hebbianPatchedSynapse import HebbianPatchedSynapse
43
44
 
45
+ ## attention patched synaptic components
46
+ from .attention.attentionPatchedSynapse import AttentionPatchedSynapse
47
+ from .attention.hebbianAttentionPatchedSynapse import HebbianAttentionPatchedSynapse
48
+ from .attention.scoreAttentionPatchedSynapse import ScoreAttentionPatchedSynapse
49
+
50
+
@@ -0,0 +1,5 @@
1
+ ## attention patched synaptic components
2
+ from .attentionPatchedSynapse import AttentionPatchedSynapse
3
+ from .hebbianAttentionPatchedSynapse import HebbianAttentionPatchedSynapse
4
+ from .scoreAttentionPatchedSynapse import ScoreAttentionPatchedSynapse
5
+
@@ -0,0 +1,295 @@
1
+ # %%
2
+ from jax import random, numpy as jnp, nn
3
+ from ngclearn.components.jaxComponent import JaxComponent
4
+ from ngclearn.utils.distribution_generator import DistributionGenerator
5
+ from ngcsimlib.logger import info
6
+ from ngclearn import compilable, Compartment
7
+
8
+ def _create_attention_synapses(key, shape, n_patch, use_value=True, init_type=DistributionGenerator.fan_in_gaussian()):
9
+ key, *subkey = random.split(key, 10)
10
+
11
+ patch_shape = (shape[0] // n_patch, shape[1] // n_patch)
12
+ di, dj = patch_shape
13
+ n_weight = 3 if use_value else 2 ## synapses: query, key, value (optional)
14
+
15
+ weight_shape = (di, n_weight * dj)
16
+ weights = jnp.zeros(weight_shape)
17
+ w_masks = jnp.zeros(weight_shape)
18
+
19
+ for i in range(n_weight): ## W = (Wq, Wk, Wv)
20
+ start_j = i * dj
21
+ end_j = (i + 1) * dj
22
+
23
+ weights = weights.at[:, start_j : end_j].set(init_type(patch_shape, subkey[i]))
24
+ w_masks = w_masks.at[:, start_j : end_j].set(jnp.ones(patch_shape))
25
+
26
+ return weights, patch_shape, w_masks
27
+
28
+ def _split_heads(t, n_heads):
29
+ """
30
+ (batch_size, n_patch, d) -> (batch_size, n_heads, n_patch, d / n_heads)
31
+ """
32
+ return t.reshape(t.shape[0], t.shape[1], n_heads, -1).transpose(0, 2, 1, 3)
33
+
34
+ def _merge_heads(t):
35
+ """
36
+ (batch_size, n_heads, n_patch, d / n_heads) -> (batch_size, n_patch, d)
37
+ """
38
+ return t.transpose(0, 2, 1, 3).reshape(t.shape[0], t.shape[2], -1)
39
+
40
+ def _attend(inputs, W, b, n_patch, n_heads=1, use_value=True):
41
+ """
42
+ (zF W + b) -> y = softmax(q k.T / sqrt(d_h)) v
43
+ """
44
+ zF = inputs.reshape(inputs.shape[0], n_patch, -1) ## (B, n, d)
45
+ q_k_v = (zF @ W) + b ## q_k_v: (B, n, d)
46
+
47
+ if use_value:
48
+ q, k, v = jnp.split(q_k_v, 3, axis=2) ## q, k v projections of every patch
49
+ else:
50
+ q, k = jnp.split(q_k_v, 2, axis=2) ## v = zF
51
+ v = zF
52
+
53
+ q = _split_heads(q, n_heads) ## Reshape: (B, n, d) -> (B, H, n, d/H)
54
+ k = _split_heads(k, n_heads) ## Reshape: (B, n, d) -> (_, H, _, d/H)
55
+ v = _split_heads(v, n_heads) ## Reshape: (B, n, d) -> (_, H, _, d/H)
56
+ ## attention score
57
+ rd = jnp.sqrt(q.shape[3])
58
+ s = (q @ k.transpose(0, 1, 3, 2)) / rd ## (B, H, n, d/H) @ (B, H, d/H, n)
59
+ ## probability
60
+ A = nn.softmax(s, axis=-1)
61
+ y = _merge_heads(A @ v) ## Reshape.T: (B, H, n, d/H) -> (B, n, d)
62
+ return y.reshape(y.shape[0], -1), (zF, q, k, v, s, A)
63
+
64
+ def _attend_backward(e, attention_params, n_heads=1):
65
+ """
66
+ d_qkv = (chain rule through softmax(q k.T / sqrt(d_h)) v)
67
+ Passes a post-synaptic signal back through the attention mixing to the (q, k, v) projections of every patch
68
+ """
69
+ zF, q, k, v, s, A = attention_params
70
+ rd = jnp.sqrt(q.shape[3])
71
+ e = _split_heads(e.reshape(e.shape[0], zF.shape[1], -1), n_heads) ## Reshape: (B, n, d) -> (_, H, _, d/H)
72
+ dv = A.transpose(0, 1, 3, 2) @ e
73
+ dA = e @ v.transpose(0, 1, 3, 2)
74
+ dS = A * (dA - jnp.sum(dA * A, axis=-1, keepdims=True)) / rd
75
+ dq = dS @ k
76
+ dk = dS.transpose(0, 1, 3, 2) @ q
77
+ return jnp.concatenate([_merge_heads(dq), ## Reshape.T: (B, H, n, d/H) -> (B, n, d)
78
+ _merge_heads(dk), ## Reshape.T: (B, H, n, d/H) -> (B, n, d)
79
+ _merge_heads(dv)], ## Reshape.T: (B, H, n, d/H) -> (B, n, d)
80
+ axis=2)
81
+
82
+ def _backtransmit(e, attention_params, W, n_heads=1, use_value=True):
83
+ """
84
+ pre_out = dq * Wq.T + dk * Wk.T + dv (v = zF) (chain rule through the weights)
85
+ """
86
+ d_qkv = _attend_backward(e, attention_params, n_heads)
87
+ dzF = d_qkv[:, :, 0:W.shape[1]] @ W.T
88
+ if not use_value: ## (v = zF): the value signal passes straight back
89
+ dzF = dzF + d_qkv[:, :, W.shape[1]:]
90
+ return dzF.reshape(dzF.shape[0], -1)
91
+
92
+ class AttentionPatchedSynapse(JaxComponent): ## base attention patched synaptic cable
93
+ """
94
+ A patched self-attention synaptic cable that lets the patches (tokens) of a layer attend to one another, i.e., it
95
+ transforms inputs via multi-head self-attention through a single set of query, key, and value synapses that is
96
+ shared by every patch, no form of synaptic evolution/adaptation is in-built to this component.
97
+
98
+ | --- Synapse Compartments: ---
99
+ | inputs - input (takes in external signals)
100
+ | outputs - output signals (transformation induced by synapses)
101
+ | project_input - input of the projection pathway (takes in external signals)
102
+ | project_output - output signals of the projection pathway (transformation induced by synapses)
103
+ | post_in - post-synaptic input of the backward pathway (takes in external signals)
104
+ | pre_out - pre-synaptic output signals of the backward pathway (post_in carried back across the synapses)
105
+ | weights - current value matrix of synaptic efficacies, the query, key, and value synapses W = (Wq, Wk, Wv)
106
+ | biases - current value vector of synaptic bias values, b = (bq, bk, bv)
107
+ | key - JAX PRNG key
108
+
109
+ Args:
110
+ name: the string name of this cell
111
+
112
+ shape: tuple specifying shape of this synaptic cable (usually a 2-tuple
113
+ with number of inputs by number of outputs), every patch gets
114
+ shape[0] / n_patch input and shape[1] / n_patch output
115
+ features (these must be equal if use_value=False)
116
+
117
+ n_patch: The number of patches (tokens) in each layer (Default: 1)
118
+
119
+ n_heads: The number of attention heads, each head attends over
120
+ (shape[1] / n_patch) / n_heads features (Default: 1)
121
+
122
+ use_value: if False, the value synapses are fixed to the identity (v = zF)
123
+ and are left out of `weights`, i.e., W = (Wq, Wk) (Default: True)
124
+
125
+ weight_init: a kernel to drive initialization of this synaptic cable's values;
126
+ typically a tuple with 1st element as a string calling the name of
127
+ initialization to use
128
+
129
+ bias_init: a kernel to drive initialization of biases for this synaptic cable
130
+ (Default: None, which turns off/disables biases)
131
+
132
+ resist_scale: a fixed scaling factor to apply to synaptic transform
133
+ (Default: 1.), i.e., yields: out = attention(in; W, b) * Rscale
134
+
135
+ p_conn: probability of a connection existing (default: 1.); setting
136
+ this to < 1. will result in a sparser synaptic structure
137
+
138
+ batch_size: the size of each mini batch
139
+ """
140
+
141
+ def __init__(self, name, shape, n_patch=1, n_heads=1, use_value=True, weight_init=None, bias_init=None,
142
+ resist_scale=1., p_conn=1., batch_size=1, **kwargs
143
+ ):
144
+ super().__init__(name, **kwargs)
145
+
146
+ self.Rscale = resist_scale
147
+ self.batch_size = batch_size
148
+ self.weight_init = weight_init
149
+ self.bias_init = bias_init
150
+
151
+ self.n_patch = n_patch
152
+ self.n_heads = n_heads
153
+ self.use_value = use_value
154
+
155
+ tmp_key, *subkeys = random.split(self.key.get(), 4)
156
+ if self.weight_init is None:
157
+ info(self.name, "is using default weight initializer!")
158
+ self.weight_init = DistributionGenerator.fan_in_gaussian()
159
+
160
+ weights, self.patch_shape, self.w_masks = _create_attention_synapses(
161
+ key=tmp_key, shape=shape, n_patch=self.n_patch, use_value=self.use_value,
162
+ init_type=self.weight_init
163
+ )
164
+
165
+ self.shape = shape ## input x output same for all weights (Wq, Wk, Wv)
166
+
167
+ if 0. < p_conn < 1.: ## only non-zero and <1 probs allowed
168
+ mask = random.bernoulli(subkeys[1], p=p_conn, shape=weights.shape)
169
+ weights = weights * mask ## sparsify matrix
170
+
171
+ ## Compartment setup
172
+ self.weights = Compartment(weights)
173
+
174
+ preVals = jnp.zeros((self.batch_size, self.shape[0]))
175
+ postVals = jnp.zeros((self.batch_size, self.shape[1]))
176
+
177
+ self.inputs = Compartment(preVals)
178
+ self.outputs = Compartment(postVals)
179
+
180
+ self.project_input = Compartment(preVals)
181
+ self.project_output = Compartment(postVals)
182
+
183
+ self.post_in = Compartment(postVals)
184
+ self.pre_out = Compartment(preVals)
185
+
186
+ ## Set up (optional) bias values
187
+ if self.bias_init is None:
188
+ info(self.name, "is using default bias value of zero (no bias kernel provided)!")
189
+ self.biases = Compartment(self.bias_init((1, weights.shape[1]), subkeys[2]) if bias_init else 0.0)
190
+
191
+ @compilable
192
+ def advance_state(self):
193
+ # Get the variables
194
+ weights = self.weights.get()
195
+ biases = self.biases.get()
196
+
197
+ ################### inputs → attention(W)= A @ v → outputs
198
+ inputs = self.inputs.get() ## zF
199
+ ## Compute (zF @ W) -> softmax(q k.T / sqrt(d_h)) v
200
+ outputs, attention_params = _attend(inputs, weights, biases, self.n_patch, self.n_heads, self.use_value)
201
+ _, q, k, v, s, A = attention_params
202
+ outputs = outputs * self.Rscale
203
+ ## Update outputs compartment
204
+ self.outputs.set(outputs)
205
+
206
+
207
+ ################### post_in → (d_qkv @ W.T) → pre_out
208
+ post_in = self.post_in.get()
209
+ ## Compute attention(post_in, W.T)
210
+ pre_out = _backtransmit(post_in, attention_params, weights, self.n_heads, self.use_value)
211
+ ## Update pre_out compartment
212
+ self.pre_out.set(pre_out)
213
+
214
+
215
+ ################### project_input → attention(W) → project_output
216
+ project_input = self.project_input.get()
217
+ ## Compute attention(project_input, W)
218
+ project_output, _ = _attend(project_input, weights, biases, self.n_patch, self.n_heads, self.use_value)
219
+ project_output = project_output * self.Rscale
220
+ ## Update project_output compartment
221
+ self.project_output.set(project_output)
222
+
223
+ @compilable
224
+ def reset(self): ## closed, no-batch argument reset
225
+ ## write reset command to call inner batched_reset command
226
+ self.batched_reset(batch_size=self.batch_size) ## arg = batch_size data-member
227
+
228
+ @compilable
229
+ def batched_reset(self, batch_size): ## open, batch argument reset
230
+ preVals = jnp.zeros((batch_size, self.shape[0]))
231
+ postVals = jnp.zeros((batch_size, self.shape[1]))
232
+
233
+ # BUG: the self.inputs here does not have the targeted field
234
+ # NOTE: Quick workaround is to check if targeted is in the input or not
235
+ hasattr(self.inputs, "targeted") and not self.inputs.targeted and self.inputs.set(preVals)
236
+ self.outputs.set(postVals)
237
+ self.post_in.set(postVals)
238
+ self.pre_out.set(preVals)
239
+ self.project_input.set(preVals)
240
+ self.project_output.set(postVals)
241
+
242
+ @classmethod
243
+ def help(cls): ## component help function
244
+ properties = {
245
+ "synapse_type": "AttentionPatchedSynapse - performs a synaptic transformation "
246
+ "of inputs to produce output signals (e.g., a multi-head "
247
+ "self-attention transformation across the patches of a layer)"
248
+ }
249
+ compartment_props = {
250
+ "inputs":
251
+ {"inputs": "Takes in external input signal values",
252
+ "project_input": "Takes in external input signal values",
253
+ "post_in": "Takes in external input signal values",
254
+ },
255
+ "states":
256
+ {"weights": "Synapse efficacy/strength parameter values (query, key, and value synapses)",
257
+ "biases": "Base-rate/bias parameter values (query, key, and value biases)",
258
+ "key": "JAX PRNG key"},
259
+ "outputs":
260
+ {"outputs": "Output of synaptic transformation",
261
+ "project_output": "Output of synaptic transformation",
262
+ "pre_out": "Output of synaptic transformation",
263
+ },
264
+ }
265
+ hyperparams = {
266
+ "shape": "Overall shape of synaptic cable, number inputs x number outputs",
267
+ "n_patch": "The number of patches (tokens) in each layer",
268
+ "n_heads": "The number of attention heads",
269
+ "use_value": "Are the value synapses adaptive? (otherwise, they are fixed to the identity)",
270
+ "batch_size": "Batch size dimension of this component",
271
+ "weight_init": "Initialization conditions for synaptic weight (W) values",
272
+ "bias_init": "Initialization conditions for bias/base-rate (b) values",
273
+ "resist_scale": "Resistance level scaling factor (Rscale), applied to output of transformation",
274
+ "w_masks": "weight mask matrix",
275
+ "p_conn": "Probability of a connection existing (otherwise, it is masked to zero)"
276
+ }
277
+ info = {cls.__name__: properties,
278
+ "compartments": compartment_props,
279
+ "dynamics": "outputs = [softmax((inputs * Wq + bq) * (inputs * Wk + bk).T / sqrt(d)) * (inputs * Wv + bv)] * Rscale",
280
+ "hyperparameters": hyperparams}
281
+ return info
282
+
283
+ if __name__ == '__main__':
284
+ from ngcsimlib.context import Context
285
+
286
+ with Context("Bar") as bar:
287
+ Wab = AttentionPatchedSynapse("Wab", (9, 9), 3)
288
+ print(Wab)
289
+
290
+
291
+
292
+
293
+
294
+
295
+