Skip to main content

aind-dynamic-foraging-models

License Code Style semantic-release: angular Interrogate Coverage Python

AIND library for generative (RL) and descriptive (logistic regression) models of dynamic foraging tasks.

User documentation available on readthedocs.

Reinforcement Learning (RL) models with Maximum Likelihood Estimation (MLE) fitting

Overview

RL agents that can perform any dynamic foraging task in aind-behavior-gym and can fit behavior using MLE.

image

Code structure

image

Implemented foragers

image
  • ForagerQLearning: Simple Q-learning agents that incrementally update Q-values.
    • Available agent_kwargs:
        number_of_learning_rate: Literal[1, 2] = 2,
        number_of_forget_rate: Literal[0, 1] = 1,
        choice_kernel: Literal["none", "one_step", "full"] = "none",
        action_selection: Literal["softmax", "epsilon-greedy"] = "softmax",
      
  • ForagerLossCounting: Loss counting agents with probabilistic loss_count_threshold.
    • Available agent_kwargs:
        win_stay_lose_switch: Literal[False, True] = False,
        choice_kernel: Literal["none", "one_step", "full"] = "none",
      
  • Action selections (readthedoc)

Here is the full list of available foragers:

image image

Usage

RL model playground

Play with the generative models here.

image

Logistic regression

See this demo notebook.

Choosing logistic regression models

Su 2022

Untitled

$$ logit(p(c_r)) \sim RewardedChoice+UnrewardedChoice $$

Bari 2019

Untitled

Untitled

$$ logit(p(c_r)) \sim RewardedChoice+Choice $$

Hattori 2019

Untitled

$$ logit(p(c_r)) \sim RewardedChoice+UnrewardedChoice+Choice $$

Miller 2021

Untitled

$$ logit(p(c_r)) \sim Choice + Reward+ Choice*Reward $$

Encodings

  • Ignored trials are removed
choice reward Choice Reward RewardedChoice UnrewardedChoice Choice * Reward
L yes -1 1 -1 0 -1
L no -1 -1 0 -1 1
R yes 1 1 1 0 1
L yes -1 1 -1 0 -1
R no 1 -1 0 1 -1
R yes 1 1 1 0 1
L no -1 -1 0 -1 1

Some observations:

  1. $RewardedChoice$ and $UnrewardedChoice$ are orthogonal
  2. $Choice = RewardedChoice + UnrewardedChoice$
  3. $Choice * Reward = RewardedChoice - UnrewardedChoice$

Comparison

Su 2022 Bari 2019 Hattori 2019 Miller 2021
Equivalent to RewC + UnrC RewC + (RewC + UnrC) RewC + UnrC + (RewC + UnrC) (RewC + UnrC) + (RewC - UnrC) + Rew
Severity of multicollinearity Not at all Medium Severe Slight
Interpretation Like a RL model with different learning rates on reward and unrewarded trials. Like a RL model that only updates on rewarded trials, plus a choice kernel (tendency to repeat previous choices). Like a RL model that has different learning rates on reward and unrewarded trials, plus a choice kernel (the full RL model from the same paper). Like a RL model that has symmetric learning rates for rewarded and unrewarded trials, plus a choice kernel. However, the $Reward $ term seems to be a strawman assumption, as it means “if I get reward on any side, I’ll choose the right side more”, which doesn’t make much sense.
Conclusion Probably the best Okay Not good due to the severe multicollinearity Good

Regularization and optimization

The choice of optimizer depends on the penality term, as listed here.

  • lbfgs - [l2, None]
  • liblinear - [l1, l2]
  • newton-cg - [l2, None]
  • newton-cholesky - [l2, None]
  • sag - [l2, None]
  • saga - [elasticnet, l1, l2, None]

See also

Installation

To install the package (logistic regression only), run

pip install aind-dynamic-foraging-models

To install the package with RL models, run

pip install aind-dynamic-foraging-models[rl]

To develop the code, clone the repo to your local machine, and run

pip install -e .[dev]

Contributing

Linters and testing

There are several libraries used to run linters, check documentation, and run tests.

  • Please test your changes using the coverage library, which will run the tests and log a coverage report:
coverage run -m unittest discover && coverage report
  • Use interrogate to check that modules, methods, etc. have been documented thoroughly:
interrogate .
  • Use flake8 to check that code is up to standards (no unused imports, etc.):
flake8 .
  • Use black to automatically format the code into PEP standards:
black .
  • Use isort to automatically sort import statements:
isort .

Pull requests

For internal members, please create a branch. For external members, please fork the repository and open a pull request from the fork. We'll primarily use Angular style for commit messages. Roughly, they should follow the pattern:

<type>(<scope>): <short summary>

where scope (optional) describes the packages affected by the code changes and type (mandatory) is one of:

  • build: Changes that affect build tools or external dependencies (example scopes: pyproject.toml, setup.py)
  • ci: Changes to our CI configuration files and scripts (examples: .github/workflows/ci.yml)
  • docs: Documentation only changes
  • feat: A new feature
  • fix: A bugfix
  • perf: A code change that improves performance
  • refactor: A code change that neither fixes a bug nor adds a feature
  • test: Adding missing tests or correcting existing tests

Semantic Release

The table below, from semantic release, shows which commit message gets you which release type when semantic-release runs (using the default configuration):

Commit message Release type
fix(pencil): stop graphite breaking when too much pressure applied Patch Fix Release, Default release
feat(pencil): add 'graphiteWidth' option Minor Feature Release
perf(pencil): remove graphiteWidth option

BREAKING CHANGE: The graphiteWidth option has been removed.
The default graphite width of 10mm is always used for performance reasons.
Major Breaking Release
(Note that the BREAKING CHANGE: token must be in the footer of the commit)

Documentation

To generate the rst files source files for documentation, run

sphinx-apidoc -o doc_template/source/ src 

Then to create the documentation HTML files, run

sphinx-build -b html doc_template/source/ doc_template/build/html

More info on sphinx installation can be found here.

Hierarchical Bayesian fitting

aind_dynamic_foraging_models.hierarchical_bayes fits the foragers as hierarchical Bayesian models (population → subject → session) with NumPyro, as a partially-pooled counterpart to the per-session MLE fitting in generative_model.

pip install aind-dynamic-foraging-models[bayes]

GLM-HMM

aind_dynamic_foraging_models.glm_hmm fits an input-driven HMM with GLM emissions (Ashwood et al. 2022, Nat Neurosci 25:201) over left / right / ignore choices, on dynamax.

pip install aind-dynamic-foraging-models[glmhmm]
  • Two emissions, both exactly normalised over the three outcomes: hurdle (per state, an engagement GLM on unsigned history and a side GLM on signed history) and reference (per state, one multinomial GLM with ignore as the zero-logit class, as in Faeze's ssm fits). How they differ, and which to use: glm_hmm/README.md.
  • Regressors (design.py): RewC and UnrC lags (signed), Ignored and Rewarded lags (unsigned), and a bias; trial 0 of every session sees the bias alone.
  • Fitting (model.py): EM over many variable-length sessions, bucketed by length with exact masking. The emission M-step is exact Newton with a Gaussian prior; pi and A use a Dirichlet MAP. Priors are arguments, so one model serves a near-flat global fit (GLOBAL_PRIOR) and per-subject MAP refits started from it (SUBJECT_PRIOR).
  • Scoring: predictive_log_probs is the forward filter's one-step-ahead log p(y_t | y_<t) per class. It is the held-out quantity, and it never uses later trials. state_posteriors gives filtered and smoothed posteriors and Viterbi paths.
  • tfp-nightly is pinned to one build in the extra: dynamax leaves it unpinned, and only some nightlies work with jax 0.6.1 and numpy 2.4.
  • Device: float64 on the CPU by default; AIND_GLMHMM_DEVICE=gpu moves the fits to a GPU. GPU linear solves need the CUDA solver libraries pinned, as model._compute explains. A GPU is faster for a large pooled fit, but not for one mouse's refit.
  • Validation: glm_hmm/recovery/ simulates from known parameters and refits them, and cross-checks the likelihood against ssm (RESULTS.md). The study version, including a factorial of designed strategies, is AllenNeuralDynamics/aind-dynamic-foraging-bfm-studies#50.

Metadata

Release files for aind-dynamic-foraging-models 0.23.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aind-dynamic-foraging-models 0.23.0
File Size Uploaded Provenance Actions
aind_dynamic_foraging_models-0.23.0.tar.gz 7.0 MB Without provenance Details for aind_dynamic_foraging_models-0.23.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for aind-dynamic-foraging-models 0.23.0
File Interpreter ABI Platform Actions
aind_dynamic_foraging_models-0.23.0-py3-none-any.whl Python 3 none any Details for aind_dynamic_foraging_models-0.23.0-py3-none-any.whl

Total release size: 7.2 MB

Release files / aind_dynamic_foraging_models-0.23.0.tar.gz

Download URL aind_dynamic_foraging_models-0.23.0.tar.gz
Size 7.0 MB
Tags Source
SHA-256 checksum
How to use checksums
96e45f3ab7c8518b8970bab4cbbc5ca8faf40427637e2ea13b7d9eb3aa705d9b
BLAKE2b-256 checksum
How to use checksums
3c130be0c07c71598fdf4f24093939207010707d70486694a74607534e301368
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Release files / aind_dynamic_foraging_models-0.23.0-py3-none-any.whl

Download URL aind_dynamic_foraging_models-0.23.0-py3-none-any.whl
Size 240.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e32a97b4be039782c7409734886513d0c7871499610e95a4e6cfcf45a2489929
BLAKE2b-256 checksum
How to use checksums
fbd5e34a007d2703b2be5bc4e093fd5b2bc04ee4f2c66443f4e44fb2f3732c6e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.16

Security for aind-dynamic-foraging-models 0.23.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.23.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page