aind_dynamic_foraging_models.generative_model package¶
Subpackages¶
- aind_dynamic_foraging_models.generative_model.params package
- Submodules
- aind_dynamic_foraging_models.generative_model.params.forager_loss_counting_params module
- aind_dynamic_foraging_models.generative_model.params.forager_q_learning_params module
- aind_dynamic_foraging_models.generative_model.params.util module
- Module contents
ParamsSymbolsParamsSymbols.biasLParamsSymbols.choice_biasParamsSymbols.choice_history_weightParamsSymbols.choice_kernel_inverse_temperatureParamsSymbols.choice_kernel_relative_weightParamsSymbols.choice_kernel_step_sizeParamsSymbols.epsilonParamsSymbols.evidence_time_constantParamsSymbols.expected_uncertainty_step_sizeParamsSymbols.fast_choice_trace_step_sizeParamsSymbols.fast_choice_trace_weightParamsSymbols.forget_rate_unchosenParamsSymbols.forgetting_factorParamsSymbols.gambler_fallacy_retention_logitParamsSymbols.gambler_fallacy_weightParamsSymbols.habit_retention_logitParamsSymbols.habit_weightParamsSymbols.learn_rateParamsSymbols.learn_rate_actorParamsSymbols.learn_rate_criticParamsSymbols.learn_rate_rewParamsSymbols.learn_rate_unrewParamsSymbols.loss_count_threshold_meanParamsSymbols.loss_count_threshold_stdParamsSymbols.negative_learning_rateParamsSymbols.negative_learning_rate_step_sizeParamsSymbols.perseveration_bonusParamsSymbols.perseveration_learning_rateParamsSymbols.perseveration_weightParamsSymbols.positive_learning_rateParamsSymbols.reset_to_thresholdParamsSymbols.reward_evidence_weightParamsSymbols.reward_learning_rateParamsSymbols.reward_retention_logitParamsSymbols.reward_weightParamsSymbols.slow_choice_trace_step_sizeParamsSymbols.slow_choice_trace_weightParamsSymbols.softmax_inverse_temperatureParamsSymbols.subjective_reward_probabilityParamsSymbols.subjective_switch_probabilityParamsSymbols.threshold
Submodules¶
aind_dynamic_foraging_models.generative_model.act_functions module¶
aind_dynamic_foraging_models.generative_model.base module¶
Base class for DynamicForagingAgent with MLE fitting
- class aind_dynamic_foraging_models.generative_model.base.DynamicForagingAgentMLEBase(agent_kwargs: dict = {}, params: dict = {}, **kwargs)[source]¶
Bases:
DynamicForagingAgentBaseBase class of “DynamicForagingAgentBase” + “MLE fitting”
- act(observation)[source]¶
Chooses an action based on the current observation. I just copy and paste this from DynamicForagingAgentBase here for clarity.
- Parameters:
observation – The current observation from the environment.
- Returns:
The action chosen by the agent.
- Return type:
action
- fit(fit_choice_history, fit_reward_history, fit_bounds_override: dict | None = {}, clamp_params: dict | None = None, k_fold_cross_validation: int | None = None, DE_kwargs: dict | None = {'workers': 1})[source]¶
Fit the model to the data using differential evolution.
It handles fit_bounds_override and clamp_params as follows: 1. It will first clamp the parameters specified in clamp_params 2. For other parameters, if it is specified in fit_bounds_override, the specified
bound will be used; otherwise, the bound in the model’s ParamFitBounds will be used.
For example, if params_to_fit and clamp_params are all empty, all parameters will be fitted with default bounds in the model’s ParamFitBounds.
Supports both single-session and multi-session fitting.
Multi-session format is a list/tuple of per-session 1D arrays. In multi-session fitting, latent states (Q-values, choice kernels, etc.) are reset at the start of each session.
- Parameters:
fit_choice_history (np.ndarray or List[np.ndarray]) – Choice history for fitting. Can be either: - A single 1D array for single-session fitting (backward compatible) - A list of 1D arrays for multi-session fitting, one array per session
fit_reward_history (np.ndarray or List[np.ndarray]) – Reward history for fitting. Must match the format of fit_choice_history.
fit_bounds_override (dict, optional) – Override the default bounds for fitting parameters in ParamFitBounds, by default {}
clamp_params (dict, optional) – Specify parameters to fix to certain values, by default {}
k_fold_cross_validation (Optional[int], optional) –
Whether to do cross-validation, by default None (no cross-validation). If k_fold_cross_validation > 1, it will do k-fold cross-validation and return the prediction accuracy of the test set for model comparison. Cross-validation behavior: - Single-session input: trial-level k-fold CV (backward compatible) - Multi-session input: session-level k-fold CV (entire sessions held out)
Requires n_sessions >= k_fold_cross_validation.
DE_kwargs (dict, optional) –
kwargs for differential_evolution, by default {‘workers’: 1} For example:
- workersint
Number of workers for differential evolution, by default 1. In CO, fitting a typical session of 1000 trials takes:
1 worker: ~100 s 4 workers: ~35 s 8 workers: ~22 s 16 workers: ~20 s
(see https://github.com/AllenNeuralDynamics/aind-dynamic-foraging-models/blob/22075b85360c0a5db475a90bcb025deaa4318f05/notebook/demo_rl_mle_fitting_new_test_time.ipynb) # noqa E501 That is to say, the parallel speedup in DE is sublinear. Therefore, given a constant number of total CPUs, it is more efficient to parallelize on the level of session, instead of on DE’s workers.
- Returns:
fitting_result (OptimizeResult) – The fitting result object containing optimized parameters and statistics.
fitting_result_cross_validation (dict or None) – Cross-validation results if k_fold_cross_validation is specified, else None.
- get_choice_history()[source]¶
Return the history of actions in format that is compatible with other library such as aind_dynamic_foraging_basic_analysis
- get_fitting_result_dict()[source]¶
Return the fitting result in a json-compatible dict for uploading to docDB etc.
- get_latent_variables()[source]¶
Return the latent variables of the agent
This is agent-specific and should be implemented by the subclass.
- get_p_reward()[source]¶
Return the reward probabilities for each arm in each trial which is compatible with other library such as aind_dynamic_foraging_basic_analysis
- get_params_str(if_latex=True, if_value=True, decimal=3)[source]¶
Get string of the model parameters
- Parameters:
if_latex (bool, optional) – if True, return the latex format of the parameters, by default True
if_value (bool, optional) – if True, return the value of the parameters, by default True
decimal (int, optional)
- get_reward_history()[source]¶
Return the history of reward in format that is compatible with other library such as aind_dynamic_foraging_basic_analysis
- learn(observation, action, reward, next_observation, done)[source]¶
Updates the agent’s knowledge or policy based on the last action and its outcome. I just copy and paste this from DynamicForagingAgentBase here for clarity.
This is the core method that should be implemented by all non-trivial agents. It could be Q-learning, policy gradients, neural networks, etc.
- Parameters:
observation – The observation before the action was taken.
action – The action taken by the agent.
reward – The reward received after taking the action.
next_observation – The next observation after the action.
done – Whether the episode has ended.
- perform(task: DynamicForagingTaskBase)[source]¶
Generative simulation of a task, or “open-loop” simulation
Override the base class method to include choice_prob caching etc.
- In each trial loop (note when time ticks):
agent.act() task.step() agent.learn()
latent variable [t] –> choice [t] –> reward [t] —-> update latent variable [t+1]
- perform_closed_loop(fit_choice_history, fit_reward_history)[source]¶
Simulates the agent over a fixed choice and reward history using its params. Also called “teacher forcing” or “closed-loop” simulation.
Unlike .perform() (“generative” simulation), this is called “predictive” simulation, which does not need a task and is used for model fitting.
- perform_closed_loop_multi_session(fit_choice_history_sessions, fit_reward_history_sessions)[source]¶
Simulates the agent over multiple sessions, resetting latent states at each session start.
Unlike .perform() (“generative” simulation), this is called “predictive” simulation, which does not need a task and is used for model fitting across multiple sessions.
- Parameters:
fit_choice_history_sessions (list of np.ndarray) – List of choice history arrays, one per session
fit_reward_history_sessions (list of np.ndarray) – List of reward history arrays, one per session
- Returns:
choice_prob_sessions – List of choice probability arrays, one per session
- Return type:
list of np.ndarray
- plot_fitted_session(if_plot_latent=True)[source]¶
Plot session after .fit()
choice and reward history will be the history used for fitting
laten variables q_estimate and choice_prob will be plotted
p_reward will be missing (since it is not used for fitting)
- Parameters:
if_plot_latent (bool, optional) – Whether to plot latent variables, by default True
- plot_latent_variables(ax, if_fitted=False)[source]¶
Add agent-specific latent variables to the plot
if_fitted: whether the latent variables are from the fitted model (styling purpose)
aind_dynamic_foraging_models.generative_model.forager_loss_counting module¶
aind_dynamic_foraging_models.generative_model.forager_q_learning module¶
aind_dynamic_foraging_models.generative_model.foragers module¶
aind_dynamic_foraging_models.generative_model.learn_functions module¶
Functions for update latent variables in generative models.
- aind_dynamic_foraging_models.generative_model.learn_functions.learn_RWlike(choice, reward, q_value_tminus1, forget_rates, learn_rates)[source]¶
Learning function for Rescorla-Wagner-like model.
- Parameters:
choice (int) – this choice
reward (float) – this reward
q_value_tminus1 (np.ndarray) – array of old q values
forget_rates (list) – forget rates for [unchosen, chosen] sides
learn_rates (_type_) – learning rates for [rewarded, unrewarded] sides
- Returns:
array of new q values
- Return type:
np.ndarray
- aind_dynamic_foraging_models.generative_model.learn_functions.learn_actor_critic(choice, reward, actor_preference_tminus1, value_tminus1, choice_prob_t, learn_rates)[source]¶
One-step actor-critic update for a (state-less) two-armed foraging task.
This implements the classic Sutton & Barto actor-critic with a softmax actor:
Critic (state value V) is updated by the TD error. Because the dynamic foraging task is effectively state-less (a single state / bandit), there is no bootstrap term, so the TD error reduces to the reward-prediction error:
delta_t = reward_t - V_{t-1} V_t = V_{t-1} + alpha_critic * delta_t
Here V acts as a running reward baseline shared across actions.
Actor (per-action preference H) is updated along the softmax policy gradient, using the same TD error as the critic’s teaching signal:
H_t(a) = H_{t-1}(a) + alpha_actor * delta_t * (1{a == choice} - pi(a))
where
piis the policy (choice probability) that was actually used to select the action on this trial.
- Parameters:
choice (int) – This trial’s choice (action index).
reward (float) – This trial’s reward.
actor_preference_tminus1 (np.ndarray) – Array of old actor preferences H, one entry per action.
value_tminus1 (float) – Old critic state value V (scalar).
choice_prob_t (np.ndarray) – The policy pi (choice probability per action) that was used to make this trial’s choice. Used for the softmax policy-gradient term.
learn_rates (list) – Learning rates as [alpha_actor, alpha_critic].
- Returns:
(new actor preferences H, new critic value V)
- Return type:
tuple(np.ndarray, float)
Notes
The actor’s overall scale (alpha_actor) and the policy’s softmax inverse temperature (beta) are not jointly identifiable, because both scale the preferences inside the softmax. When fitting, it is therefore recommended to clamp
softmax_inverse_temperature(e.g. to 1.0) and letlearn_rate_actorabsorb the scale. For that reason, beta is intentionally not multiplied into the actor gradient here.
- aind_dynamic_foraging_models.generative_model.learn_functions.learn_choice_kernel(choice, choice_kernel_tminus1, choice_kernel_step_size)[source]¶
Learning function for choice kernel.
- Parameters:
choice (int) – this choice
choice_kernel_tminus1 (np.ndarray) – array of old choice kernel values
choice_kernel_step_size (float) – step size for choice kernel
- Returns:
array of new choice kernel values
- Return type:
np.ndarray