From 220f357a428aca42cb108f912cb4d78374c78be2 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 14:37:37 -0800 Subject: [PATCH 01/37] add sphinx documentation code --- docs/conf.py | 30 ++++++++++++++++++++++++++++++ docs/index.rst | 21 +++++++++++++++++++++ docs/requirements.txt | 1 + 3 files changed, 52 insertions(+) create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/requirements.txt diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..223539d --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,30 @@ +# Configuration file for the Sphinx documentation builder. +# +# For the full list of built-in configuration values, see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information + +project = 'sparsecoding' +copyright = '2024, RCTN' +author = 'RCTN' + +# -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration + +extensions = [ + 'sphinx.ext.napoleon', + 'sphinx.ext.autodoc', +] + +templates_path = ['_templates'] +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + + + +# -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output + +html_theme = 'pydata_sphinx_theme' +html_static_path = ['_static'] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..f56e6c1 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,21 @@ +.. sparsecoding documentation master file, created by + sphinx-quickstart on Fri Nov 15 13:23:58 2024. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +sparsecoding documentation +========================== + +Add your content using ``reStructuredText`` syntax. See the +`reStructuredText `_ +documentation for details. + + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + sparsecoding + sparsecoding.data + sparsecoding.priors + modules + diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..b0a77ce --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1 @@ +pydata-sphinx-theme \ No newline at end of file From bfa3319f19c69ce02136eca136305c44acd79548 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 14:44:00 -0800 Subject: [PATCH 02/37] import sphinx and add readthedocs config yaml --- .readthedocs.yaml | 13 +++++++++++++ docs/requirements.txt | 1 + 2 files changed, 14 insertions(+) create mode 100644 .readthedocs.yaml diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..34ad79a --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,13 @@ +version: 2 + +build: + os: ubuntu-24.04 + tools: + python: "3" + +sphinx: + configuration: docs/conf.py + +python: + install: + - requirements: docs/requirements.txt \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index b0a77ce..7274d5e 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ +sphinx pydata-sphinx-theme \ No newline at end of file From 45c008fe5e82338e0cf0ab6126dff0531d007152 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:02:06 -0800 Subject: [PATCH 03/37] run apidoc post build --- .readthedocs.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 34ad79a..71277d9 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -4,6 +4,9 @@ build: os: ubuntu-24.04 tools: python: "3" + jobs: + post_install: + - sphinx-apidoc -o docs sparsecoding sphinx: configuration: docs/conf.py From 63d4e3e9063866ddc767082fdf0138da50367c06 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:06:57 -0800 Subject: [PATCH 04/37] require sparse coding repo install for documentation generation --- docs/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/requirements.txt b/docs/requirements.txt index 7274d5e..b341987 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,2 +1,3 @@ +. sphinx pydata-sphinx-theme \ No newline at end of file From d8aab42d1c4f344c9bc3aedeba1b5a9053df68df Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:15:05 -0800 Subject: [PATCH 05/37] install package requirements to build docs --- .readthedocs.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 71277d9..10b95f8 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -7,6 +7,7 @@ build: jobs: post_install: - sphinx-apidoc -o docs sparsecoding + - pip install -r requirements.txt sphinx: configuration: docs/conf.py From b4b3b3c40c48ecf3352a4acd63748edaef68a804 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:28:42 -0800 Subject: [PATCH 06/37] autogenerate rst files to import --- docs/api.rst | 7 +++++++ docs/conf.py | 4 ++++ docs/index.rst | 7 +------ 3 files changed, 12 insertions(+), 6 deletions(-) create mode 100644 docs/api.rst diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..8ab30de --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,7 @@ +API +=== + +.. autosummary:: + :toctree: generated + + sparsecoding diff --git a/docs/conf.py b/docs/conf.py index 223539d..fad24b8 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,6 +6,8 @@ # -- Project information ----------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information +import os + project = 'sparsecoding' copyright = '2024, RCTN' author = 'RCTN' @@ -16,6 +18,7 @@ extensions = [ 'sphinx.ext.napoleon', 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', ] templates_path = ['_templates'] @@ -28,3 +31,4 @@ html_theme = 'pydata_sphinx_theme' html_static_path = ['_static'] +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index f56e6c1..6af82eb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,10 +12,5 @@ documentation for details. .. toctree:: - :maxdepth: 2 - :caption: Contents: - sparsecoding - sparsecoding.data - sparsecoding.priors - modules + api \ No newline at end of file From 0d5575a5b1c686bb6b933f857f729a136f77b936 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:41:20 -0800 Subject: [PATCH 07/37] make submodules importable --- .readthedocs.yaml | 2 +- sparsecoding/__init__.py | 6 ++++++ sparsecoding/data/__init__.py | 4 ++++ sparsecoding/data/datasets/__init__.py | 0 sparsecoding/data/dictionaries/__init__.py | 0 5 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 sparsecoding/data/datasets/__init__.py create mode 100644 sparsecoding/data/dictionaries/__init__.py diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 10b95f8..6e7b8ca 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -6,7 +6,7 @@ build: python: "3" jobs: post_install: - - sphinx-apidoc -o docs sparsecoding + - sphinx-apidoc -M -o docs sparsecoding - pip install -r requirements.txt sphinx: diff --git a/sparsecoding/__init__.py b/sparsecoding/__init__.py index 74847a6..bb7144d 100644 --- a/sparsecoding/__init__.py +++ b/sparsecoding/__init__.py @@ -1 +1,7 @@ "Modules for sparse coding." + +from . import models +from . import inference +from . import visualization +from . import priors +from . import data \ No newline at end of file diff --git a/sparsecoding/data/__init__.py b/sparsecoding/data/__init__.py index 6f39034..8dcf25f 100644 --- a/sparsecoding/data/__init__.py +++ b/sparsecoding/data/__init__.py @@ -1 +1,5 @@ """Module for exposing datasets to users.""" + +from . import transforms +from . import datasets +from . import dictionaries \ No newline at end of file diff --git a/sparsecoding/data/datasets/__init__.py b/sparsecoding/data/datasets/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sparsecoding/data/dictionaries/__init__.py b/sparsecoding/data/dictionaries/__init__.py new file mode 100644 index 0000000..e69de29 From d098b88e7729513da66c774f7e23977b1c9bf948 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:43:29 -0800 Subject: [PATCH 08/37] change base from sparsecoding to modules --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 8ab30de..99e5b5c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,4 +4,4 @@ API .. autosummary:: :toctree: generated - sparsecoding + modules From 5bbe776a96ae40ac735097efd72b5bbead3f8f06 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:45:32 -0800 Subject: [PATCH 09/37] apidoc output in generated dir --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 6e7b8ca..4cb56eb 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -6,7 +6,7 @@ build: python: "3" jobs: post_install: - - sphinx-apidoc -M -o docs sparsecoding + - sphinx-apidoc -M -o docs/generated sparsecoding - pip install -r requirements.txt sphinx: From 7bb06a892eb0e5de150566f3aa0b06395c338672 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 15:51:20 -0800 Subject: [PATCH 10/37] change modules to sparsecoding --- docs/api.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 99e5b5c..8ab30de 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -4,4 +4,4 @@ API .. autosummary:: :toctree: generated - modules + sparsecoding From 707fa3c3c70da14db80155fe122801f862d3a324 Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 15 Nov 2024 16:12:39 -0800 Subject: [PATCH 11/37] docs are generated, however there are errors and when searching the generated docs, inference and models doesnt show up. Need to investigate this issue further --- docs/api.rst | 1 + docs/index.rst | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 8ab30de..3844893 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -2,6 +2,7 @@ API === .. autosummary:: + :toctree: generated sparsecoding diff --git a/docs/index.rst b/docs/index.rst index 6af82eb..3896321 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,5 +12,4 @@ documentation for details. .. toctree:: - api \ No newline at end of file From f00f62573981b9052eefb44109331da841a591f3 Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 19:29:49 -0800 Subject: [PATCH 12/37] change theme to rtd, generate API documentation with autodoc --- docs/api.rst | 69 +++++++++++++++++++++++++++++++++++++++---- docs/conf.py | 4 +-- docs/index.rst | 14 ++++----- docs/requirements.txt | 2 +- 4 files changed, 74 insertions(+), 15 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 3844893..7dc6b94 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -1,8 +1,67 @@ -API -=== +============= +API Reference +============= -.. autosummary:: +.. py:currentmodule:: sparsecoding - :toctree: generated +Dictionary learning models +-------------------------- - sparsecoding +.. automodule:: sparsecoding.models + :members: + :undoc-members: + :show-inheritance: + + +Inference methods +----------------- + +.. automodule:: sparsecoding.inference + :members: + :undoc-members: + :show-inheritance: + + +Visualization tools +------------------- + +.. automodule:: sparsecoding.visualization + :members: + :undoc-members: + :show-inheritance: + + +Priors +------ + +.. automodule:: sparsecoding.priors + :members: + :undoc-members: + :show-inheritance: + + +Datasets +-------- + +.. automodule:: sparsecoding.data.datasets + :members: + :undoc-members: + :show-inheritance: + + +Whitening and sphering +---------------------- + +.. automodule:: sparsecoding.data.transforms.whiten + :members: + :undoc-members: + :show-inheritance: + + +Extracting image patches +------------------------ + +.. automodule:: sparsecoding.data.transforms.patch + :members: + :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index fad24b8..2c3cf75 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -8,7 +8,7 @@ import os -project = 'sparsecoding' +project = 'RCTN sparsecoding' copyright = '2024, RCTN' author = 'RCTN' @@ -29,6 +29,6 @@ # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -html_theme = 'pydata_sphinx_theme' +html_theme = 'sphinx_rtd_theme' html_static_path = ['_static'] html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 3896321..213aa61 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,13 +3,13 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -sparsecoding documentation -========================== - -Add your content using ``reStructuredText`` syntax. See the -`reStructuredText `_ -documentation for details. +########################################### +Welcome to the RCTN sparsecoding repository +########################################### .. toctree:: - api \ No newline at end of file + :maxdepth: 1 + :numbered: + + api diff --git a/docs/requirements.txt b/docs/requirements.txt index b341987..9ab2504 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,3 +1,3 @@ . sphinx -pydata-sphinx-theme \ No newline at end of file +sphinx-rtd-theme \ No newline at end of file From cec25cbcb496993b99080b78a5399dcf99bac118 Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 19:34:13 -0800 Subject: [PATCH 13/37] change python 3 to 3.7 --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 4cb56eb..47ace67 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-24.04 tools: - python: "3" + python: "3.7" jobs: post_install: - sphinx-apidoc -M -o docs/generated sparsecoding From a876c383ff27ccfe958d8ab6c8cf5577a8f8a844 Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 20:53:44 -0800 Subject: [PATCH 14/37] upload of install, contributing, and quickstart docs. quickstart doc still needs to be completed --- docs/contributing.rst | 37 +++++++++++++++++++++++++++++++++++++ docs/index.rst | 3 +++ docs/install.rst | 30 ++++++++++++++++++++++++++++++ docs/quickstart.rst | 4 ++++ 4 files changed, 74 insertions(+) create mode 100644 docs/contributing.rst create mode 100644 docs/install.rst create mode 100644 docs/quickstart.rst diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000..513741b --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1,37 @@ +============ +Contributing +============ + +All contributions are welcome! + +Bug Reporting +------------- + +If you find a bug, submit a bug report on GitHub Issues. + +Adding Features/Fixing Bugs +--------------------------- + +If you have identified a new feature or bug that you can fix yourself, please follow the following procedure. + +#. Clone ``main`` branch. +#. Create a new branch to contain your changes. +#. ``add``, ``commit``, and ``push`` your changes to this branch. +#. Create a pull request (PR). See more information on submitting a PR request below. + +Submitting a Pull Request +------------------------- + +#. If necessary, please **write your own unit tests** and add them to `the tests directory `_. +#. Verify that all tests are passed by running `python -m unittest discover tests -vvv`. +#. Be sure that your PR follows formatting guidelines, `PEP8 `_ and `flake8 `_. +#. Make sure the title of your PR summarizes the features/issues resolved in your branch. +#. Submit your pull request and add reviewers. + +Coding Style Guidelines +----------------------- +We adhere to the `NumPy documentation standards `_. + +#. Format code in accordance with `flake8 `_ standard. +#. Use underscores to separate words in non-class names: ``n_samples`` rather than ``nsamples``. +#. Avoid single-character variable names. \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 213aa61..bcbf0d8 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,4 +12,7 @@ Welcome to the RCTN sparsecoding repository :maxdepth: 1 :numbered: + install + quickstart api + contributing diff --git a/docs/install.rst b/docs/install.rst new file mode 100644 index 0000000..031b19e --- /dev/null +++ b/docs/install.rst @@ -0,0 +1,30 @@ +============ +Installation +============ + +Basic +----- + +The fastest way to install is by cloning the code from Github: + +.. code:: bash + + $ git clone https://github.com/rctn/sparsecoding.git + $ cd sparsecoding + $ pip install -e sparsecoding + $ pip install -r requirements.txt + + +The last line of the code above will install the RCTN sparse coding dependencies: + +- ``numpy`` + +- ``scipy`` + +- ``matplotlib`` + +- ``torch`` + +- ``torchvision`` + + diff --git a/docs/quickstart.rst b/docs/quickstart.rst new file mode 100644 index 0000000..bca4f4e --- /dev/null +++ b/docs/quickstart.rst @@ -0,0 +1,4 @@ +========== +Quickstart +========== + From 4426be3aad6cb0eb059b0b830161802fd9defe12 Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 21:18:39 -0800 Subject: [PATCH 15/37] add quick intro to library --- docs/index.rst | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index bcbf0d8..2a42382 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,10 +3,21 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -########################################### -Welcome to the RCTN sparsecoding repository -########################################### +####################################### +RCTN sparsecoding library documentation +####################################### +`sparsecoding`_ is a python library developed by the `Redwood Center for +Theoretical Neuroscience `_ which contains +performant `pytorch `_ implementations of sparse coding dictionary learning, +inference, and data processing. It was written to be a useful research tool +for applying various sparse coding methods to data. + +We believe that sharing code within the scientific community is an important +part of science and we hope that the research community finds this library +useful. + +.. _sparsecoding: https://github.com/rctn/sparsecoding/ .. toctree:: :maxdepth: 1 From e2332e0c0e2e828a671cf1ef1002be47f549fd6e Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 21:20:28 -0800 Subject: [PATCH 16/37] add RCTN abbreviation --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index 2a42382..7292e78 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -8,7 +8,7 @@ RCTN sparsecoding library documentation ####################################### `sparsecoding`_ is a python library developed by the `Redwood Center for -Theoretical Neuroscience `_ which contains +Theoretical Neuroscience (RCTN) `_ which contains performant `pytorch `_ implementations of sparse coding dictionary learning, inference, and data processing. It was written to be a useful research tool for applying various sparse coding methods to data. From c82631c53c98cf6483607a0484e30f6a668bfad4 Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 21:25:49 -0800 Subject: [PATCH 17/37] add license info --- docs/index.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 7292e78..0227015 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -27,3 +27,9 @@ useful. quickstart api contributing + + +License +------- + +`sparsecoding`_ has a BSD-3-clause license, as found in the `LICENSE `_ file. \ No newline at end of file From 5608d357897d1c1fd67b61af36f8ae610d712eed Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 19 Nov 2024 21:27:06 -0800 Subject: [PATCH 18/37] remove basic --- docs/install.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/install.rst b/docs/install.rst index 031b19e..deff6eb 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -2,10 +2,7 @@ Installation ============ -Basic ------ - -The fastest way to install is by cloning the code from Github: +The fastest way to install is by cloning the library from Github: .. code:: bash From 4360d40f310938ae576b5d593055600f6a1f7349 Mon Sep 17 00:00:00 2001 From: belsten Date: Wed, 20 Nov 2024 10:36:10 -0800 Subject: [PATCH 19/37] added structure of library. Note its not exacly correct. It reflects restructure proposed in recent issue. --- docs/quickstart.rst | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index bca4f4e..57e170d 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -2,3 +2,47 @@ Quickstart ========== +Overview +-------- + +.. _sparsecoding: https://github.com/rctn/sparsecoding/ + +`sparsecoding`_ is a python package that provides tools for using sparse coding algorithms. +Historically, sparse coding has been largely focused on learning sparse representations +of images and we provide visualization and transformation tools to work with such data. +However, we've tried to structure the dictionary learning methods and inference methods +in a manner that is data-agnostic. + +The `sparsecoding`_ library is largely built using PyTorch which enables it to inheret +many performance benifits. These include: + +- GPU support + +- Batched operations + +- Auto-grad optimizers + + + +Structure of library +-------------------- + +The functionalities of `sparsecoding`_ are broken into differnent modules. + +- ``sparsecoding.models`` contains dictionary learning models (e.g. SparseCoding). + +- ``sparsecoding.inference`` contains algorithms for computing latent coefficients. + +- ``sparsecoding.visualization`` contains tools for visualizing image dictionaries and data. + +- ``sparsecoding.priors`` contains methods for sampling from various sparse coding priors. + +- ``sparsecoding.datasets`` contains methods for loading datasets. + +- ``sparsecoding.transforms`` contains methods working with data, such as whitening and extracting patches from images. + + +Getting started +--------------- + +`See example notebooks `_. \ No newline at end of file From 2f0cff9e7edf656b8718aeacecb8d1832954b25f Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 22 Nov 2024 17:01:32 -0800 Subject: [PATCH 20/37] rename transformations --- docs/api.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 7dc6b94..61f2801 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -43,25 +43,25 @@ Priors Datasets -------- -.. automodule:: sparsecoding.data.datasets +.. automodule:: sparsecoding.datasets :members: :undoc-members: :show-inheritance: -Whitening and sphering ----------------------- +Data transformations +-------------------- -.. automodule:: sparsecoding.data.transforms.whiten +.. automodule:: sparsecoding.transforms.whiten :members: :undoc-members: :show-inheritance: -Extracting image patches ------------------------- +Image transformations +--------------------- -.. automodule:: sparsecoding.data.transforms.patch +.. automodule:: sparsecoding.transforms.patch :members: :undoc-members: :show-inheritance: \ No newline at end of file From 3a3d0f0043b30577aa0fc38c65a0e56a232695ed Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 22 Nov 2024 17:02:00 -0800 Subject: [PATCH 21/37] delete unnecessary utils and init --- sparsecoding/data/__init__.py | 5 ----- sparsecoding/data/utils.py | 37 ----------------------------------- 2 files changed, 42 deletions(-) delete mode 100644 sparsecoding/data/__init__.py delete mode 100644 sparsecoding/data/utils.py diff --git a/sparsecoding/data/__init__.py b/sparsecoding/data/__init__.py deleted file mode 100644 index 8dcf25f..0000000 --- a/sparsecoding/data/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -"""Module for exposing datasets to users.""" - -from . import transforms -from . import datasets -from . import dictionaries \ No newline at end of file diff --git a/sparsecoding/data/utils.py b/sparsecoding/data/utils.py deleted file mode 100644 index 7eccfc2..0000000 --- a/sparsecoding/data/utils.py +++ /dev/null @@ -1,37 +0,0 @@ -import os -import torch -import numpy as np -import pickle as pkl - -MODULE_PATH = os.path.dirname(__file__) -DATASET_PATH = os.path.join(MODULE_PATH, "datasets") -DICTIONARY_PATH = os.path.join(MODULE_PATH, "dictionaries") - -BARS_DICT_PATH = os.path.join(DICTIONARY_PATH, "bars", "bars-16_by_16.p") -OLSHAUSEN_DICT_PATH = os.path.join(DICTIONARY_PATH, "olshausen", "olshausen-1.5x_overcomplete.p") - - -def load_dictionary_from_pickle(path): - dictionary_file = open(path, 'rb') - numpy_dictionary = pkl.load(dictionary_file) - dictionary_file.close() - dictionary = torch.tensor(numpy_dictionary.astype(np.float32)) - return dictionary - - -def load_bars_dictionary(): - path = BARS_DICT_PATH - dictionary_file = open(path, 'rb') - numpy_dictionary = pkl.load(dictionary_file) - dictionary_file.close() - dictionary = torch.tensor(numpy_dictionary.astype(np.float32)) - return dictionary - - -def load_olshausen_dictionary(): - path = OLSHAUSEN_DICT_PATH - dictionary_file = open(path, 'rb') - numpy_dictionary = pkl.load(dictionary_file) - dictionary_file.close() - dictionary = torch.tensor(numpy_dictionary.astype(np.float32)) - return dictionary From 7dc169abafd84c2fd365438f772b814bcaaf0f4d Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 22 Nov 2024 17:02:43 -0800 Subject: [PATCH 22/37] remove import from data and add imports of transfrom tools --- sparsecoding/__init__.py | 47 +++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/sparsecoding/__init__.py b/sparsecoding/__init__.py index bb7144d..07955ca 100644 --- a/sparsecoding/__init__.py +++ b/sparsecoding/__init__.py @@ -1,7 +1,42 @@ -"Modules for sparse coding." +from .models import SparseCoding +from .inference import LCA, IHT, ISTA, LSM, MP, OMP, Vanilla, PyTorchOptimizer +from .visualization import plot_dictionary, plot_patches +from .priors import SpikeSlabPrior, L0Prior +from .datasets import BarsDataset, FieldDataset +from .dictionaries import ( + load_dictionary_from_pickle, + load_bars_dictionary, + load_olshausen_dictionary, +) -from . import models -from . import inference -from . import visualization -from . import priors -from . import data \ No newline at end of file +__all__ = [ + # Models + "SparseCoding", + + # Inference + "LCA", + "IHT", + "ISTA", + "LSM", + "MP", + "OMP", + "Vanilla", + "PyTorchOptimizer", + + # Visualization + "plot_dictionary", + "plot_patches", + + # Priors + "SpikeSlabPrior", + "L0Prior", + + # Dictionaries + "load_dictionary_from_pickle", + "load_bars_dictionary", + "load_olshausen_dictionary", + + # Datasets + "BarsDataset", + "FieldDataset", +] \ No newline at end of file From dbb2537b404fd9980f6bb4b19dfd69c4d3c9774b Mon Sep 17 00:00:00 2001 From: belsten Date: Sat, 23 Nov 2024 08:45:54 -0800 Subject: [PATCH 23/37] fixed typos and minor reword --- docs/contributing.rst | 42 ++++++++++++++++++++----------------- docs/install.rst | 21 +++++++------------ docs/quickstart.rst | 48 ++++++++++++++++++------------------------- 3 files changed, 50 insertions(+), 61 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 513741b..16b2981 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -2,36 +2,40 @@ Contributing ============ -All contributions are welcome! +We welcome all contributions! Bug Reporting ------------- -If you find a bug, submit a bug report on GitHub Issues. +If you encounter a bug, please report it by creating an issue on GitHub. -Adding Features/Fixing Bugs ---------------------------- +Adding Features or Fixing Bugs +------------------------------ -If you have identified a new feature or bug that you can fix yourself, please follow the following procedure. +If you’ve identified a new feature to add or a bug you can fix, follow these steps: -#. Clone ``main`` branch. -#. Create a new branch to contain your changes. -#. ``add``, ``commit``, and ``push`` your changes to this branch. -#. Create a pull request (PR). See more information on submitting a PR request below. +#. Clone the ``main`` branch. +#. Create a new branch to work on your changes. +#. Use ``add``, ``commit``, and ``push`` to save your changes to the new branch. +#. Create a pull request (PR). See the "Submitting a Pull Request" section for more details. Submitting a Pull Request ------------------------- -#. If necessary, please **write your own unit tests** and add them to `the tests directory `_. -#. Verify that all tests are passed by running `python -m unittest discover tests -vvv`. -#. Be sure that your PR follows formatting guidelines, `PEP8 `_ and `flake8 `_. -#. Make sure the title of your PR summarizes the features/issues resolved in your branch. -#. Submit your pull request and add reviewers. +#. If applicable, write unit tests for your changes and add them to the + `tests directory `_. +#. Verify that all tests pass by running ``python -m unittest discover tests -vvv``. +#. Ensure your code adheres to the formatting guidelines specified in + `PEP8 `_ and validated by + `flake8 `_. +#. Provide a concise and descriptive title for your PR that summarizes the changes made in your branch. +#. Submit your PR and assign reviewers as necessary. Coding Style Guidelines ------------------------ -We adhere to the `NumPy documentation standards `_. +------------------------ -#. Format code in accordance with `flake8 `_ standard. -#. Use underscores to separate words in non-class names: ``n_samples`` rather than ``nsamples``. -#. Avoid single-character variable names. \ No newline at end of file +We follow the `NumPy documentation standards `_. + +1. Format your code according to the `flake8 `_ standard. +2. Use underscores to separate words in non-class names (e.g., ``n_samples`` instead of ``nsamples``). +3. Avoid single-character variable names. diff --git a/docs/install.rst b/docs/install.rst index deff6eb..e71e79f 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -2,26 +2,19 @@ Installation ============ -The fastest way to install is by cloning the library from Github: +The quickest way to install the library is by cloning it directly from GitHub: .. code:: bash - $ git clone https://github.com/rctn/sparsecoding.git - $ cd sparsecoding - $ pip install -e sparsecoding - $ pip install -r requirements.txt + git clone https://github.com/rctn/sparsecoding.git + cd sparsecoding + pip install -e sparsecoding + pip install -r requirements.txt +The last command installs the dependencies required for the RCTN sparse coding library, including: -The last line of the code above will install the RCTN sparse coding dependencies: - -- ``numpy`` - +- ``numpy`` - ``scipy`` - - ``matplotlib`` - - ``torch`` - - ``torchvision`` - - diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 57e170d..bc6ccb1 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -7,42 +7,34 @@ Overview .. _sparsecoding: https://github.com/rctn/sparsecoding/ -`sparsecoding`_ is a python package that provides tools for using sparse coding algorithms. -Historically, sparse coding has been largely focused on learning sparse representations -of images and we provide visualization and transformation tools to work with such data. -However, we've tried to structure the dictionary learning methods and inference methods -in a manner that is data-agnostic. +`sparsecoding`_ is a Python package that provides tools for implementing sparse coding algorithms. +Traditionally, sparse coding has been primarily used for learning sparse representations of images. +To support this, we include tools for visualization and data transformation specific to image data. +However, we have designed the dictionary learning and inference methods to be data-agnostic, +allowing for broader applications. -The `sparsecoding`_ library is largely built using PyTorch which enables it to inheret -many performance benifits. These include: +The `sparsecoding`_ library is built largely on PyTorch, enabling it to inherit several +performance benefits, such as: - GPU support - - Batched operations - - Auto-grad optimizers +Structure of the Library +------------------------- +The functionalities of `sparsecoding`_ are organized into several modules: -Structure of library --------------------- - -The functionalities of `sparsecoding`_ are broken into differnent modules. - -- ``sparsecoding.models`` contains dictionary learning models (e.g. SparseCoding). - -- ``sparsecoding.inference`` contains algorithms for computing latent coefficients. - -- ``sparsecoding.visualization`` contains tools for visualizing image dictionaries and data. - -- ``sparsecoding.priors`` contains methods for sampling from various sparse coding priors. - -- ``sparsecoding.datasets`` contains methods for loading datasets. - -- ``sparsecoding.transforms`` contains methods working with data, such as whitening and extracting patches from images. - +- ``sparsecoding.models``: Contains dictionary learning models (e.g., SparseCoding). +- ``sparsecoding.inference``: Includes algorithms for computing latent coefficients. +- ``sparsecoding.visualization``: Provides tools for visualizing image dictionaries and data. +- ``sparsecoding.priors``: Offers methods for sampling from various sparse coding priors. +- ``sparsecoding.datasets``: Contains utilities for loading datasets. +- ``sparsecoding.transforms``: Includes methods for working with data, such as whitening and + extracting patches from images. -Getting started +Getting Started --------------- -`See example notebooks `_. \ No newline at end of file +Explore our `example notebooks `_ +to get started. From cd22d5beda53575b8b69308d28e00e5caf7de05e Mon Sep 17 00:00:00 2001 From: belsten Date: Sat, 23 Nov 2024 09:12:23 -0800 Subject: [PATCH 24/37] update readme to provide pointers to the readthedocs. delete obsolete contributing.md as updated material is now in the readthedocs --- README.md | 46 +++++++++++++++----------- docs/contributing.md | 78 -------------------------------------------- 2 files changed, 27 insertions(+), 97 deletions(-) delete mode 100644 docs/contributing.md diff --git a/README.md b/README.md index 56c2b86..01c69ab 100644 --- a/README.md +++ b/README.md @@ -1,31 +1,39 @@ -# Sparse Coding +# RCTN SparseCoding Library -Reference sparse coding implementations for efficient learning and inference implemented in PyTorch with GPU support. +`sparsecoding` is a Python library developed by UC Berkeley's [Redwood Center for Theoretical Neuroscience (RCTN)](https://redwood.berkeley.edu). It provides efficient, batched, and GPU-compatible [PyTorch](https://github.com/pytorch/pytorch) implementations for sparse coding related-algorithms, including dictionary learning, inference, and data processing. -## Features +Historically, sparse coding has been largely focused on learning sparse representations of images and we provide visualization and transformation tools to work with such data. However, we’ve tried to structure the transformation, dictionary learning methods, and inference methods in a manner that is data-agnostic, making them applicable to a wide range of use cases. + +We believe that sharing code within the scientific community is an important part of science and we hope that the research community finds this library useful. -### Dictionary Learning +--- -* Repo currently includes classic patch-wise sparse coding dictionary learning. +## Features -### Implemented Inference Methods +- Check out our [Quickstart Guide](https://sparsecoding.readthedocs.io/en/latest/quickstart.html) for an overview and setup instructions. +- Refer to the [API Reference](https://sparsecoding.readthedocs.io/en/latest/api.html) for detailed usage of the library's features. -* Locally Competative Algorithm (LCA) -* Gradient Descent with Euler's method on Laplace Prior (Vanilla) -* Laplacian Scale Mixture (LSM) -* Iterative Shrinkage-threshold Algorithm (ISTA) -* Generic PyTorch minimization of arbitrary loss function (PyTorchOptimizer) +--- ## Setup -1. Clone the repo. -2. Navigate to the directory containing the repo directory. -3. Run `pip install -e ".[all]"` -4. Install the natural images dataset from this link: https://rctn.org/bruno/sparsenet/IMAGES.mat -5. Try running the demo notebook: `examples/sparse_coding.ipynb` +To install the library, follow these steps: + +```bash +git clone https://github.com/rctn/sparsecoding.git +cd sparsecoding +pip install -e ".[all]" +``` + +Try running the demo notebook: `examples/sparse_coding.ipynb`. + +For more detailed instructions, see our [Installation Guide](https://sparsecoding.readthedocs.io/en/latest/install.html). + +Note: If you're using a Jupyter notebook and make changes to the source files, you can either: +* Restart the Jupyter kernel, or +* Use the autoreload extension as explained [here](https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html#autoreload). -Note: If you are using a Jupyter notebook and change a source file, you can either: 1) restart the Jupyter kernel, or 2) follow instructions [here](https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html#autoreload). -## Contributing -See the [contributing](docs/contributing.md) document! +# Contributing +We welcome contributions! Please see our [contributing](https://sparsecoding.readthedocs.io/en/latest/contributing.html) for details on how to get involved. diff --git a/docs/contributing.md b/docs/contributing.md deleted file mode 100644 index 5a49a47..0000000 --- a/docs/contributing.md +++ /dev/null @@ -1,78 +0,0 @@ -# Contributing - -All contributions are welcome! - -## Bug Reporting - -If you find a bug, submit a bug report on GitHub Issues. - -## Adding Features/Fixing Bugs - -If you have identified a new feature or bug that you can fix yourself, please follow the following procedure. - -1. Fork `main` branch. -2. Create a new branch to contain your changes. -3. `add`, `commit`, and `push` your changes to this branch. -4. Create a pull request (PR). See more information on submitting a PR request below. - -### Submitting a Pull Request - -1. If necessary, please **write your own unit tests** and place them near the code being tested. High-level tests, such as integration or example tests can be placed in the top-level "tests" folder. -2. Verify that all tests are passed by running `python -m pytest .`. -3. Be sure that your PR follows formatting guidelines, [PEP8](https://peps.python.org/pep-0008/) and [flake8](https://flake8.pycqa.org/en/latest/). -4. Make sure the title of your PR summarizes the features/issues resolved in your branch. -5. Submit your pull request and add reviewers. - -## Coding Style Guidelines - -The following are some guidelines on how new code should be written. Of course, there are special cases, and there will be exceptions to these rules. - -1. Format code in accordance with [flake8](https://flake8.pycqa.org/en/latest/) standard. -2. Use underscores to separate words in non-class names: `n_samples` rather than `nsamples`. -3. Avoid single-character variable names. - -## Docstrings - -When writing docstrings, please follow the following example. - -```py -def count_beans(self, baz, use_gpu=False, foo="vector" - bar=None): - """Write a one-line summary for the method. - - Parameters - ---------- - baz : array-like, shape [..., dim] - Write a short description of parameter baz. - use_gpu : bool, default=False - Write a short description of parameter use_gpu. - foo : str, {"vector", "matrix"}, default="vector" - Write a short description of parameter foo. - bar : array-like, shape [...,], optional - Write a short description of parameter bar. - - Returns - ------- - n_beans : array-like, shape [..., dim, dim] - Write a short description of the result returned by the method. - - Notes - ----- - If relevant, provide equations with (:math:) - describing computations performed in the method. - - Example - ------- - Provide code snippets showing how the method is used. - You can link to scripts of the examples/ directory. - - Reference - --------- - If relevant, provide a reference with associated pdf or - wikipedia page. - ex: - [1] Einstein, A., Podolsky, B., & Rosen, N. (1935). Can - quantum-mechanical description of physical reality be - considered complete?. Physical review, 47(10), 777. - """ -``` From 86fa6a7963d33998f264b3af0c56e577e39b2b94 Mon Sep 17 00:00:00 2001 From: belsten Date: Sat, 23 Nov 2024 09:13:32 -0800 Subject: [PATCH 25/37] remove accidental horizontal lines --- README.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/README.md b/README.md index 01c69ab..d4bc7ad 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,12 @@ Historically, sparse coding has been largely focused on learning sparse represen We believe that sharing code within the scientific community is an important part of science and we hope that the research community finds this library useful. ---- ## Features - Check out our [Quickstart Guide](https://sparsecoding.readthedocs.io/en/latest/quickstart.html) for an overview and setup instructions. - Refer to the [API Reference](https://sparsecoding.readthedocs.io/en/latest/api.html) for detailed usage of the library's features. ---- ## Setup @@ -34,6 +32,5 @@ Note: If you're using a Jupyter notebook and make changes to the source files, y * Use the autoreload extension as explained [here](https://ipython.readthedocs.io/en/stable/config/extensions/autoreload.html#autoreload). - # Contributing We welcome contributions! Please see our [contributing](https://sparsecoding.readthedocs.io/en/latest/contributing.html) for details on how to get involved. From 33c543798d94f467012b15011fe43e7b51873c3f Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 28 Nov 2024 08:11:27 -0800 Subject: [PATCH 26/37] add documentation badge to readme --- README.md | 3 +++ sparsecoding/__init__.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d4bc7ad..81de545 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # RCTN SparseCoding Library +[![Documentation status](https://readthedocs.org/projects/sparsecoding/badge/)]( +https://sparsecoding.readthedocs.io/) + `sparsecoding` is a Python library developed by UC Berkeley's [Redwood Center for Theoretical Neuroscience (RCTN)](https://redwood.berkeley.edu). It provides efficient, batched, and GPU-compatible [PyTorch](https://github.com/pytorch/pytorch) implementations for sparse coding related-algorithms, including dictionary learning, inference, and data processing. Historically, sparse coding has been largely focused on learning sparse representations of images and we provide visualization and transformation tools to work with such data. However, we’ve tried to structure the transformation, dictionary learning methods, and inference methods in a manner that is data-agnostic, making them applicable to a wide range of use cases. diff --git a/sparsecoding/__init__.py b/sparsecoding/__init__.py index 07955ca..d233a2c 100644 --- a/sparsecoding/__init__.py +++ b/sparsecoding/__init__.py @@ -39,4 +39,4 @@ # Datasets "BarsDataset", "FieldDataset", -] \ No newline at end of file +] From b228aa812f99e8abb0fa5a3b7323c1958a1bab43 Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 28 Nov 2024 08:40:23 -0800 Subject: [PATCH 27/37] flake8 docs --- docs/conf.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 2c3cf75..9ab4d69 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,10 +25,9 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - # -- Options for HTML output ------------------------------------------------- # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = 'sphinx_rtd_theme' html_static_path = ['_static'] -html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") \ No newline at end of file +html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") From a13d921a1919880db9755c67c5d8ad1cdaf3521e Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 23 Jan 2025 14:57:06 -0800 Subject: [PATCH 28/37] upgrade python install for readthedocs to match that of setup.py --- .readthedocs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 47ace67..8a81993 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -3,7 +3,7 @@ version: 2 build: os: ubuntu-24.04 tools: - python: "3.7" + python: "3.8" jobs: post_install: - sphinx-apidoc -M -o docs/generated sparsecoding From c6d18710fef231a32e6228b55affb10d4063eb86 Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 23 Jan 2025 15:25:34 -0800 Subject: [PATCH 29/37] moved base class documentation above __init__ such that sphinx autodocs finds it and generates it --- sparsecoding/inference/iht.py | 30 +++++---- sparsecoding/inference/ista.py | 52 ++++++++-------- sparsecoding/inference/lca.py | 68 +++++++++++---------- sparsecoding/inference/lsm.py | 66 ++++++++++---------- sparsecoding/inference/mp.py | 24 ++++---- sparsecoding/inference/omp.py | 24 ++++---- sparsecoding/inference/pytorch_optimizer.py | 36 +++++------ sparsecoding/inference/vanilla.py | 60 +++++++++--------- 8 files changed, 182 insertions(+), 178 deletions(-) diff --git a/sparsecoding/inference/iht.py b/sparsecoding/inference/iht.py index 467cfc5..6c6f8f0 100644 --- a/sparsecoding/inference/iht.py +++ b/sparsecoding/inference/iht.py @@ -9,25 +9,23 @@ class IHT(InferenceMethod): Infer coefficients for each image in data using elements dictionary. Method description can be traced to "Iterative Hard Thresholding for Compressed Sensing" (T. Blumensath & M. E. Davies, 2009) + + Parameters + ---------- + sparsity : scalar (1,) + Sparsity of the solution. The number of active coefficients will be set + to ceil(sparsity * data_dim) at the end of each iterative update. + n_iter : scalar (1,) default=100 + number of iterations to run for an inference method + return_all_coefficients : string (1,) default=False + returns all coefficients during inference procedure if True + user beware: if n_iter is large, setting this parameter to True + can result in large memory usage/potential exhaustion. This function typically used for + debugging + solver : default=None """ def __init__(self, sparsity, n_iter=10, solver=None, return_all_coefficients=False): - """ - - Parameters - ---------- - sparsity : scalar (1,) - Sparsity of the solution. The number of active coefficients will be set - to ceil(sparsity * data_dim) at the end of each iterative update. - n_iter : scalar (1,) default=100 - number of iterations to run for an inference method - return_all_coefficients : string (1,) default=False - returns all coefficients during inference procedure if True - user beware: if n_iter is large, setting this parameter to True - can result in large memory usage/potential exhaustion. This function typically used for - debugging - solver : default=None - """ super().__init__(solver) self.n_iter = n_iter self.sparsity = sparsity diff --git a/sparsecoding/inference/ista.py b/sparsecoding/inference/ista.py index 42bd21b..dec12d1 100644 --- a/sparsecoding/inference/ista.py +++ b/sparsecoding/inference/ista.py @@ -4,6 +4,33 @@ class ISTA(InferenceMethod): + """ + Iterative shrinkage-thresholding algorithm for solving LASSO problems. + + Parameters + ---------- + n_iter : int, default=100 + Number of iterations to run + sparsity_penalty : float, default=0.2 + + stop_early : bool, default=False + Stops dynamics early based on change in coefficents + epsilon : float, default=1e-2 + Only used if stop_early True, specifies criteria to stop dynamics + return_all_coefficients : str, default=False + Returns all coefficients during inference procedure if True + User beware: if n_iter is large, setting this parameter to True + can result in large memory usage/potential exhaustion. This + function typically used for debugging. + solver : default=None + + References + ---------- + [1] Beck, A., & Teboulle, M. (2009). A fast iterative + shrinkage-thresholding algorithm for linear inverse problems. + SIAM journal on imaging sciences, 2(1), 183-202. + """ + def __init__( self, n_iter=100, @@ -13,31 +40,6 @@ def __init__( solver=None, return_all_coefficients=False, ): - """Iterative shrinkage-thresholding algorithm for solving LASSO problems. - - Parameters - ---------- - n_iter : int, default=100 - Number of iterations to run - sparsity_penalty : float, default=0.2 - - stop_early : bool, default=False - Stops dynamics early based on change in coefficents - epsilon : float, default=1e-2 - Only used if stop_early True, specifies criteria to stop dynamics - return_all_coefficients : str, default=False - Returns all coefficients during inference procedure if True - User beware: if n_iter is large, setting this parameter to True - can result in large memory usage/potential exhaustion. This - function typically used for debugging. - solver : default=None - - References - ---------- - [1] Beck, A., & Teboulle, M. (2009). A fast iterative - shrinkage-thresholding algorithm for linear inverse problems. - SIAM journal on imaging sciences, 2(1), 183-202. - """ super().__init__(solver) self.n_iter = n_iter self.sparsity_penalty = sparsity_penalty diff --git a/sparsecoding/inference/lca.py b/sparsecoding/inference/lca.py index ad5023f..61eb0e4 100644 --- a/sparsecoding/inference/lca.py +++ b/sparsecoding/inference/lca.py @@ -4,6 +4,41 @@ class LCA(InferenceMethod): + """ + Method implemented according locally competative algorithm (LCA) + with the ideal soft thresholding function. + + Parameters + ---------- + n_iter : int, default=100 + Number of iterations to run + coeff_lr : float, default=1e-3 + Update rate of coefficient dynamics + threshold : float, default=0.1 + Threshold for non-linearity + stop_early : bool, default=False + Stops dynamics early based on change in coefficents + epsilon : float, default=1e-2 + Only used if stop_early True, specifies criteria to stop dynamics + nonnegative : bool, default=False + Constrain coefficients to be nonnegative + return_all_coefficients : str, {"none", "membrane", "active"}, default="none" + Returns all coefficients during inference procedure if not equal + to "none". If return_all_coefficients=="membrane", membrane + potentials (u) returned. If return_all_coefficients=="active", + active units (a) (output of thresholding function over u) returned. + User beware: if n_iter is large, setting this parameter to True + can result in large memory usage/potential exhaustion. This + function typically used for debugging. + solver : default=None + + References + ---------- + [1] Rozell, C. J., Johnson, D. H., Baraniuk, R. G., & Olshausen, + B. A. (2008). Sparse coding via thresholding and local competition + in neural circuits. Neural computation, 20(10), 2526-2563. + """ + def __init__( self, n_iter=100, @@ -15,39 +50,6 @@ def __init__( return_all_coefficients="none", nonnegative=False, ): - """Method implemented according locally competative algorithm (LCA) - with the ideal soft thresholding function. - - Parameters - ---------- - n_iter : int, default=100 - Number of iterations to run - coeff_lr : float, default=1e-3 - Update rate of coefficient dynamics - threshold : float, default=0.1 - Threshold for non-linearity - stop_early : bool, default=False - Stops dynamics early based on change in coefficents - epsilon : float, default=1e-2 - Only used if stop_early True, specifies criteria to stop dynamics - nonnegative : bool, default=False - Constrain coefficients to be nonnegative - return_all_coefficients : str, {"none", "membrane", "active"}, default="none" - Returns all coefficients during inference procedure if not equal - to "none". If return_all_coefficients=="membrane", membrane - potentials (u) returned. If return_all_coefficients=="active", - active units (a) (output of thresholding function over u) returned. - User beware: if n_iter is large, setting this parameter to True - can result in large memory usage/potential exhaustion. This - function typically used for debugging. - solver : default=None - - References - ---------- - [1] Rozell, C. J., Johnson, D. H., Baraniuk, R. G., & Olshausen, - B. A. (2008). Sparse coding via thresholding and local competition - in neural circuits. Neural computation, 20(10), 2526-2563. - """ super().__init__(solver) self.threshold = threshold self.coeff_lr = coeff_lr diff --git a/sparsecoding/inference/lsm.py b/sparsecoding/inference/lsm.py index 83e5ed5..636610b 100644 --- a/sparsecoding/inference/lsm.py +++ b/sparsecoding/inference/lsm.py @@ -4,6 +4,40 @@ class LSM(InferenceMethod): + """ + Infer latent coefficients generating data given dictionary. + Method implemented according to "Group Sparse Coding with a Laplacian + Scale Mixture Prior" (P. J. Garrigues & B. A. Olshausen, 2010) + + Parameters + ---------- + n_iter : int, default=100 + Number of iterations to run for an optimizer + n_iter_LSM : int, default=6 + Number of iterations to run the outer loop of LSM + beta : float, default=0.01 + LSM parameter used to update lambdas + alpha : float, default=80.0 + LSM parameter used to update lambdas + sigma : float, default=0.005 + LSM parameter used to compute the loss function + sparse_threshold : float, default=10**-2 + Threshold used to discard smallest coefficients in the final + solution SM parameter used to compute the loss function + return_all_coefficients : bool, default=False + Returns all coefficients during inference procedure if True + User beware: If n_iter is large, setting this parameter to True + can result in large memory usage/potential exhaustion. This + function typically used for debugging. + solver : default=None + + References + ---------- + [1] Garrigues, P., & Olshausen, B. (2010). Group sparse coding with + a laplacian scale mixture prior. Advances in neural information + processing systems, 23. + """ + def __init__( self, n_iter=100, @@ -15,38 +49,6 @@ def __init__( solver=None, return_all_coefficients=False, ): - """Infer latent coefficients generating data given dictionary. - Method implemented according to "Group Sparse Coding with a Laplacian - Scale Mixture Prior" (P. J. Garrigues & B. A. Olshausen, 2010) - - Parameters - ---------- - n_iter : int, default=100 - Number of iterations to run for an optimizer - n_iter_LSM : int, default=6 - Number of iterations to run the outer loop of LSM - beta : float, default=0.01 - LSM parameter used to update lambdas - alpha : float, default=80.0 - LSM parameter used to update lambdas - sigma : float, default=0.005 - LSM parameter used to compute the loss function - sparse_threshold : float, default=10**-2 - Threshold used to discard smallest coefficients in the final - solution SM parameter used to compute the loss function - return_all_coefficients : bool, default=False - Returns all coefficients during inference procedure if True - User beware: If n_iter is large, setting this parameter to True - can result in large memory usage/potential exhaustion. This - function typically used for debugging. - solver : default=None - - References - ---------- - [1] Garrigues, P., & Olshausen, B. (2010). Group sparse coding with - a laplacian scale mixture prior. Advances in neural information - processing systems, 23. - """ super().__init__(solver) self.n_iter = n_iter self.n_iter_LSM = n_iter_LSM diff --git a/sparsecoding/inference/mp.py b/sparsecoding/inference/mp.py index 4305976..c402f3b 100644 --- a/sparsecoding/inference/mp.py +++ b/sparsecoding/inference/mp.py @@ -9,22 +9,20 @@ class MP(InferenceMethod): Infer coefficients for each image in data using elements dictionary. Method description can be traced to "Matching Pursuits with Time-Frequency Dictionaries" (S. G. Mallat & Z. Zhang, 1993) + + Parameters + ---------- + sparsity : scalar (1,) + sparsity of the solution + return_all_coefficients : string (1,) default=False + returns all coefficients during inference procedure if True + user beware: if n_iter is large, setting this parameter to True + can result in large memory usage/potential exhaustion. This function typically used for + debugging + solver : default=None """ def __init__(self, sparsity, solver=None, return_all_coefficients=False): - """ - - Parameters - ---------- - sparsity : scalar (1,) - sparsity of the solution - return_all_coefficients : string (1,) default=False - returns all coefficients during inference procedure if True - user beware: if n_iter is large, setting this parameter to True - can result in large memory usage/potential exhaustion. This function typically used for - debugging - solver : default=None - """ super().__init__(solver) self.sparsity = sparsity self.return_all_coefficients = return_all_coefficients diff --git a/sparsecoding/inference/omp.py b/sparsecoding/inference/omp.py index db99427..b11789b 100644 --- a/sparsecoding/inference/omp.py +++ b/sparsecoding/inference/omp.py @@ -10,22 +10,20 @@ class OMP(InferenceMethod): Method description can be traced to: "Orthogonal Matching Pursuit: Recursive Function Approximation with Application to Wavelet Decomposition" (Y. Pati & R. Rezaiifar & P. Krishnaprasad, 1993) + + Parameters + ---------- + sparsity : scalar (1,) + sparsity of the solution + return_all_coefficients : string (1,) default=False + returns all coefficients during inference procedure if True + user beware: if n_iter is large, setting this parameter to True + can result in large memory usage/potential exhaustion. This function typically used for + debugging + solver : default=None """ def __init__(self, sparsity, solver=None, return_all_coefficients=False): - """ - - Parameters - ---------- - sparsity : scalar (1,) - sparsity of the solution - return_all_coefficients : string (1,) default=False - returns all coefficients during inference procedure if True - user beware: if n_iter is large, setting this parameter to True - can result in large memory usage/potential exhaustion. This function typically used for - debugging - solver : default=None - """ super().__init__(solver) self.sparsity = sparsity self.return_all_coefficients = return_all_coefficients diff --git a/sparsecoding/inference/pytorch_optimizer.py b/sparsecoding/inference/pytorch_optimizer.py index 7c13079..bc98c88 100644 --- a/sparsecoding/inference/pytorch_optimizer.py +++ b/sparsecoding/inference/pytorch_optimizer.py @@ -4,24 +4,26 @@ class PyTorchOptimizer(InferenceMethod): - def __init__(self, optimizer_f, loss_f, n_iter=100, solver=None): - """Infer coefficients using provided loss functional and optimizer + """ + Infer coefficients using provided loss functional and optimizer. + + Parameters + ---------- + optimizer : function handle + Pytorch optimizer handle have single parameter: + (coefficients) + where coefficients is of shape [batch_size, n_basis] + loss_f : function handle + Must have parameters: + (data, dictionary, coefficients) + where data is of shape [batch_size, n_features] + and loss_f must return tensor of size [batch_size,] + n_iter : int, default=100 + Number of iterations to run for an optimizer + solver : default=None + """ - Parameters - ---------- - optimizer : function handle - Pytorch optimizer handle have single parameter: - (coefficients) - where coefficients is of shape [batch_size, n_basis] - loss_f : function handle - Must have parameters: - (data, dictionary, coefficients) - where data is of shape [batch_size, n_features] - and loss_f must return tensor of size [batch_size,] - n_iter : int, default=100 - Number of iterations to run for an optimizer - solver : default=None - """ + def __init__(self, optimizer_f, loss_f, n_iter=100, solver=None): super().__init__(solver) self.optimizer_f = optimizer_f self.loss_f = loss_f diff --git a/sparsecoding/inference/vanilla.py b/sparsecoding/inference/vanilla.py index 11bbfa4..28b7be5 100644 --- a/sparsecoding/inference/vanilla.py +++ b/sparsecoding/inference/vanilla.py @@ -4,6 +4,37 @@ class Vanilla(InferenceMethod): + """ + Gradient descent with Euler's method on model in Olshausen & Field + (1997) with laplace prior over coefficients (corresponding to L1 norm + penalty). + + Parameters + ---------- + n_iter : int, default=100 + Number of iterations to run + coeff_lr : float, default=1e-3 + Update rate of coefficient dynamics + sparsity_penalty : float, default=0.2 + + stop_early : bool, default=False + Stops dynamics early based on change in coefficents + epsilon : float, default=1e-2 + Only used if stop_early True, specifies criteria to stop dynamics + return_all_coefficients : str, default=False + Returns all coefficients during inference procedure if True + User beware: If n_iter is large, setting this parameter to True + Can result in large memory usage/potential exhaustion. This + function typically used for debugging. + solver : default=None + + References + ---------- + [1] Olshausen, B. A., & Field, D. J. (1997). Sparse coding with an + overcomplete basis set: A strategy employed by V1?. Vision research, + 37(23), 3311-3325. + """ + def __init__( self, n_iter=100, @@ -14,35 +45,6 @@ def __init__( solver=None, return_all_coefficients=False, ): - """Gradient descent with Euler's method on model in Olshausen & Field - (1997) with laplace prior over coefficients (corresponding to l-1 norm - penalty). - - Parameters - ---------- - n_iter : int, default=100 - Number of iterations to run - coeff_lr : float, default=1e-3 - Update rate of coefficient dynamics - sparsity_penalty : float, default=0.2 - - stop_early : bool, default=False - Stops dynamics early based on change in coefficents - epsilon : float, default=1e-2 - Only used if stop_early True, specifies criteria to stop dynamics - return_all_coefficients : str, default=False - Returns all coefficients during inference procedure if True - User beware: If n_iter is large, setting this parameter to True - Can result in large memory usage/potential exhaustion. This - function typically used for debugging. - solver : default=None - - References - ---------- - [1] Olshausen, B. A., & Field, D. J. (1997). Sparse coding with an - overcomplete basis set: A strategy employed by V1?. Vision research, - 37(23), 3311-3325. - """ super().__init__(solver) self.coeff_lr = coeff_lr self.sparsity_penalty = sparsity_penalty From 3f1912d4280e6de1491e50bb1b72f09d61a4a4b8 Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 23 Jan 2025 16:03:56 -0800 Subject: [PATCH 30/37] modified documentation to adhear to structure used in rest of repository --- sparsecoding/transforms/images.py | 121 ++++++++++++++++-------------- sparsecoding/transforms/whiten.py | 28 ++++--- 2 files changed, 83 insertions(+), 66 deletions(-) diff --git a/sparsecoding/transforms/images.py b/sparsecoding/transforms/images.py index 9e0f20b..521f1f0 100644 --- a/sparsecoding/transforms/images.py +++ b/sparsecoding/transforms/images.py @@ -39,12 +39,15 @@ def whiten_images(images: torch.Tensor, algorithm: str, stats: Dict = None, **kw Parameters ---------- - images: tensor of shape (N, C, H, W) - algorithm: what whitening transform we want to use - stats: dictionary of dataset statistics needed for whitening transformations + images : torch.Tensor + Tensor of shape (N, C, H, W) + algorithm : str + What whitening transform we want to use + stats : Dict, default=None + Dictionary of dataset statistics needed for whitening transformations Returns - ---------- + ------- Tensor of whitened data in shape (N, C, H, W) """ @@ -72,13 +75,15 @@ def compute_image_whitening_stats(images: torch.Tensor) -> Dict: Parameters ---------- - images: tensor of shape (N, C, H, W) - n_components: Number of principal components to keep. If None, keep all components. - If int, keep that many components. If float between 0 and 1, - keep components that explain that fraction of variance. + images : torch.Tensor + Tensor of shape (N, C, H, W) + n_components : + Number of principal components to keep. If None, keep all components. + If int, keep that many components. If float between 0 and 1, + keep components that explain that fraction of variance. Returns - ---------- + ------- Dictionary containing whitening statistics (eigenvalues, eigenvectors, mean) """ check_images(images) @@ -92,11 +97,13 @@ def create_frequency_filter(image_size: int, f0_factor: float = 0.4) -> torch.Te Parameters ---------- - image_size: Size of the square image - f0_factor: Factor for determining the cutoff frequency (default 0.4) + image_size : int + Size of the square image + f0_factor : float, default=0.4 + Factor for determining the cutoff frequency Returns - ---------- + ------- torch.Tensor: Frequency domain filter """ fx = torch.linspace(-image_size / 2, image_size / 2 - 1, image_size) @@ -117,11 +124,13 @@ def get_cached_filter(image_size: int, f0_factor: float = 0.4) -> torch.Tensor: Parameters ---------- - image_size: Size of the square image - f0_factor: Factor for determining the cutoff frequency + image_size : int + Size of the square image + f0_factor : float, default=0.4 + Factor for determining the cutoff frequency Returns - ---------- + ------- torch.Tensor: Cached frequency domain filter """ return create_frequency_filter(image_size, f0_factor) @@ -133,11 +142,13 @@ def normalize_variance(tensor: torch.Tensor, target_variance: float = 1.0) -> to Parameters ---------- - tensor: Input tensor - target_variance: Desired variance after normalization + tensor : torch.Tensor + Input tensor + target_variance : float, default=1.0 + Desired variance after normalization Returns - ---------- + ------- torch.Tensor: Normalized tensor """ @@ -156,12 +167,15 @@ def whiten_channel(channel: torch.Tensor, filt: torch.Tensor, target_variance: f Parameters ---------- - channel: Single channel image tensor - filt: Frequency domain filter - target_variance: Target variance for normalization + channel : torch.Tensor + Single channel image tensor + filt : torch.Tensor + Frequency domain filter + target_variance : float, default=1.0 + Target variance for normalization Returns - ---------- + ------- torch.Tensor: Whitened channel """ @@ -189,12 +203,15 @@ def frequency_whitening(images: torch.Tensor, target_variance: float = 0.1, f0_f Parameters ---------- - images: Input images of shape (N, C, H, W) - target_variance: Target variance for normalization - f0_factor: Factor for determining filter cutoff frequency + images : torch.Tensor + Input images of shape (N, C, H, W) + target_variance : float, default=0.1 + Target variance for normalization + f0_factor : float, default = 0.4 + Factor for determining filter cutoff frequency Returns - ---------- + ------- torch.Tensor: Whitened images """ _, _, H, W = images.shape @@ -216,19 +233,20 @@ class WhiteningTransform(object): """ A PyTorch transform for image whitening that can be used in a transform pipeline. Supports frequency, PCA, and ZCA whitening methods. + + Parameters + ---------- + algorithm : str + One of ['frequency', 'pca', 'zca', 'cholesky] + stats : Dict or None, default=None + Pre-computed statistics for PCA/ZCA whitening + compute_stats : bool, default=False + If True, will compute stats on first batch seen + **kwargs : + Additional arguments passed to whitening function """ def __init__(self, algorithm: str = "zca", stats: Optional[Dict] = None, compute_stats: bool = False, **kwargs): - """ - Initialize whitening transform. - - Parameters - ---------- - algorithm: One of ['frequency', 'pca', 'zca', 'cholesky] - stats: Pre-computed statistics for PCA/ZCA whitening - compute_stats: If True, will compute stats on first batch seen - **kwargs: Additional arguments passed to whitening function - """ self.algorithm = algorithm self.stats = stats self.compute_stats = compute_stats @@ -240,11 +258,12 @@ def __call__(self, images: torch.Tensor) -> torch.Tensor: Parameters ---------- - images: Input images of shape [N, C, H, W] or [C, H, W] + images : torch.Tensor + Input images of shape [N, C, H, W] or [C, H, W] Returns - ---------- - Whitened images of same shape as input + ------- + Whitened images of same shape as input """ # Add batch dimension if necessary if images.dim() == 3: @@ -281,10 +300,8 @@ def sample_random_patches( num_patches : int Number of patches to sample. image : Tensor, shape [*, C, H, W] - where: - C is the number of channels, - H is the image height, - W is the image width. + where: C is the number of channels, H is the image height, + W is the image width. Returns ------- @@ -333,10 +350,8 @@ def patchify( patch_size : int Patch side length. image : Tensor, shape [*, C, H, W] - where: - C is the number of channels, - H is the image height, - W is the image width. + where: C is the number of channels, H is the image height, + W is the image width. stride : int, optional Stride between patches in pixel space. If not specified, set to `patch_size` (non-overlapping patches). @@ -345,10 +360,8 @@ def patchify( ------- patches : Tensor, shape [*, N, C, P, P] Non-overlapping patches taken from the input image, - where: - P is the patch size, - N is the number of patches, equal to H//P * W//P, - C is the number of channels of the input image. + where: P is the patch size, N is the number of patches, equal + to H//P * W//P, C is the number of channels of the input image. """ leading_dims = image.shape[:-3] C, H, W = image.shape[-3:] @@ -394,10 +407,8 @@ def quilt( Width for the reconstructed image. patches : Tensor, shape [*, N, C, P, P] Non-overlapping patches from an input image, - where: - P is the patch size, - N is the number of patches, - C is the number of channels in the image. + where: P is the patch size, N is the number of patches, + C is the number of channels in the image. Returns ------- diff --git a/sparsecoding/transforms/whiten.py b/sparsecoding/transforms/whiten.py index 4206adc..c2ad175 100644 --- a/sparsecoding/transforms/whiten.py +++ b/sparsecoding/transforms/whiten.py @@ -9,10 +9,11 @@ def compute_whitening_stats(X: torch.Tensor): Parameters ---------- - X: Input data of size [N, D] + X : torch.Tensor + Input data of size [N, D] Returns - ---------- + ------- Dictionary containing whitening statistics (eigenvalues, eigenvectors, mean) """ @@ -43,20 +44,25 @@ def whiten( Parameters ---------- - X: Input data of shape [N, D] where N are unique data elements of dimensionality D - algorithm: Whitening transform we want to apply, one of ['zca', 'pca', or 'cholesky'] - stats: Dict containing precomputed whitening statistics (mean, eigenvectors, eigenvalues) - n_components: Number of principal components to keep. If None, keep all components. - If int, keep that many components. If float between 0 and 1, - keep components that explain that fraction of variance. - epsilon: Optional small constant to prevent division by zero + X : torch.Tensor + Input data of shape [N, D] where N are unique data elements of dimensionality D + algorithm : str, default="zca" + Whitening transform we want to apply, one of ['zca', 'pca', or 'cholesky'] + stats : Dict, default=None + Dict containing precomputed whitening statistics (mean, eigenvectors, eigenvalues) + n_components : float, int, default=None + Number of principal components to keep. If None, keep all components. + If int, keep that many components. If float between 0 and 1, + keep components that explain that fraction of variance. + epsilon : float, default=0.0 + Optional small constant to prevent division by zero Returns - ---------- + ------- Whitened data of shape [N, D] Notes - ---------- + ----- See examples/Data_Whitening.ipynb for usage examples, and brief discussion about the different whitening methods See https://arxiv.org/abs/1512.00809 for extensive details on whitening transformations From 240e8e91eca0fc2b55c2f9bba9e8716365f8a266 Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 23 Jan 2025 16:05:30 -0800 Subject: [PATCH 31/37] make api documentation match new directory structure/file naming and exlude test files from autodocs --- docs/api.rst | 2 +- docs/conf.py | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 61f2801..fdc1a77 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -61,7 +61,7 @@ Data transformations Image transformations --------------------- -.. automodule:: sparsecoding.transforms.patch +.. automodule:: sparsecoding.transforms.images :members: :undoc-members: :show-inheritance: \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 9ab4d69..6f3a0c9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,6 +21,18 @@ 'sphinx.ext.autosummary', ] +autodoc_default_options = { + 'members': True, + 'undoc-members': True, + 'show-inheritance': True, + 'inherited-members': False, +} + +exclude_patterns = [ + '**/test_*', + '**/*_test.py', +] + templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] @@ -29,5 +41,4 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output html_theme = 'sphinx_rtd_theme' -html_static_path = ['_static'] html_baseurl = os.environ.get("READTHEDOCS_CANONICAL_URL", "/") From dbf804a4d676cabe005ea4590948028710dbc83c Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 23 Jan 2025 16:10:01 -0800 Subject: [PATCH 32/37] flake --- sparsecoding/transforms/images.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sparsecoding/transforms/images.py b/sparsecoding/transforms/images.py index 521f1f0..cd48994 100644 --- a/sparsecoding/transforms/images.py +++ b/sparsecoding/transforms/images.py @@ -77,10 +77,6 @@ def compute_image_whitening_stats(images: torch.Tensor) -> Dict: ---------- images : torch.Tensor Tensor of shape (N, C, H, W) - n_components : - Number of principal components to keep. If None, keep all components. - If int, keep that many components. If float between 0 and 1, - keep components that explain that fraction of variance. Returns ------- @@ -242,7 +238,7 @@ class WhiteningTransform(object): Pre-computed statistics for PCA/ZCA whitening compute_stats : bool, default=False If True, will compute stats on first batch seen - **kwargs : + **kwargs Additional arguments passed to whitening function """ @@ -360,7 +356,7 @@ def patchify( ------- patches : Tensor, shape [*, N, C, P, P] Non-overlapping patches taken from the input image, - where: P is the patch size, N is the number of patches, equal + where: P is the patch size, N is the number of patches, equal to H//P * W//P, C is the number of channels of the input image. """ leading_dims = image.shape[:-3] From e58410c65a1ecb0de28cdc2e2484dcb87c741512 Mon Sep 17 00:00:00 2001 From: belsten Date: Thu, 23 Jan 2025 16:12:44 -0800 Subject: [PATCH 33/37] again, moved triple quote docstring to after definition of class (as opposed to in the __init__) --- sparsecoding/models.py | 44 +++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/sparsecoding/models.py b/sparsecoding/models.py index 5f19db1..1316dbd 100644 --- a/sparsecoding/models.py +++ b/sparsecoding/models.py @@ -5,31 +5,31 @@ class SparseCoding(torch.nn.Module): + """Class for learning a sparse code via dictionary learning + + Parameters + ---------- + inference_method : sparsecoding.InferenceMethod + Method for inferring coefficients for each image given the + dictionary + n_basis : int + Number of basis functions in dictionary + n_features : int + Number of features in data + sparsity_penalty : float, default=0.2 + Sparsity penalty + dictionary_lr : float, default=1e-2 + Learning rate of dictionary update + device : torch.device, default=torch.device("cpu") + Which device to utilize + check_for_dictionary_nan : bool, default=False + Flag to check for nans in the dictionary after gradient + updates and normalizations. Raises ValueError if nan + found + """ def __init__(self, inference_method, n_basis, n_features, sparsity_penalty=0.2, device=None, check_for_dictionary_nan=False, **kwargs): - """Class for learning a sparse code via dictionary learning - - Parameters - ---------- - inference_method : sparsecoding.InferenceMethod - Method for inferring coefficients for each image given the - dictionary - n_basis : int - Number of basis functions in dictionary - n_features : int - Number of features in data - sparsity_penalty : float, default=0.2 - Sparsity penalty - dictionary_lr : float, default=1e-2 - Learning rate of dictionary update - device : torch.device, default=torch.device("cpu") - Which device to utilize - check_for_dictionary_nan : bool, default=False - Flag to check for nans in the dictionary after gradient - updates and normalizations. Raises ValueError if nan - found - """ super(SparseCoding, self).__init__() self.inference_method = inference_method self.n_basis = n_basis From 5c169773537dfee46ed839c4872bb34680da92f8 Mon Sep 17 00:00:00 2001 From: belsten Date: Tue, 28 Jan 2025 13:10:11 -0800 Subject: [PATCH 34/37] update contributing documentation to new testing framework (pytest). Improve details of submitting PRs. Add information for reveiwers on how to merge pull requests. --- docs/contributing.rst | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/docs/contributing.rst b/docs/contributing.rst index 16b2981..95791bd 100644 --- a/docs/contributing.rst +++ b/docs/contributing.rst @@ -2,12 +2,14 @@ Contributing ============ -We welcome all contributions! +We welcome all contributions to this project! Whether it’s reporting bugs, suggesting features, +fixing issues, or improving documentation, your input is invaluable. Bug Reporting ------------- -If you encounter a bug, please report it by creating an issue on GitHub. +If you encounter a bug, please report it by creating an issue on GitHub. Include as much detail as +possible to help us reproduce and fix the issue. Adding Features or Fixing Bugs ------------------------------ @@ -15,24 +17,44 @@ Adding Features or Fixing Bugs If you’ve identified a new feature to add or a bug you can fix, follow these steps: #. Clone the ``main`` branch. -#. Create a new branch to work on your changes. +#. Create a new branch to work on your changes. Use a descriptive name for your branch, such as + ``fix-issue-123`` or ``feature-add-logging``. #. Use ``add``, ``commit``, and ``push`` to save your changes to the new branch. #. Create a pull request (PR). See the "Submitting a Pull Request" section for more details. Submitting a Pull Request ------------------------- - -#. If applicable, write unit tests for your changes and add them to the - `tests directory `_. -#. Verify that all tests pass by running ``python -m unittest discover tests -vvv``. +To ensure a smooth review process and maintain high code quality, follow these guidelines when +submitting a PR: + +#. If applicable, write unit tests for your changes. We use the + `pytest `_ framework. Every Python module, extension module, + or subpackage in the sparsecoding package directory should have a corresponding ``test_.py`` + file. Pytest examines these files for test methods (named ``test*``) and test classes (named + ``Test*``). Add your tests to the appropriate ``test_*.py`` (create this file if it doesn't + already exist). +#. Verify that all tests pass by running ``pytest sparsecoding/`` from the base repository directory. #. Ensure your code adheres to the formatting guidelines specified in `PEP8 `_ and validated by `flake8 `_. -#. Provide a concise and descriptive title for your PR that summarizes the changes made in your branch. +#. Prepare a detailed and clear PR description: + + * Summarize the purpose of the PR and the changes made. + + * Include any relevant context, such as links to related issues or discussions. + + * Specify testing steps or considerations for reviewers. + #. Submit your PR and assign reviewers as necessary. +#. Reviewers: Use squash and merge when merging the PR. + + * Set the merge description to match the PR description. + + * Squash commits into a single commit to maintain a clean project history. + Coding Style Guidelines ------------------------- +----------------------- We follow the `NumPy documentation standards `_. From f8429e6e51c8b2c4f66c7a0a2d84fb62f6561e4a Mon Sep 17 00:00:00 2001 From: belsten Date: Mon, 3 Feb 2025 13:03:09 -0800 Subject: [PATCH 35/37] Slight wording adjustment --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 81de545..a1a568a 100644 --- a/README.md +++ b/README.md @@ -5,9 +5,7 @@ https://sparsecoding.readthedocs.io/) `sparsecoding` is a Python library developed by UC Berkeley's [Redwood Center for Theoretical Neuroscience (RCTN)](https://redwood.berkeley.edu). It provides efficient, batched, and GPU-compatible [PyTorch](https://github.com/pytorch/pytorch) implementations for sparse coding related-algorithms, including dictionary learning, inference, and data processing. -Historically, sparse coding has been largely focused on learning sparse representations of images and we provide visualization and transformation tools to work with such data. However, we’ve tried to structure the transformation, dictionary learning methods, and inference methods in a manner that is data-agnostic, making them applicable to a wide range of use cases. - -We believe that sharing code within the scientific community is an important part of science and we hope that the research community finds this library useful. +Historically, sparse coding has been largely focused on learning sparse representations of images, and we provide visualization and transformation tools to work with such data. However, we structure the transformation, dictionary learning methods, and inference methods in a manner that is data-agnostic, making them applicable to a wide range of use cases. ## Features From 454c7e89cc3711192ee0b87dbb94a36faa2f8678 Mon Sep 17 00:00:00 2001 From: belsten Date: Mon, 3 Feb 2025 13:12:35 -0800 Subject: [PATCH 36/37] comment syntax adjustmented for consistancy --- sparsecoding/inference/iht.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sparsecoding/inference/iht.py b/sparsecoding/inference/iht.py index 6c6f8f0..39ee55d 100644 --- a/sparsecoding/inference/iht.py +++ b/sparsecoding/inference/iht.py @@ -12,12 +12,12 @@ class IHT(InferenceMethod): Parameters ---------- - sparsity : scalar (1,) + sparsity : float Sparsity of the solution. The number of active coefficients will be set to ceil(sparsity * data_dim) at the end of each iterative update. - n_iter : scalar (1,) default=100 + n_iter : int, default=10 number of iterations to run for an inference method - return_all_coefficients : string (1,) default=False + return_all_coefficients : str, default=False returns all coefficients during inference procedure if True user beware: if n_iter is large, setting this parameter to True can result in large memory usage/potential exhaustion. This function typically used for From 5ce17a20cb15bfc9003991a239aa3181be701d0b Mon Sep 17 00:00:00 2001 From: belsten Date: Fri, 7 Feb 2025 15:37:04 -0800 Subject: [PATCH 37/37] install instructions using pyproject.toml --- docs/install.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/install.rst b/docs/install.rst index e71e79f..5514996 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -8,8 +8,7 @@ The quickest way to install the library is by cloning it directly from GitHub: git clone https://github.com/rctn/sparsecoding.git cd sparsecoding - pip install -e sparsecoding - pip install -r requirements.txt + pip install -e ".[all]" The last command installs the dependencies required for the RCTN sparse coding library, including: