physioex 2.0.1__tar.gz → 2.0.2__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 (308) hide show
  1. {physioex-2.0.1 → physioex-2.0.2}/CHANGELOG.md +12 -0
  2. {physioex-2.0.1 → physioex-2.0.2}/PKG-INFO +14 -2
  3. {physioex-2.0.1 → physioex-2.0.2}/README.md +13 -1
  4. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/explain/explain.md +6 -0
  5. physioex-2.0.2/physioex/__init__.py +1 -0
  6. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/protosleepnet.py +16 -6
  7. physioex-2.0.2/tests/test_modality_dropout.py +62 -0
  8. physioex-2.0.1/physioex/__init__.py +0 -1
  9. {physioex-2.0.1 → physioex-2.0.2}/.claudeignore +0 -0
  10. {physioex-2.0.1 → physioex-2.0.2}/.github/copilot-instructions.md +0 -0
  11. {physioex-2.0.1 → physioex-2.0.2}/.github/workflows/black.yml +0 -0
  12. {physioex-2.0.1 → physioex-2.0.2}/.github/workflows/ci.yml +0 -0
  13. {physioex-2.0.1 → physioex-2.0.2}/.github/workflows/publish.yaml +0 -0
  14. {physioex-2.0.1 → physioex-2.0.2}/.github/workflows/test.yml +0 -0
  15. {physioex-2.0.1 → physioex-2.0.2}/.gitignore +0 -0
  16. {physioex-2.0.1 → physioex-2.0.2}/LICENSE +0 -0
  17. {physioex-2.0.1 → physioex-2.0.2}/MANIFEST.in +0 -0
  18. {physioex-2.0.1 → physioex-2.0.2}/REPO_MAP.txt +0 -0
  19. {physioex-2.0.1 → physioex-2.0.2}/docs/_ext/related_works.py +0 -0
  20. {physioex-2.0.1 → physioex-2.0.2}/docs/_static/custom.css +0 -0
  21. {physioex-2.0.1 → physioex-2.0.2}/docs/api/index.md +0 -0
  22. {physioex-2.0.1 → physioex-2.0.2}/docs/assets/images/data/sequence_viz.png +0 -0
  23. {physioex-2.0.1 → physioex-2.0.2}/docs/assets/images/logo.psd +0 -0
  24. {physioex-2.0.1 → physioex-2.0.2}/docs/assets/images/logo.svg +0 -0
  25. {physioex-2.0.1 → physioex-2.0.2}/docs/assets/images/logo_bar.svg +0 -0
  26. {physioex-2.0.1 → physioex-2.0.2}/docs/conf.py +0 -0
  27. {physioex-2.0.1 → physioex-2.0.2}/docs/index.md +0 -0
  28. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/architecture/library/data.md +0 -0
  29. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/architecture/library/explain.md +0 -0
  30. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/architecture/library/models.md +0 -0
  31. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/architecture/library/overview.md +0 -0
  32. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/architecture/library/train.md +0 -0
  33. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/architecture/testing/overview.md +0 -0
  34. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/contribute.md +0 -0
  35. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/data.md +0 -0
  36. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/preprocess.md +0 -0
  37. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/train/cli.md +0 -0
  38. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/train/networks/chambon2018.md +0 -0
  39. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/train/networks.md +0 -0
  40. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/train/train.md +0 -0
  41. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/unavailable.md +0 -0
  42. {physioex-2.0.1 → physioex-2.0.2}/docs/pages/user_guide.md +0 -0
  43. {physioex-2.0.1 → physioex-2.0.2}/docs/related/_thumbs/_placeholder.svg +0 -0
  44. {physioex-2.0.1 → physioex-2.0.2}/docs/related/fetch_citations.py +0 -0
  45. {physioex-2.0.1 → physioex-2.0.2}/docs/related/index.md +0 -0
  46. {physioex-2.0.1 → physioex-2.0.2}/docs/related/works.yaml +0 -0
  47. {physioex-2.0.1 → physioex-2.0.2}/examples/__init__.py +0 -0
  48. {physioex-2.0.1 → physioex-2.0.2}/examples/analyze_csd_concepts/__init__.py +0 -0
  49. {physioex-2.0.1 → physioex-2.0.2}/examples/analyze_csd_concepts/compare_strategies.py +0 -0
  50. {physioex-2.0.1 → physioex-2.0.2}/examples/analyze_csd_concepts/extract_all_concepts.py +0 -0
  51. {physioex-2.0.1 → physioex-2.0.2}/examples/analyze_csd_concepts/report.py +0 -0
  52. {physioex-2.0.1 → physioex-2.0.2}/examples/analyze_csd_concepts/utils.py +0 -0
  53. {physioex-2.0.1 → physioex-2.0.2}/examples/analyze_csd_concepts/visualize_concepts.py +0 -0
  54. {physioex-2.0.1 → physioex-2.0.2}/examples/explain/conceptualspectraldecomposition/README.md +0 -0
  55. {physioex-2.0.1 → physioex-2.0.2}/examples/explain/conceptualspectraldecomposition/explain_csd.py +0 -0
  56. {physioex-2.0.1 → physioex-2.0.2}/examples/explain/conceptualspectraldecomposition/train_probe.py +0 -0
  57. {physioex-2.0.1 → physioex-2.0.2}/examples/explain/conceptualspectraldecomposition/utils.py +0 -0
  58. {physioex-2.0.1 → physioex-2.0.2}/examples/explain/conceptualspectraldecomposition/visualize.py +0 -0
  59. {physioex-2.0.1 → physioex-2.0.2}/examples/explain/lrp_seqsleepnet_n3.py +0 -0
  60. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/bendr/extract_embeddings.py +0 -0
  61. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/biot/extract_embeddings.py +0 -0
  62. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/cbramod/extract_embeddings.py +0 -0
  63. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/labram/extract_embeddings.py +0 -0
  64. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/neurolm/extract_embeddings.py +0 -0
  65. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/reve/extract_embeddings.py +0 -0
  66. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/sjepa/extract_embeddings.py +0 -0
  67. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/sleepfm/extract_embeddings.py +0 -0
  68. {physioex-2.0.1 → physioex-2.0.2}/examples/foundation/tfc/extract_embeddings.py +0 -0
  69. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/extract_embeddings.py +0 -0
  70. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/extract_embeddings.sbatch +0 -0
  71. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/quickstart.py +0 -0
  72. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/smoke.sbatch +0 -0
  73. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/test_pretrained.py +0 -0
  74. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/train.py +0 -0
  75. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/chambon2018/train.sbatch +0 -0
  76. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/coresleep-kontras/extract_embeddings.py +0 -0
  77. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/coresleep-kontras/train.py +0 -0
  78. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/extract_embeddings.py +0 -0
  79. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/quickstart.py +0 -0
  80. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/smoke.sbatch +0 -0
  81. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/test_pretrained.py +0 -0
  82. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/test_pretrained.sbatch +0 -0
  83. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/train.py +0 -0
  84. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/lseqsleepnet-phan/train.sbatch +0 -0
  85. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/protosleepnet/README.md +0 -0
  86. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/protosleepnet/quickstart.py +0 -0
  87. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/extract_embeddings.py +0 -0
  88. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/extract_embeddings.sbatch +0 -0
  89. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/quickstart.py +0 -0
  90. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/test.py +0 -0
  91. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/test_pretrained.py +0 -0
  92. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/test_pretrained.sbatch +0 -0
  93. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/test_stages_sites.py +0 -0
  94. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/train.py +0 -0
  95. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/train.sbatch +0 -0
  96. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/train_shhs.py +0 -0
  97. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/seqsleepnet-phan/train_shhs.sbatch +0 -0
  98. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/extract_embeddings.py +0 -0
  99. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/extract_embeddings.sbatch +0 -0
  100. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/quickstart.py +0 -0
  101. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/smoke.sbatch +0 -0
  102. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/test_pretrained.py +0 -0
  103. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/test_pretrained.sbatch +0 -0
  104. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/train.py +0 -0
  105. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/sleeptransformer-phan/train.sbatch +0 -0
  106. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/extract_embeddings.py +0 -0
  107. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/extract_embeddings.sbatch +0 -0
  108. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/quickstart.py +0 -0
  109. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/smoke.sbatch +0 -0
  110. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/test_pretrained.py +0 -0
  111. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/test_pretrained.sbatch +0 -0
  112. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/train.py +0 -0
  113. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tinysleepnet-supratak/train.sbatch +0 -0
  114. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tsinalis-2016/extract_embeddings.py +0 -0
  115. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tsinalis-2016/quickstart.py +0 -0
  116. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tsinalis-2016/smoke.sbatch +0 -0
  117. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tsinalis-2016/test_pretrained.py +0 -0
  118. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tsinalis-2016/train.py +0 -0
  119. {physioex-2.0.1 → physioex-2.0.2}/examples/pretrained/tsinalis-2016/train.sbatch +0 -0
  120. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/notebook.ipynb +0 -0
  121. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell11_tiny_barplot.png +0 -0
  122. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell11_tiny_hypnogram.png +0 -0
  123. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell13_seq_barplot.png +0 -0
  124. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell13_seq_hypnogram.png +0 -0
  125. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell17_ig_tiny.png +0 -0
  126. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell19_ig_seq.png +0 -0
  127. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell19b_attr_vs_psd.png +0 -0
  128. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell5_raw_n3_psd.png +0 -0
  129. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/outputs/cell7_spec_n3_psd.png +0 -0
  130. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/run_notebook.py +0 -0
  131. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/script.pdf +0 -0
  132. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/slides.pdf +0 -0
  133. {physioex-2.0.1 → physioex-2.0.2}/lectures/2026-06-24_ugent_xai/util.py +0 -0
  134. {physioex-2.0.1 → physioex-2.0.2}/lectures/README.md +0 -0
  135. {physioex-2.0.1 → physioex-2.0.2}/lectures/assets/kuleuven_logo.png +0 -0
  136. {physioex-2.0.1 → physioex-2.0.2}/lectures/assets/physioex_logo.png +0 -0
  137. {physioex-2.0.1 → physioex-2.0.2}/lectures/assets/physioex_logo.svg +0 -0
  138. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/__init__.py +0 -0
  139. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/base.py +0 -0
  140. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/cache.py +0 -0
  141. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/collate.py +0 -0
  142. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datareader.py +0 -0
  143. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/dataset.py +0 -0
  144. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/__init__.py +0 -0
  145. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/_nsrr.py +0 -0
  146. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/_splits/shhs.json +0 -0
  147. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/alzheimers.py +0 -0
  148. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/channels_table.md +0 -0
  149. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/dcsm.py +0 -0
  150. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/hmc.py +0 -0
  151. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/hpap.py +0 -0
  152. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/mass.py +0 -0
  153. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/mesa.py +0 -0
  154. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/mros.py +0 -0
  155. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/parkinsons.py +0 -0
  156. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/shhs.py +0 -0
  157. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/sleepedf.py +0 -0
  158. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/stages.py +0 -0
  159. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/datasets/wsc.py +0 -0
  160. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/events.py +0 -0
  161. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/modality.py +0 -0
  162. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/multi.py +0 -0
  163. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/pipeline.py +0 -0
  164. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/presets.py +0 -0
  165. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/readers/__init__.py +0 -0
  166. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/readers/annotations.py +0 -0
  167. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/readers/edf.py +0 -0
  168. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/__init__.py +0 -0
  169. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/bandpass.py +0 -0
  170. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/highpass.py +0 -0
  171. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/identity.py +0 -0
  172. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/normalize.py +0 -0
  173. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/notch.py +0 -0
  174. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/resample.py +0 -0
  175. {physioex-2.0.1 → physioex-2.0.2}/physioex/data/steps/spectrogram.py +0 -0
  176. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/__init__.py +0 -0
  177. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/foundational/__init__.py +0 -0
  178. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/foundational/csd.py +0 -0
  179. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/foundational/multichannel_sg.py +0 -0
  180. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/foundational/report.py +0 -0
  181. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/foundational/sleep_bands.py +0 -0
  182. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/foundational/specificity.py +0 -0
  183. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/__init__.py +0 -0
  184. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/_functional.py +0 -0
  185. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/_rules.py +0 -0
  186. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/attributor.py +0 -0
  187. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/canonizers.py +0 -0
  188. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/composites.py +0 -0
  189. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/diagnostics.py +0 -0
  190. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/model.py +0 -0
  191. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/pooling.py +0 -0
  192. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/recurrent.py +0 -0
  193. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/lrp/transformer.py +0 -0
  194. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/__init__.py +0 -0
  195. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/filters.py +0 -0
  196. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/functionizer.py +0 -0
  197. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/gradients.py +0 -0
  198. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/metrics/__init__.py +0 -0
  199. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/spectralgradients.py +0 -0
  200. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/vidft.py +0 -0
  201. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/posthoc/vistdft.py +0 -0
  202. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/__init__.py +0 -0
  203. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/local.py +0 -0
  204. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/posthoc/__init__.py +0 -0
  205. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/posthoc/nmf.py +0 -0
  206. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/posthoc/utils.py +0 -0
  207. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/posthoc/vq.py +0 -0
  208. {physioex-2.0.1 → physioex-2.0.2}/physioex/explain/prototypes/reconstruct.py +0 -0
  209. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/__init__.py +0 -0
  210. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/bendr.py +0 -0
  211. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/biot.py +0 -0
  212. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/cbramod.py +0 -0
  213. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/chambon2018.py +0 -0
  214. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/coresleep.py +0 -0
  215. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/embed.py +0 -0
  216. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/foundation_base.py +0 -0
  217. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/foundation_channel_mapping.py +0 -0
  218. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/foundation_checkpoints.py +0 -0
  219. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/foundation_datasets.py +0 -0
  220. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/foundation_preproc.py +0 -0
  221. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/labram.py +0 -0
  222. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/lseqsleepnet.py +0 -0
  223. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/neurolm.py +0 -0
  224. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/pretrained.py +0 -0
  225. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/reve.py +0 -0
  226. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/seqsleepnet.py +0 -0
  227. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/sjepa.py +0 -0
  228. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/sleep_tokenizer.py +0 -0
  229. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/sleepfm.py +0 -0
  230. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/sleeptransformer.py +0 -0
  231. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/tfc.py +0 -0
  232. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/tinysleepnet.py +0 -0
  233. {physioex-2.0.1 → physioex-2.0.2}/physioex/models/tsinalis.py +0 -0
  234. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/__init__.py +0 -0
  235. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/bin/__init__.py +0 -0
  236. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/bin/_common.py +0 -0
  237. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/bin/finetune.py +0 -0
  238. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/bin/test.py +0 -0
  239. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/bin/train.py +0 -0
  240. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/logger.py +0 -0
  241. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/metrics.py +0 -0
  242. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/models/__init__.py +0 -0
  243. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/models/check_table.csv +0 -0
  244. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/models/load.py +0 -0
  245. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/multidevicetrainer.py +0 -0
  246. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/progress.py +0 -0
  247. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/stats.py +0 -0
  248. {physioex-2.0.1 → physioex-2.0.2}/physioex/train/trainer.py +0 -0
  249. {physioex-2.0.1 → physioex-2.0.2}/pyproject.toml +0 -0
  250. {physioex-2.0.1 → physioex-2.0.2}/tests/__init__.py +0 -0
  251. {physioex-2.0.1 → physioex-2.0.2}/tests/conftest.py +0 -0
  252. {physioex-2.0.1 → physioex-2.0.2}/tests/data/test_base_smoke.py +0 -0
  253. {physioex-2.0.1 → physioex-2.0.2}/tests/data/test_modality.py +0 -0
  254. {physioex-2.0.1 → physioex-2.0.2}/tests/data/test_multi.py +0 -0
  255. {physioex-2.0.1 → physioex-2.0.2}/tests/data/test_readers_annotations.py +0 -0
  256. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/foundational/test_sleep_bands.py +0 -0
  257. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/foundational/test_specificity.py +0 -0
  258. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/__init__.py +0 -0
  259. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/test_functional.py +0 -0
  260. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/test_lrp.py +0 -0
  261. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/test_model.py +0 -0
  262. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/test_real_models.py +0 -0
  263. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/test_recurrent.py +0 -0
  264. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/lrp/test_transformer.py +0 -0
  265. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/posthoc/__init__.py +0 -0
  266. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/posthoc/test_gradients.py +0 -0
  267. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/posthoc/test_metrics.py +0 -0
  268. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/posthoc/test_spectralgradients.py +0 -0
  269. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/posthoc/test_vidft.py +0 -0
  270. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/posthoc/test_vistdft.py +0 -0
  271. {physioex-2.0.1 → physioex-2.0.2}/tests/explain/prototypes/posthoc/test_nmf_vq.py +0 -0
  272. {physioex-2.0.1 → physioex-2.0.2}/tests/factories/__init__.py +0 -0
  273. {physioex-2.0.1 → physioex-2.0.2}/tests/factories/edf.py +0 -0
  274. {physioex-2.0.1 → physioex-2.0.2}/tests/models/test_architectures.py +0 -0
  275. {physioex-2.0.1 → physioex-2.0.2}/tests/models/test_foundation_base.py +0 -0
  276. {physioex-2.0.1 → physioex-2.0.2}/tests/models/test_foundation_encoders.py +0 -0
  277. {physioex-2.0.1 → physioex-2.0.2}/tests/models/test_foundation_preproc.py +0 -0
  278. {physioex-2.0.1 → physioex-2.0.2}/tests/models/test_pretrained_embed_helpers.py +0 -0
  279. {physioex-2.0.1 → physioex-2.0.2}/tests/models/test_sleep_tokenizer.py +0 -0
  280. {physioex-2.0.1 → physioex-2.0.2}/tests/test_alzheimers_parkinsons.py +0 -0
  281. {physioex-2.0.1 → physioex-2.0.2}/tests/test_api_surface.py +0 -0
  282. {physioex-2.0.1 → physioex-2.0.2}/tests/test_cache.py +0 -0
  283. {physioex-2.0.1 → physioex-2.0.2}/tests/test_cache_enabled.py +0 -0
  284. {physioex-2.0.1 → physioex-2.0.2}/tests/test_channel_resolution.py +0 -0
  285. {physioex-2.0.1 → physioex-2.0.2}/tests/test_cli_workflows.py +0 -0
  286. {physioex-2.0.1 → physioex-2.0.2}/tests/test_dataset_config.py +0 -0
  287. {physioex-2.0.1 → physioex-2.0.2}/tests/test_e2e_smoke.py +0 -0
  288. {physioex-2.0.1 → physioex-2.0.2}/tests/test_events.py +0 -0
  289. {physioex-2.0.1 → physioex-2.0.2}/tests/test_explain_fixes.py +0 -0
  290. {physioex-2.0.1 → physioex-2.0.2}/tests/test_label_hardening.py +0 -0
  291. {physioex-2.0.1 → physioex-2.0.2}/tests/test_load_model.py +0 -0
  292. {physioex-2.0.1 → physioex-2.0.2}/tests/test_mass_dataset.py +0 -0
  293. {physioex-2.0.1 → physioex-2.0.2}/tests/test_metrics_and_packaging.py +0 -0
  294. {physioex-2.0.1 → physioex-2.0.2}/tests/test_phase_b_datasets.py +0 -0
  295. {physioex-2.0.1 → physioex-2.0.2}/tests/test_phase_c_datasets.py +0 -0
  296. {physioex-2.0.1 → physioex-2.0.2}/tests/test_pipeline.py +0 -0
  297. {physioex-2.0.1 → physioex-2.0.2}/tests/test_presets.py +0 -0
  298. {physioex-2.0.1 → physioex-2.0.2}/tests/test_raw_dataset_integration.py +0 -0
  299. {physioex-2.0.1 → physioex-2.0.2}/tests/test_reading_modes.py +0 -0
  300. {physioex-2.0.1 → physioex-2.0.2}/tests/test_stages_dataset.py +0 -0
  301. {physioex-2.0.1 → physioex-2.0.2}/tests/test_trainer_enhancements.py +0 -0
  302. {physioex-2.0.1 → physioex-2.0.2}/tests/test_trainer_fixes.py +0 -0
  303. {physioex-2.0.1 → physioex-2.0.2}/tests/test_trainer_integration.py +0 -0
  304. {physioex-2.0.1 → physioex-2.0.2}/tests/test_wake_trimming.py +0 -0
  305. {physioex-2.0.1 → physioex-2.0.2}/tests/test_wsc_dataset.py +0 -0
  306. {physioex-2.0.1 → physioex-2.0.2}/tests/train/test_logger.py +0 -0
  307. {physioex-2.0.1 → physioex-2.0.2}/tests/train/test_progress.py +0 -0
  308. {physioex-2.0.1 → physioex-2.0.2}/tests/train/test_stats.py +0 -0
@@ -4,6 +4,18 @@ All notable changes to PhysioEx are documented here. Versions follow the
4
4
  `physioex.__version__` string (read dynamically by the build) and the `v*` git tags
5
5
  that publish to PyPI.
6
6
 
7
+ ## 2.0.2 — 2026-10-10
8
+
9
+ ### Fixed — accuracy-weighted modality dropout (`physioex.models.protosleepnet`)
10
+
11
+ `ZeroEmbeddingDropout` now samples the channels to occlude with probability
12
+ proportional to their accuracy, `p_c = a_c / sum_j a_j`, so the channels the
13
+ model relies on most are dropped most often. This is the rule the released
14
+ ProtoSleepNet and ProtoSleepTransformer models were trained with; a later
15
+ refactoring had inverted the sampling weights to `1 - a_c`. When no accuracy
16
+ estimate is available yet the sampling is uniform. Unit tests in
17
+ `tests/test_modality_dropout.py`.
18
+
7
19
  ## 2.0.1 — 2026-09-13
8
20
 
9
21
  ### Added — Layer-wise Relevance Propagation (`physioex.explain.lrp`)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: physioex
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: A python package for explainable sleep staging via deep learning
5
5
  Project-URL: Homepage, https://github.com/guidogagl/physioex
6
6
  Project-URL: Documentation, https://guidogagl.github.io/physioex
@@ -64,7 +64,7 @@ Description-Content-Type: text/markdown
64
64
  # PhysioEx
65
65
 
66
66
  ![Python Version](https://img.shields.io/badge/python-3.11%2B-blue)
67
- [![PyPI Version](https://img.shields.io/pypi/v/physioex)](https://pypi.org/project/physioex/)
67
+ [![PyPI Version](https://img.shields.io/pypi/v/physioex?cacheSeconds=3600)](https://pypi.org/project/physioex/)
68
68
 
69
69
  **PhysioEx ( Physiological Signal Explainer )** is a versatile python library tailored for building, training, and explaining deep learning models for physiological signal analysis.
70
70
 
@@ -172,8 +172,20 @@ Note: the github version of the library is kept updated weekly, the PiPy version
172
172
  $ pip install "physioex[foundation]" # transformers, for the REVE encoder
173
173
  $ pip install "physioex[datasets]" # mne, for the HOMEPAP EDF fallback reader
174
174
  $ pip install "physioex[tracking]" # tensorboard / wandb logging
175
+ $ pip install "physioex[explain]" # zennit, for Layer-wise Relevance Propagation
175
176
  ```
176
177
 
178
+ > **Note on `torchvision` (CPU-only installs).** The `explain` extra depends on
179
+ > `zennit`, which requires `torchvision`. If your `torch` comes from the PyTorch
180
+ > CPU index, install `torchvision` from the **same** index *before* the extra,
181
+ > otherwise pip pulls a CUDA build from PyPI that fails at import with
182
+ > `operator torchvision::nms does not exist`:
183
+ >
184
+ > ```bash
185
+ > $ pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
186
+ > $ pip install "physioex[explain]"
187
+ > ```
188
+
177
189
  ## Quickstart
178
190
 
179
191
  Set `PHYSIOEX_DATA` to the directory holding your datasets, then use the raw-EDF
@@ -5,7 +5,7 @@
5
5
  # PhysioEx
6
6
 
7
7
  ![Python Version](https://img.shields.io/badge/python-3.11%2B-blue)
8
- [![PyPI Version](https://img.shields.io/pypi/v/physioex)](https://pypi.org/project/physioex/)
8
+ [![PyPI Version](https://img.shields.io/pypi/v/physioex?cacheSeconds=3600)](https://pypi.org/project/physioex/)
9
9
 
10
10
  **PhysioEx ( Physiological Signal Explainer )** is a versatile python library tailored for building, training, and explaining deep learning models for physiological signal analysis.
11
11
 
@@ -113,8 +113,20 @@ Note: the github version of the library is kept updated weekly, the PiPy version
113
113
  $ pip install "physioex[foundation]" # transformers, for the REVE encoder
114
114
  $ pip install "physioex[datasets]" # mne, for the HOMEPAP EDF fallback reader
115
115
  $ pip install "physioex[tracking]" # tensorboard / wandb logging
116
+ $ pip install "physioex[explain]" # zennit, for Layer-wise Relevance Propagation
116
117
  ```
117
118
 
119
+ > **Note on `torchvision` (CPU-only installs).** The `explain` extra depends on
120
+ > `zennit`, which requires `torchvision`. If your `torch` comes from the PyTorch
121
+ > CPU index, install `torchvision` from the **same** index *before* the extra,
122
+ > otherwise pip pulls a CUDA build from PyPI that fails at import with
123
+ > `operator torchvision::nms does not exist`:
124
+ >
125
+ > ```bash
126
+ > $ pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu
127
+ > $ pip install "physioex[explain]"
128
+ > ```
129
+
118
130
  ## Quickstart
119
131
 
120
132
  Set `PHYSIOEX_DATA` to the directory holding your datasets, then use the raw-EDF
@@ -64,6 +64,12 @@ is **optional** — install the extra:
64
64
  pip install "physioex[explain]"
65
65
  ```
66
66
 
67
+ The extra pulls in `zennit`, and therefore `torchvision`. On a CPU-only `torch`
68
+ from the PyTorch index, install `torch torchvision` from that same index *first*
69
+ (`pip install torch torchvision --index-url https://download.pytorch.org/whl/cpu`),
70
+ or pip will fetch a mismatched CUDA `torchvision` from PyPI that fails at import
71
+ (`operator torchvision::nms does not exist`).
72
+
67
73
  Two entry points, both seeding the target neuron with its **logit value** so
68
74
  that `Σ R ≈ f_c(x)` and returning relevance shaped like the input:
69
75
 
@@ -0,0 +1 @@
1
+ __version__ = "2.0.2"
@@ -52,9 +52,17 @@ from physioex.train.metrics import accuracy_score
52
52
 
53
53
 
54
54
  class ZeroEmbeddingDropout(nn.Module):
55
- """Drop channels by replacing embeddings with the encoder's zero-input
56
- embedding. Drop probability is accuracy-weighted: low-accuracy channels
57
- are dropped more often.
55
+ """Accuracy-weighted modality dropout.
56
+
57
+ Replaces the embeddings of selected channels with the encoder's
58
+ zero-input embedding. The drop probability of channel ``c`` is
59
+ proportional to its accuracy, ``p_c = a_c / sum_j a_j``, so the
60
+ channels the model relies on most are occluded most often and the
61
+ model must learn to stage from the secondary modalities.
62
+
63
+ For each sample, with probability ``p_apply`` a number ``n`` of
64
+ channels drawn uniformly in ``{1, ..., C-1}`` is sampled without
65
+ replacement according to ``{p_c}`` and replaced.
58
66
 
59
67
  Only active during training.
60
68
 
@@ -84,11 +92,13 @@ class ZeroEmbeddingDropout(nn.Module):
84
92
  else:
85
93
  acc = torch.tensor(channel_acc, device=device, dtype=torch.float32)
86
94
 
87
- proba = 1.0 - acc
95
+ proba = acc.clamp(min=0.0)
88
96
  proba_sum = proba.sum()
89
97
  if proba_sum <= 0:
90
- return x
91
- proba = proba / proba_sum
98
+ # No accuracy estimate yet: fall back to uniform sampling.
99
+ proba = torch.full((nchan,), 1.0 / nchan, device=device)
100
+ else:
101
+ proba = proba / proba_sum
92
102
 
93
103
  apply_mask = torch.rand(batch, device=device) < self.p_apply
94
104
  n_to_drop = torch.randint(1, nchan, (batch,), device=device)
@@ -0,0 +1,62 @@
1
+ """Accuracy-weighted modality dropout of ProtoSleepNet.
2
+
3
+ The drop probability of a channel must be proportional to its accuracy,
4
+ ``p_c = a_c / sum_j a_j``: the most accurate channel is the one occluded
5
+ most often.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import pytest
10
+
11
+ torch = pytest.importorskip("torch")
12
+
13
+ from physioex.models.protosleepnet import ZeroEmbeddingDropout # noqa: E402
14
+
15
+ pytestmark = pytest.mark.unit
16
+
17
+
18
+ def _drop_counts(acc, n_samples=4000, seed=0):
19
+ torch.manual_seed(seed)
20
+ nchan = len(acc)
21
+ drop = ZeroEmbeddingDropout(p_apply=1.0).train()
22
+ x = torch.ones(n_samples, nchan, 4)
23
+ zero_emb = torch.zeros(1, 4)
24
+ out = drop(x, zero_emb, torch.tensor(acc))
25
+ dropped = (out == 0).all(dim=-1) # (n_samples, nchan)
26
+ return dropped.float().sum(dim=0)
27
+
28
+
29
+ def test_high_accuracy_channel_is_dropped_most():
30
+ counts = _drop_counts([0.9, 0.3, 0.1])
31
+ assert counts[0] > counts[1] > counts[2]
32
+
33
+
34
+ def test_drop_frequency_follows_accuracy_ratio():
35
+ # With two channels, exactly one is dropped per sample (n in {1}), so
36
+ # the empirical drop frequency equals p_c = a_c / sum_j a_j.
37
+ counts = _drop_counts([0.8, 0.2], n_samples=20000)
38
+ freq = counts / counts.sum()
39
+ assert abs(freq[0].item() - 0.8) < 0.02
40
+ assert abs(freq[1].item() - 0.2) < 0.02
41
+
42
+
43
+ def test_never_drops_all_channels():
44
+ torch.manual_seed(0)
45
+ drop = ZeroEmbeddingDropout(p_apply=1.0).train()
46
+ x = torch.ones(512, 3, 4)
47
+ out = drop(x, torch.zeros(1, 4), torch.tensor([0.5, 0.3, 0.2]))
48
+ kept = (out != 0).any(dim=-1).sum(dim=1)
49
+ assert (kept >= 1).all()
50
+
51
+
52
+ def test_uniform_fallback_without_accuracy_estimates():
53
+ counts = _drop_counts([0.0, 0.0, 0.0], n_samples=6000)
54
+ freq = counts / counts.sum()
55
+ assert (freq - 1.0 / 3).abs().max().item() < 0.03
56
+
57
+
58
+ def test_identity_in_eval_mode():
59
+ drop = ZeroEmbeddingDropout(p_apply=1.0).eval()
60
+ x = torch.randn(8, 3, 4)
61
+ out = drop(x, torch.zeros(1, 4), torch.tensor([0.9, 0.1, 0.1]))
62
+ assert torch.equal(out, x)
@@ -1 +0,0 @@
1
- __version__ = "2.0.1"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes