diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 44a257fa..95793bfd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,7 +10,6 @@ on: - 'docs-mkdocs/**' - 'scripts/docs_*.sh' - 'scripts/sync_docs_notebooks.sh' - - 'docs/**' - '.readthedocs.yml' - 'pyproject.toml' - 'pymdp/**' @@ -22,7 +21,6 @@ on: - 'docs-mkdocs/**' - 'scripts/docs_*.sh' - 'scripts/sync_docs_notebooks.sh' - - 'docs/**' - '.readthedocs.yml' - 'pyproject.toml' - 'pymdp/**' diff --git a/docs-mkdocs/development/viewing-docs.md b/docs-mkdocs/development/viewing-docs.md index 5b189618..b1d8d55e 100644 --- a/docs-mkdocs/development/viewing-docs.md +++ b/docs-mkdocs/development/viewing-docs.md @@ -31,4 +31,3 @@ Local URL: - `./scripts/docs_build.sh` and `./scripts/docs_serve.sh` sync curated notebooks automatically before invoking MkDocs. - To add notebook docs, update `docs-mkdocs/tutorials/notebooks.manifest`. The sync step will copy the listed notebooks into the generated docs tree. - MkDocs source-of-truth content lives in `docs-mkdocs/`. -- `docs/` is retained as legacy Sphinx-era content for compatibility/history. diff --git a/docs/Makefile b/docs/Makefile deleted file mode 100644 index d4bb2cbb..00000000 --- a/docs/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/_static/pymdp_logo_2-removebg.png b/docs/_static/pymdp_logo_2-removebg.png deleted file mode 100644 index d9c9f51c..00000000 Binary files a/docs/_static/pymdp_logo_2-removebg.png and /dev/null differ diff --git a/docs/agent.rst b/docs/agent.rst deleted file mode 100644 index 017dca31..00000000 --- a/docs/agent.rst +++ /dev/null @@ -1,5 +0,0 @@ -Agent class -================================= - -.. autoclass:: pymdp.agent.Agent - :members: diff --git a/docs/algos/fpi.rst b/docs/algos/fpi.rst deleted file mode 100644 index 7414062e..00000000 --- a/docs/algos/fpi.rst +++ /dev/null @@ -1,6 +0,0 @@ -FPI (Fixed Point Iteration) -================================= - -.. automodule:: pymdp.algos.fpi - :members: - diff --git a/docs/algos/index.rst b/docs/algos/index.rst deleted file mode 100644 index a609603f..00000000 --- a/docs/algos/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -Algos -================================= - -The ``algos.py`` library contains the functions for implementing message passing algorithms for variational inference on POMDP generative models - -Sub-libraries ---------------- - -.. toctree:: - :maxdepth: 1 - - fpi - mmp \ No newline at end of file diff --git a/docs/algos/mmp.rst b/docs/algos/mmp.rst deleted file mode 100644 index 13370ef8..00000000 --- a/docs/algos/mmp.rst +++ /dev/null @@ -1,5 +0,0 @@ -MMP (Marginal Message Passing) -================================= - -.. automodule:: pymdp.algos.mmp - :members: \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py deleted file mode 100644 index 8e489feb..00000000 --- a/docs/conf.py +++ /dev/null @@ -1,81 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -import os -import sys -sys.path.insert(0, os.path.abspath('..')) - -# -- Project information ----------------------------------------------------- - -project = 'pymdp' -copyright = '2021, infer-actively' -author = 'infer-actively' - -# The full version, including alpha/beta/rc tags -release = '0.0.7.1' - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = ['sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.coverage', - 'sphinx.ext.napoleon', - 'sphinx.ext.autosummary', - 'myst_nb' - ] - -source_suffix = { - '.rst': 'restructuredtext', - '.ipynb': 'myst-nb' - } - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = { - 'logo_only': True, -} - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -html_logo = '_static/pymdp_logo_2-removebg.png' - -html_favicon = '_static/pymdp_logo_2-removebg.png' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - - -# -- Options for myst ---------------------------------------------- -jupyter_execute_notebooks = "cache" -jupyter_cache = "notebooks" diff --git a/docs/control.rst b/docs/control.rst deleted file mode 100644 index afd69e98..00000000 --- a/docs/control.rst +++ /dev/null @@ -1,8 +0,0 @@ -Control -================================= - -The ``control.py`` module contains the functions for performing inference of policies (sequences of control states) in POMDP generative models, -according to active inference. - -.. automodule:: pymdp.control - :members: \ No newline at end of file diff --git a/docs/env.rst b/docs/env.rst deleted file mode 100644 index 076361c0..00000000 --- a/docs/env.rst +++ /dev/null @@ -1,24 +0,0 @@ -Env -======== - -The OpenAIGym-inspired ``Env`` base class is the main API that represents the environmental dynamics or "generative process" with -which agents exchange observations and actions - -Base class ----------- -.. autoclass:: pymdp.envs.Env - -Specific environment implementations ----------- - -All of the following dynamics inherit from ``Env`` and have the -same general usage as above. - -.. autosummary:: - :nosignatures: - - pymdp.envs.GridWorldEnv - pymdp.envs.DGridWorldEnv - pymdp.envs.SceneConstruction - pymdp.envs.TMazeEnv - pymdp.envs.TMazeEnvNullOutcome diff --git a/docs/index.rst b/docs/index.rst deleted file mode 100644 index 4483d97d..00000000 --- a/docs/index.rst +++ /dev/null @@ -1,63 +0,0 @@ -.. pymdp documentation master file, created by - sphinx-quickstart on Fri Oct 29 13:27:58 2021. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to pymdp's documentation! -================================= - -``pymdp`` is a Python package for simulating active inference agents in -discrete space and time, using partially-observed Markov Decision Processes -(POMDPs) as a generative model class. The package is designed to be modular and flexible, to -enable users to design and simulate bespoke active inference models with varying levels of -specificity to a given task. - -For a theoretical overview of active inference and the motivations for developing this package, -please see our companion paper_: "pymdp: A Python library for active inference in discrete state spaces". - -.. toctree:: - :maxdepth: 1 - :caption: Installation & Usage - - installation - notebooks/pymdp_fundamentals - notebooks/active_inference_from_scratch - notebooks/using_the_agent_class - -.. toctree:: - :maxdepth: 1 - :caption: Examples - - notebooks/tmaze_demo - notebooks/cue_chaining_demo - -.. toctree:: - :maxdepth: 2 - :caption: Modules - - inference - control - learning - algos/index - -.. toctree:: - :maxdepth: 2 - :caption: Agent and environment API - - agent - env - -.. toctree:: - :maxdepth: 1 - :caption: Additional learning materials - - notebooks/free_energy_calculation - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _paper: https://joss.theoj.org/papers/10.21105/joss.04098 diff --git a/docs/inference.rst b/docs/inference.rst deleted file mode 100644 index 949f1fd8..00000000 --- a/docs/inference.rst +++ /dev/null @@ -1,7 +0,0 @@ -Inference -================================= - -The ``inference.py`` module contains the functions for performing inference of discrete hidden states (categorical distributions) in POMDP generative models. - -.. automodule:: pymdp.inference - :members: \ No newline at end of file diff --git a/docs/installation.rst b/docs/installation.rst deleted file mode 100644 index 583de3f4..00000000 --- a/docs/installation.rst +++ /dev/null @@ -1,13 +0,0 @@ -Installation -================================= - -We recommend installing ``pymdp`` using the package installer pip_, which will install the package locally as well as its dependencies. -This can also be done in a virtual environment (e.g. one created using ``venv`` or ``conda``). - -When pip installing ``pymdp``, use the full package name: ``inferactively-pymdp``: - -.. code-block:: console - - (.venv) $ pip install inferactively-pymdp - -.. _pip: https://pip.pypa.io/en/stable/ \ No newline at end of file diff --git a/docs/learning.rst b/docs/learning.rst deleted file mode 100644 index 77f420b2..00000000 --- a/docs/learning.rst +++ /dev/null @@ -1,7 +0,0 @@ -Learning -================================= - -The ``learning.py`` module contains the functions for updating parameters of Dirichlet posteriors (that paramaterise categorical priors and likelihoods) in POMDP generative models. - -.. automodule:: pymdp.learning - :members: \ No newline at end of file diff --git a/docs/make.bat b/docs/make.bat deleted file mode 100644 index 153be5e2..00000000 --- a/docs/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.https://www.sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/docs/notebooks/cue_chaining_demo.ipynb b/docs/notebooks/cue_chaining_demo.ipynb deleted file mode 100644 index 38c712a0..00000000 --- a/docs/notebooks/cue_chaining_demo.ipynb +++ /dev/null @@ -1,1065 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Active Inference Demo: Epistemic Chaining\n", - "\n", - "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/infer-actively/pymdp/blob/main/docs/notebooks/cue_chaining_demo.ipynb)\n", - "\n", - "*Author: Conor Heins*\n", - "\n", - "This demo notebook builds a generative model from scratch, constructs an `Agent` instance using the constructed generative model, and then runs an active inference simulation in a simple environment.\n", - "\n", - "The environment used here is similar in spirit to the [T-Maze demo](https://pymdp-rtd.readthedocs.io/en/latest/notebooks/tmaze_demo.html), but the task structure is more complex. Here, we analogize the agent to a rat tasked with solving a spatial puzzle. The rat must sequentially visit a sequence of two cues located at different locations in a 2-D grid world, in order to ultimately reveal the locations of two (opposite) reward outcomes: one location will give the rat a reward (\"Cheese\") and the other location will give the rat a punishment (\"Shock\").\n", - "\n", - "Using active inference to solve a POMDP representation of this task, the rat can successfully forage the correct cues in sequence, in order to ultimately discover the location of the \"Cheese\", and avoid the \"Shock\"." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Note*: When running this notebook in Google Colab, you may have to run `!pip install inferactively-pymdp` at the top of the notebook, before you can `import pymdp`. That cell is left commented out below, in case you are running this notebook from Google Colab." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# ! pip install inferactively-pymdp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Imports" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "\n", - "from pymdp.agent import Agent\n", - "from pymdp import utils" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Grid World Parameters\n", - "Let's begin by initializing several variables related to the physical environment inhabited by the agent. These variables will encode things like the dimensions of the grid, the possible locations of the different cues, and the possible locations of the reward or punishment.\n", - "\n", - "Having these variables defined will also come in handy when setting up the generative model of our agent and when creating the environment class.\n", - "\n", - "We will create a grid world with dimensions $5 \\times 7$. Particular locations of the grid are indexed as (y, x) tuples, that select a particular row and column respectively of that location in the grid.\n", - "\n", - "By design of the task, one location in the grid world contain a cue: **Cue 1**. There will be four additional locations, that will serve as possible locations for a second cue: **Cue 2**. Crucially, only *one* of these four additional locations will actually contain **Cue 2** - the other 3 will be empty. When the agent visits **Cue 1** by moving to its location, one of four signals is presented, which each unambiguously signal which of the 4 possible locations **Cue 2** occupies -- we can refer to these Cue-2-location-signals with obvious names: `L1`, `L2`, `L3`, `L4`. Once **Cue 2**'s location has been revealed, by visiting that location the agent will then receive one of two possible signals, that indicate where the hidden reward is located (and conversely, where the hidden punishment lies). These two possible reward/punishment locations are indicated by two locations: \"TOP\" (meaning the \"Cheese\" reward is on the upper of the two locations) or \"BOTTOM\" (meaning the \"Cheese\" reward is on the lower of the two locations).\n", - "\n", - "In this way, the most efficient and risk-sensitive way to achieve reward in this task is to first visit **Cue 1**, in order to figure out the location of **Cue 2**, in order to figure out the location of the reward.\n", - "\n", - "*Tip*: When setting up `pymdp` generative models and task environments, we recommend creating additional variables, like lists of strings or dicts with string-valued keys, that help you relate the values of various aspects of the task to semantically-meaning labels. These come in handy when generating print statements during debugging or labels for plotting. For example, below we create a list called `reward_conditions` that stores the \"names\" of the two reward conditions: `\"TOP\"` and `\"BOTTOM\"`" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "grid_dims = [5, 7] # dimensions of the grid (number of rows, number of columns)\n", - "num_grid_points = np.prod(grid_dims) # total number of grid locations (rows X columns)\n", - "\n", - "# create a look-up table `loc_list` that maps linear indices to tuples of (y, x) coordinates \n", - "grid = np.arange(num_grid_points).reshape(grid_dims)\n", - "it = np.nditer(grid, flags=[\"multi_index\"])\n", - "\n", - "loc_list = []\n", - "while not it.finished:\n", - " loc_list.append(it.multi_index)\n", - " it.iternext()\n", - "\n", - "# (y, x) coordinate of the first cue's location, and then a list of the (y, x) coordinates of the possible locations of the second cue, and their labels (`L1`, `L2`, ...)\n", - "cue1_location = (2, 0)\n", - "\n", - "cue2_loc_names = ['L1', 'L2', 'L3', 'L4']\n", - "cue2_locations = [(0, 2), (1, 3), (3, 3), (4, 2)]\n", - "\n", - "# names of the reward conditions and their locations\n", - "reward_conditions = [\"TOP\", \"BOTTOM\"]\n", - "reward_locations = [(1, 5), (3, 5)]\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Visualize the grid world\n", - "\n", - "Let's quickly use the variables we just defined to visualize the grid world, including the **Cue 1** location, the possible **Cue 2** locations, and the possible reward locations (in gray, since we don't know which one has the \"Cheese\" and which one has the \"Shock\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "import matplotlib.pyplot as plt\n", - "import matplotlib.patches as patches\n", - "import matplotlib.cm as cm\n", - "\n", - "fig, ax = plt.subplots(figsize=(10, 6)) \n", - "\n", - "# create the grid visualization\n", - "X, Y = np.meshgrid(np.arange(grid_dims[1]+1), np.arange(grid_dims[0]+1))\n", - "h = ax.pcolormesh(X, Y, np.ones(grid_dims), edgecolors='k', vmin = 0, vmax = 30, linewidth=3, cmap = 'coolwarm')\n", - "ax.invert_yaxis()\n", - "\n", - "# Put gray boxes around the possible reward locations\n", - "reward_top = ax.add_patch(patches.Rectangle((reward_locations[0][1],reward_locations[0][0]),1.0,1.0,linewidth=5,edgecolor=[0.5, 0.5, 0.5],facecolor=[0.5, 0.5, 0.5]))\n", - "reward_bottom = ax.add_patch(patches.Rectangle((reward_locations[1][1],reward_locations[1][0]),1.0,1.0,linewidth=5,edgecolor=[0.5, 0.5, 0.5],facecolor=[0.5, 0.5, 0.5]))\n", - "\n", - "text_offsets = [0.4, 0.6]\n", - "\n", - "cue_grid = np.ones(grid_dims)\n", - "cue_grid[cue1_location[0],cue1_location[1]] = 15.0\n", - "for ii, loc_ii in enumerate(cue2_locations):\n", - " row_coord, column_coord = loc_ii\n", - " cue_grid[row_coord, column_coord] = 5.0\n", - " ax.text(column_coord+text_offsets[0], row_coord+text_offsets[1], cue2_loc_names[ii], fontsize = 15, color='k')\n", - "h.set_array(cue_grid.ravel())\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generative model\n", - "\n", - "The hidden states $\\mathbf{s}$ of the generative model are factorized into three hidden states factors:\n", - "\n", - "1. a **Location** hidden state factor with as many levels as there are grid locations. This encodes the agent's location in the grid world.\n", - "2. a **Cue 2 Location** hidden state factor with 4 levels -- this encodes in which of the four possible locations **Cue 2** is located.\n", - "3. a **Reward Condition** hidden state factor with 2 levels -- this encodes which of the two reward locations (\"TOP\" or \"BOTTOM\") the \"Cheese\" is to be found in. When the **Reward Condition** level is \"TOP\", then the \"Cheese\" reward is the upper of the two locations, and the \"Shock\" punishment is on the lower of the two locations. The locations are switched in the \"BOTTOM\" level of the **Reward Condition** factor.\n", - "\n", - "The observations $\\mathbf{o}$ of the generative model are factorized into four different observation modalities:\n", - "\n", - "1. a **Location** observation modality with as many levels as there are grid locations, representing the agent's observation of its location in the grid world.\n", - "2. a **Cue 1** observation modality with 5 levels -- this is an observation, only obtained at the **Cue 1** location, that signals in which of the 4 possible locations **Cue 2** is located. When not at the **Cue 1** location, the agent sees `Null` or a meaningless observation.\n", - "3. a **Cue 2** observation modality with 3 levels -- this is an observation, only obtained at the **Cue 2** location, that signals in which of the two reward locations (\"TOP\" or \"BOTTOM\") the \"Cheese\" is located. When not at the **Cue 2** location, the agent sees `Null` or a meaningless observation.\n", - "4. a **Reward** observation modality with 3 levels -- this is an observation that signals whether the agent is receiving \"Cheese\", \"Shock\" or nothing at all (\"Null\"). The agent only receives \"Cheese\" or \"Shock\" when occupying one of the two reward locations, and `Null` otherwise.\n", - "\n", - "\n", - "As is the usual convention in `pymdp`, let's create a list that contains the dimensionalities of the hidden state factors, named `num_states`, and a list that contains the dimensionalities of the observation modalities, named `num_obs`. " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# list of dimensionalities of the hidden states -- useful for creating generative model later on\n", - "num_states = [num_grid_points, len(cue2_locations), len(reward_conditions)]\n", - "\n", - "# Names of the cue1 observation levels, the cue2 observation levels, and the reward observation levels\n", - "cue1_names = ['Null'] + cue2_loc_names # signals for the possible Cue 2 locations, that only are seen when agent is visiting Cue 1\n", - "cue2_names = ['Null', 'reward_on_top', 'reward_on_bottom']\n", - "reward_names = ['Null', 'Cheese', 'Shock']\n", - "\n", - "num_obs = [num_grid_points, len(cue1_names), len(cue2_names), len(reward_names)]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The observation model: **A** array\n", - "Now using `num_states` and `num_obs` we can initialize `A`, the observation model" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [], - "source": [ - "A_m_shapes = [ [o_dim] + num_states for o_dim in num_obs] # list of shapes of modality-specific A[m] arrays\n", - "A = utils.obj_array_zeros(A_m_shapes) # initialize A array to an object array of all-zero subarrays" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's fill out the various modalities of the `A` array, encoding the agents beliefs about how hidden states probabilistically cause observations within each modality.\n", - "\n", - "Starting with the `0`-th modality, the **Location** observation modality: `A[0]`" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "# make the location observation only depend on the location state (proprioceptive observation modality)\n", - "A[0] = np.tile(np.expand_dims(np.eye(num_grid_points), (-2, -1)), (1, 1, num_states[1], num_states[2]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can build the `1`-st modality, the **Cue 1** observation modality: `A[1]`" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "# make the cue1 observation depend on the location (being at cue1_location) and the true location of cue2\n", - "A[1][0,:,:,:] = 1.0 # default makes Null the most likely observation everywhere\n", - "\n", - "# Make the Cue 1 signal depend on 1) being at the Cue 1 location and 2) the location of Cue 2\n", - "for i, cue_loc2_i in enumerate(cue2_locations):\n", - " A[1][0,loc_list.index(cue1_location),i,:] = 0.0\n", - " A[1][i+1,loc_list.index(cue1_location),i,:] = 1.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can build the `2`-nd modality, the **Cue 2** observation modality: `A[2]`" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# make the cue2 observation depend on the location (being at the correct cue2_location) and the reward condition\n", - "A[2][0,:,:,:] = 1.0 # default makes Null the most likely observation everywhere\n", - "\n", - "for i, cue_loc2_i in enumerate(cue2_locations):\n", - "\n", - " # if the cue2-location is the one you're currently at, then you get a signal about where the reward is\n", - " A[2][0,loc_list.index(cue_loc2_i),i,:] = 0.0 \n", - " A[2][1,loc_list.index(cue_loc2_i),i,0] = 1.0\n", - " A[2][2,loc_list.index(cue_loc2_i),i,1] = 1.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Finally, we build the 3rd modality, the **Reward** observation modality: `A[3]`" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [], - "source": [ - "# make the reward observation depend on the location (being at reward location) and the reward condition\n", - "A[3][0,:,:,:] = 1.0 # default makes Null the most likely observation everywhere\n", - "\n", - "rew_top_idx = loc_list.index(reward_locations[0]) # linear index of the location of the \"TOP\" reward location\n", - "rew_bott_idx = loc_list.index(reward_locations[1]) # linear index of the location of the \"BOTTOM\" reward location\n", - "\n", - "# fill out the contingencies when the agent is in the \"TOP\" reward location\n", - "A[3][0,rew_top_idx,:,:] = 0.0\n", - "A[3][1,rew_top_idx,:,0] = 1.0\n", - "A[3][2,rew_top_idx,:,1] = 1.0\n", - "\n", - "# fill out the contingencies when the agent is in the \"BOTTOM\" reward location\n", - "A[3][0,rew_bott_idx,:,:] = 0.0\n", - "A[3][1,rew_bott_idx,:,1] = 1.0\n", - "A[3][2,rew_bott_idx,:,0] = 1.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The transition model: **B** array\n", - "To create the `B` array or transition model, we have to further specify `num_controls`, which like `num_states` / `num_obs` is a list, but this time of the dimensionalities of each *control factor*, which are the hidden state factors that are controllable by the agent. Uncontrollable hidden state factors can be encoded as control factors of dimension 1. Once `num_controls` is defined, we can then use it and `num_states` to specify the dimensionality of the `B` arrays. Recall that in `pymdp` hidden state factors are conditionally independent of eachother, meaning that each sub-array `B[f]` describes the dynamics of only a single hidden state factor, and its probabilistic dependence on both its own state (at the previous time) and the state of its corresponding control factor.\n", - "\n", - "In the current grid world task, we will have the agent have the ability to make movements in the 4 cardinal directions (UP, DOWN, LEFT, RIGHT) as well as the option to stay in the same place (STAY). This means we will associate a single 5-dimensional control state factor with the first hidden state factor. \n", - "\n", - "*Note*: Make sure the indices of the `num_controls` variables \"lines up\" with those of `num_states`." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [], - "source": [ - "# initialize `num_controls`\n", - "num_controls = [5, 1, 1]\n", - "\n", - "# initialize the shapes of each sub-array `B[f]`\n", - "B_f_shapes = [ [ns, ns, num_controls[f]] for f, ns in enumerate(num_states)]\n", - "\n", - "# create the `B` array and fill it out\n", - "B = utils.obj_array_zeros(B_f_shapes)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Fill out `B[0]` according to the expected consequences of each of the 5 actions. Note that we also create a list that stores the names of each action, for interpretability." - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [], - "source": [ - "actions = [\"UP\", \"DOWN\", \"LEFT\", \"RIGHT\", \"STAY\"]\n", - "\n", - "# fill out `B[0]` using the \n", - "for action_id, action_label in enumerate(actions):\n", - "\n", - " for curr_state, grid_location in enumerate(loc_list):\n", - "\n", - " y, x = grid_location\n", - "\n", - " if action_label == \"UP\":\n", - " next_y = y - 1 if y > 0 else y \n", - " next_x = x\n", - " elif action_label == \"DOWN\":\n", - " next_y = y + 1 if y < (grid_dims[0]-1) else y \n", - " next_x = x\n", - " elif action_label == \"LEFT\":\n", - " next_x = x - 1 if x > 0 else x \n", - " next_y = y\n", - " elif action_label == \"RIGHT\":\n", - " next_x = x + 1 if x < (grid_dims[1]-1) else x \n", - " next_y = y\n", - " elif action_label == \"STAY\":\n", - " next_x = x\n", - " next_y = y\n", - "\n", - " new_location = (next_y, next_x)\n", - " next_state = loc_list.index(new_location)\n", - " B[0][next_state, curr_state, action_id] = 1.0" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Fill out `B[1]` and `B[2]` as identity matrices, encoding the fact that those hidden states are uncontrollable" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "B[1][:,:,0] = np.eye(num_states[1])\n", - "B[2][:,:,0] = np.eye(num_states[2])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Prior preferences: the **C** vectors\n", - "\n", - "Now we specify the agent's prior over observations, also known as the \"prior preferences\" or \"goal vector.\" This is not technically a part of the same generative model used for inference of hidden states, but part of a special predictive generative model using for policy inference. \n", - "\n", - "Since the prior preferences are defined in `pymdp` as priors over observations, not states, so `C` will be an object array whose sub-arrays correspond to the priors over specific observation modalities, e.g `C[3]` encodes the prior preferences for different levels of the **Reward** observation modality." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "C = utils.obj_array_zeros(num_obs)\n", - "\n", - "C[3][1] = 2.0 # make the agent want to encounter the \"Cheese\" observation level\n", - "C[3][2] = -4.0 # make the agent not want to encounter the \"Shock\" observation level" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Prior over (initial) hidden states: the **D** vectors\n", - "\n", - "Now we specify the agent's prior over initial hidden states, the `D` array. Since it's defined over the multi-factor hidden states in this case, `D` will be an object array whose sub-arrays correspond to the priors over specific hidden state factors, e.g `D[0]` encodes the prior beliefs over the initial location of the agent in the grid world." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "D = utils.obj_array_uniform(num_states)\n", - "D[0] = utils.onehot(loc_list.index((0,0)), num_grid_points)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Generative process\n", - "\n", - "Now we need to write down the \"rules\" of the game, i.e. the environment that the agent will actually be interacting with. The most concise way to do this in `pymdp` is by adopting a similar format to what's used in frameworks like OpenAIGym -- namely, we create an `env` class that takes actions as inputs to a `self.step()` method, and returns observations for the agent as outputs. In Active inference we refer to this agent-independent, physical \"reality\" in which the agent operates as the *generative process*, to be distinguished from the agent's representation of that reality the *generative model* (the `A`, `B`, `C` and `D` that we just wrote down above)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Writing a custom `env` \n", - "\n", - "Now we'll define an environment class called `GridWorldEnv`. The constructor for this class allows you to establish various parameters of the generative process, like where the agent starts in the grid-world at the beginning of the trial (`starting_loc`), the location of **Cue 1** (`cue1_loc`), the location of **Cue 2** (`cue2_loc`), and the reward condition (`reward_condition`).\n", - "\n", - "*Note*: Remember the distinction between the generative model and the generative process: one can build the environment class to be as arbitrarily different from the agent's generative model as desired. For example, for the `GridWorldEnv` example, you could construct the agent's `A` array such that the agent *believes* **Cue 1** is in Location `(1,0)`, but in fact the cue is located somewhere else like `(3,0)` (as would be set by the `cue1_loc` argument to the `GridWorldEnv` constructor). Similarly, one could write the internal `step` method of the `GridWorldEnv` class so that the way the `reward_condition` is signalled is opposite from what the agent expects -- so when the agent sees a particular signal at the **Cue 2** location, they *assume* (via the `A` array) it means that the \"Cheese\" is located on the `\"TOP\"` location, but in fact the rule is switched so that \"Shock\" is at the `\"TOP\"` location in reality, and \"Cheese\" is actually at the `\"BOTTOM\"` location." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "class GridWorldEnv():\n", - " \n", - " def __init__(self,starting_loc = (0,0), cue1_loc = (2, 0), cue2 = 'L1', reward_condition = 'TOP'):\n", - "\n", - " self.init_loc = starting_loc\n", - " self.current_location = self.init_loc\n", - "\n", - " self.cue1_loc = cue1_loc\n", - " self.cue2_name = cue2\n", - " self.cue2_loc_names = ['L1', 'L2', 'L3', 'L4']\n", - " self.cue2_loc = cue2_locations[self.cue2_loc_names.index(self.cue2_name)]\n", - "\n", - " self.reward_condition = reward_condition\n", - " print(f'Starting location is {self.init_loc}, Reward condition is {self.reward_condition}, cue is located in {self.cue2_name}')\n", - " \n", - " def step(self,action_label):\n", - "\n", - " (Y, X) = self.current_location\n", - "\n", - " if action_label == \"UP\": \n", - " \n", - " Y_new = Y - 1 if Y > 0 else Y\n", - " X_new = X\n", - "\n", - " elif action_label == \"DOWN\": \n", - "\n", - " Y_new = Y + 1 if Y < (grid_dims[0]-1) else Y\n", - " X_new = X\n", - "\n", - " elif action_label == \"LEFT\": \n", - " Y_new = Y\n", - " X_new = X - 1 if X > 0 else X\n", - "\n", - " elif action_label == \"RIGHT\": \n", - " Y_new = Y\n", - " X_new = X +1 if X < (grid_dims[1]-1) else X\n", - "\n", - " elif action_label == \"STAY\":\n", - " Y_new, X_new = Y, X \n", - " \n", - " self.current_location = (Y_new, X_new) # store the new grid location\n", - "\n", - " loc_obs = self.current_location # agent always directly observes the grid location they're in \n", - "\n", - " if self.current_location == self.cue1_loc:\n", - " cue1_obs = self.cue2_name\n", - " else:\n", - " cue1_obs = 'Null'\n", - "\n", - " if self.current_location == self.cue2_loc:\n", - " cue2_obs = cue2_names[reward_conditions.index(self.reward_condition)+1]\n", - " else:\n", - " cue2_obs = 'Null'\n", - " \n", - " # @NOTE: here we use the same variable `reward_locations` to create both the agent's generative model (the `A` matrix) as well as the generative process. \n", - " # This is just for simplicity, but it's not necessary - you could have the agent believe that the Cheese/Shock are actually stored in arbitrary, incorrect locations.\n", - "\n", - " if self.current_location == reward_locations[0]:\n", - " if self.reward_condition == 'TOP':\n", - " reward_obs = 'Cheese'\n", - " else:\n", - " reward_obs = 'Shock'\n", - " elif self.current_location == reward_locations[1]:\n", - " if self.reward_condition == 'BOTTOM':\n", - " reward_obs = 'Cheese'\n", - " else:\n", - " reward_obs = 'Shock'\n", - " else:\n", - " reward_obs = 'Null'\n", - "\n", - " return loc_obs, cue1_obs, cue2_obs, reward_obs\n", - "\n", - " def reset(self):\n", - " self.current_location = self.init_loc\n", - " print(f'Re-initialized location to {self.init_loc}')\n", - " loc_obs = self.current_location\n", - " cue1_obs = 'Null'\n", - " cue2_obs = 'Null'\n", - " reward_obs = 'Null'\n", - "\n", - " return loc_obs, cue1_obs, cue2_obs, reward_obs" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Active Inference\n", - "\n", - "Now that we have a generative model and generative process set up, we can quickly run active inference in `pymdp`. In order to do this, all we need to do is to create an `Agent` using the `Agent()` constructor and create a generative process / environment using our custom `GridWorldEnv` class. Then we just exchange observations and actions between the two in a loop over time, where the agent updates its beliefs and actions using the `Agent` methods like `infer_states()` and `infer_policies()`.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initialize an `Agent` and an instance of `GridWorldEnv`\n", - "We can quickly construct an instance of `Agent` using our generative model arrays as inputs: `A`, `B`, `C`, and `D`. Since we are dealing with a spatially-extended navigation example, we will also use a `policy_len` parameter that lets the agent plan its movements forward in time. This sort of temporally deep planning is needed because of A) the local nature of the agent's action repetoire (only being able to move UP, LEFT, RIGHT, and DOWN), and B) the physical distance between the cues and reward locations in the grid world.\n", - "\n", - "We can also initialize the `GridWorldEnv` class using a desired starting location, a Cue 1 location, Cue 2 location, and reward condition. We can get the first (multi-modality) observation of the simulation by using `env.reset()`" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting location is (0, 0), Reward condition is BOTTOM, cue is located in L4\n", - "Re-initialized location to (0, 0)\n" - ] - } - ], - "source": [ - "my_agent = Agent(A = A, B = B, C = C, D = D, policy_len = 4)\n", - "\n", - "my_env = GridWorldEnv(starting_loc = (0,0), cue1_loc = (2, 0), cue2 = 'L4', reward_condition = 'BOTTOM')\n", - "\n", - "loc_obs, cue1_obs, cue2_obs, reward_obs = my_env.reset()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Run an active inference loop over time\n", - "...saving the history of the rat's locations as you do so. Include some print statements if you want to see the output of the agent's choices as they unfold." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Action at time 0: DOWN\n", - "Grid location at time 0: (1, 0)\n", - "Reward at time 0: Null\n", - "Action at time 1: DOWN\n", - "Grid location at time 1: (2, 0)\n", - "Reward at time 1: Null\n", - "Action at time 2: DOWN\n", - "Grid location at time 2: (3, 0)\n", - "Reward at time 2: Null\n", - "Action at time 3: RIGHT\n", - "Grid location at time 3: (3, 1)\n", - "Reward at time 3: Null\n", - "Action at time 4: DOWN\n", - "Grid location at time 4: (4, 1)\n", - "Reward at time 4: Null\n", - "Action at time 5: RIGHT\n", - "Grid location at time 5: (4, 2)\n", - "Reward at time 5: Null\n", - "Action at time 6: RIGHT\n", - "Grid location at time 6: (4, 3)\n", - "Reward at time 6: Null\n", - "Action at time 7: RIGHT\n", - "Grid location at time 7: (4, 4)\n", - "Reward at time 7: Null\n", - "Action at time 8: RIGHT\n", - "Grid location at time 8: (4, 5)\n", - "Reward at time 8: Null\n", - "Action at time 9: UP\n", - "Grid location at time 9: (3, 5)\n", - "Reward at time 9: Cheese\n" - ] - } - ], - "source": [ - "history_of_locs = [loc_obs]\n", - "obs = [loc_list.index(loc_obs), cue1_names.index(cue1_obs), cue2_names.index(cue2_obs), reward_names.index(reward_obs)]\n", - "\n", - "T = 10 # number of total timesteps\n", - "\n", - "for t in range(T):\n", - "\n", - " qs = my_agent.infer_states(obs)\n", - " \n", - " my_agent.infer_policies()\n", - " chosen_action_id = my_agent.sample_action()\n", - "\n", - " movement_id = int(chosen_action_id[0])\n", - "\n", - " choice_action = actions[movement_id]\n", - "\n", - " print(f'Action at time {t}: {choice_action}')\n", - "\n", - " loc_obs, cue1_obs, cue2_obs, reward_obs = my_env.step(choice_action)\n", - "\n", - " obs = [loc_list.index(loc_obs), cue1_names.index(cue1_obs), cue2_names.index(cue2_obs), reward_names.index(reward_obs)]\n", - "\n", - " history_of_locs.append(loc_obs)\n", - "\n", - " print(f'Grid location at time {t}: {loc_obs}')\n", - "\n", - " print(f'Reward at time {t}: {reward_obs}')\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Visualization\n", - "\n", - "Now let's do a quick visualization of the rat's movements over a single trial. We'll indicate the grid location and time of its movements using a hot colormap (so hotter colors means later in the trial), and indicate the Cue 1 and Cue 2 locations with purple outlined boxes. Each of the possible Cue 2 locations will be highlighted in a light blue.\n", - "\n", - "Try changing the initial settings of the generative process (the locations of Cue1, Cue 2, the reward condition, etc.) to see how and the extent to which the active inference agent can adapt its behavior to the changing environmental contingencies." - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Cue 1 located at (4, 2), Cue 2 located at (4, 2), Cheese on BOTTOM')" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkwAAAF3CAYAAABXMRQwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAABFvElEQVR4nO3dd3gc1dn38e+9u6ruHWMbbLCxAVNtWjBggyGmkzz0FhICvAnFKU8KkOIEQtqTQguBAAFCTO+hJBgwYErAxlQ3DNi49yZLWml3z/vHjMyySJqVNNIW/T7XpUvSzOyZe2bPztxzzplZc84hIiIiIk2L5DoAERERkXynhElEREQkgBImERERkQBKmEREREQCKGESERERCaCESURERCSAEiYRERGRAHmRMJnZQWZ2v5ktN7M6M1tnZs+a2dfMLNrBsXzPzJ4wsxVm5sxsSgteO93MprdfdFnFMMXMDm+Hclu0LwLKOsnMvtfC14wxs2ozG9TE/J38+c7MhrcyrpPN7CEzW2xmNWY238x+bWbdGol/lZl1bc160sopMbNvm9krZrbRzOJm9omZ3W5m+7al7FbEktW2N/Ha8f5+H9/+kTYbwxQzC/WY5pcZysPqzKynX16L3lsze9zMbmhm/l/9/X93K+Ma6L/XM/16uMbMnjOzQzOWMzObbWY/bM16Msrazcz+7te3uJltMrOXzewyMyv3l2moVxPbur7Oxj8XubSfGjObZ2Y/NbOyRpbf3sxu9I8/cTNbbWYPm9n+acsMzSizqZ/MdTf1c15L1p+27JS0berRyPyvpa2jVeeCpuQ8YTKz7wCvAL2BHwETgW8AC4CbgOM6OKQLgP7Aox283rD8HAg9YQrZSUCLEibg98DtzrllTcz/C7CpLUEB/wskgSuASXj171vAsxkn4seAFcAPWrsiM+sCPAf8AXgDOAs4CrgaGObP60jZbnu+Go9X9/M51p54MWadMPlJy1HAr5uYfzBwNrC5DXGNAU7Dq9enAOcBtcB0M9t2/HXeU45/CVxuZr1buzIzOwWYDYwGrsLbvjOAV4FfABe1tmz5nHeBg/yfY4F78erf/6UvZGZ7AW8DRwO/xXs/LsWrr6+a2Tn+oivSymv4AbgjY9rPMv6/2l/ulIzpT7Zw/ZnqgZMbmf41YEsTr2kb51zOfoBDgRRwXRPzdwb27OCYIv7vGOCAKS147XRgeo73qQOubqdys94XAWXdASxtwfJj/PXv3sT8M4FVwHf85Ya3Mq5+jUw71y/z8Izp3wbWAeWtXNetQBw4qIn5X+ngepP1tjey3Hh/ufEdGXNGDFP8GGLtUW5IZQ31Y/xmC17zBPBAE/NKgPeBy4FFwN2tjKtn5n7zj3/zgZcypkfxTpw/bOW6RgA1wCONvVdAP+DgjHo1MVf1qlB//HPRjEam3w2syqhDH/o/fTKWjQAP4SXPI5tYT+D5Bi8Bb/S43Jr1p33W7yDjfAsMwcsp/t6Wc0FTP7m+GvsRsB5otInXOfeRc+5daLpp3MzuMLNFGdMqzey3fvNenf/7ymyulJ1zqVZtSRPMbKSZPeI3ddeY2etmNqmR5fbyl1tnn3WJXJ42/ygze8q8rsJqM3vfzL5vaV2WafvnyrQmySlp8w/zm9q3mNlWM/u3mY3OiCNqZlenrWe6me2e5bb2M7ObzWyB/9olZjbV0rrRzOwOvCuAQWkxLgoo+pvAu865DxpZZy/gj3gtJBuzibMpzrk1jUx+0/+d2RV4P96J5qstXY+ZDcTbB39zzr3WRCyPpC2/yN9vmeV8oZvUr0ePm9kGvx69YmaHBMXUwm0PZJ7v+vW4zq9PN5hZ94zlYmb2IzObY2a15nUHPWNmo/z55Wb2J7++V5nZSvO6zEellTEF78oZoL6hXqXNz+p4YGb7mNctVGtmy8zsp4Blub2nm9nzfvxV5nVdfS1t/lDgE//fv1kj3RKNlLk93lX31CYW+QFeAvN/TczPinNuo3MukTEtgXfVPyhjehJ4AO8z2RrfwUvGvp25Tr/8Nc65VzImV/p1Z63/c7eZ9UxfwK9Hl5vX7RQ3b3jHH8zv3ktbLrAumFlXM7vezD61z7qHpmXUuazW1xgz6+5vz3L/tfP9z4qlLdPQHXlC0La30Ga8JKXBV4HhwBXOuXXpC/rnwkvx6th32rDO5rRl/XcBh5rZjmnTzgEWAy+1R7Cx9ig0G+ad6CcAjzrnakMsNwb8G9gNr7n3PeBA4Kd43X7fD2tdWcSyPTADr3nwErwuo4uBJ83sOOfc0/5y++NdESwEvgssxbsS2zOtuJ3wummux8u4x+Jl2v2AH/vLHAS8hpd53+xPW+qv41i8Jvcn8ZrwwUtYXzazPZ1zS/xpU/C6Zf4I/Mdfz+NZbnJvP7bLgTXA9nj7+xUzG+W/z1f5Me8HnOC/Lh5Q7iQ/7sb8DpjnnPtHcyefNjjM/z03faJzbq2ZzfVja+qE1pQJeJ+9bPdrVswbG/MyXnfHBUA18P+AaWb2JefcrBYW2ei2Z+lXePXgRrxWkobP415mdljahcm9eF20fwamAeV4Lc8DgXlAGdANr1l/BV4d+zbwmpnt6pxbiddaNxg4HxiH17UIZH88MLO+wPPASrxkNo6XkOyQ5fbuBDwI/AbvCvdQ4FYzq3DO/dWP/avAw3jdaw3v/UfNlHkk3sni5cwZ5o3N+AlwrHOuPu1cGwozK8U7nrzbyOyXgEvNbCfn3MctLPpI4E3n3IoWvOZa4F94Lckj8T7zSbz3qcHdwPF4XTqvArvivd9Dgf+BFp0b/oR3bLoCv+UDOBjvAinr9TXGT8yexOuW/Zkfw7F4x9t+/jpbuu1N8rcZoBKvTp7F549XR/jlNXp8dc4tN7NZtN8wj7as/2W8ltWzgGv8aefgvTft8yW5OWwyHOBv1K+zXH4KjTSN4yUHi9L+P8cv99CM5a4E6oD+Wa6vzV1yeFd+CdKaBfEOgPOBt9KmvQQsASqzXI/58V0JbMDvRnTNNJHiJWPPZUzrDqwF/uz/3wuoAv6asdyPWrov0rZ1iP/ar6RNv4Msu+TS6skFjcw7BO/Etpv//3mE2AyLd3W9Gni2ifn/ABa0otyG/dloM3cjyy8C7mhk+ufeE7yEei5QmvEezMW7MAlt2zOWHU9alxzeySeeGTNeou6AE/z/D/f/v6yFdaoS7yLku2nTp9BIlxxZHg/wErw6YEjaMl38z4dr4b6L+J/PvwHvpE0fSgu65PDGkS1rYt6zpHXB0YYuuSbKvwYv8TukkXk7+9txZivKrQHuyXLZhnp1Z8b0G/AuzMz//xB/uXMzljvLn753C+vC+8Afm4krq/U18drj/GXOy5je0EXftyXb3sx6pvuvz/x5nLRhBMDTwIqAsu4FqpuY19YuuRavn7TPOt6Yurn+9P396SOaW2dbfnLdJdceJuE1yb3qN5vG/Cz7P3hNkQd2YCyHAq875xY2THBek/Y9wN5+02wl3tXLP51z1U0VZN6dLDeb2WK8D3c93lV3T7xB6k0ysxF4B7l/ZuyTarwWqYa7YfbAO0ncn1HEvdlusJl9y8zeMbMqvGTxU3/WyGzLyLC9//tzXUb+FfDNwJ+cc3NaWXaTzLsD7jG8bfh6E4s1tKLlnJlV4LUIPQCk0t5jw2u5ObS512eUlc22N+dAoBTvSi/dvX6ZDS1XR+Ed1P4WEM+pZvZfM9vov34r0JXs6lS2x4OD8D6rDS2tOOe24rWOBTKzEWZ2j5ktw/ts1uN1W7W23oNXt77QVWpmZ+O10LZLa7mZnYnXan2Vc+4LrVtpMXVU3c9sfXgPr+VxgP//JLxj4oONvMfwWd3Pti68CZxnZleY2Vj74p3a2a6vMQ3jdjNbpe/G+8wclDE9aNub8w5ePdkPr+X1W3hJxQPp3X8F7i5glJnthzfm8nXn3IfttbKcdcnhDZitAXYMWrCF+vtl1jcxv0/I62tOb7zukUwr8U5kvfBOABH8rrPG+M24j+MdoKbgdVXU4HVlXInXjdGchoTqNv8nU0NSM9D/vSpjfub/TcV5KXAdXvPyD/Bbv4DXs4ixKQ2vy+y2+w7e/rsurU+/0v/dzcy6OedadaeEn3w8gdfNcphzrqn3pobWbVfDSXlHvNbGMPTGa335qf/zBWYWcQFj9Fqw7UGxgNcNtY1zLmFm69Lm9wHWO+dqmonneOA+4E68O6jW4p1wniK7fZ/t8WAgXstCpsC67yeYz+JdgPwYr5utDu8E9Y0sYmxKORn13l/XH/G6guJpdT8ClPj/b3XONbW9zfL39x3Abc65nzexWMP7VdGKVSyh5cf89Rn/N+yThve/P16ysbWJ1/dJWy6bunAp3jH6G3gtj+vN7C7gSv+iNtv1NaY3Xp2vy5i+Mm1+uqBtb06Vc25m2v+v+J+/+/GSvqfxzjtHmlllMxfsQ/nsmBW2Nq3fObfQzF7D644/mSaOfWHJWcLkHzyn4+2sMudc0DiWWvBaFjIqW2blXIc3uPLUJspZ1IpwW2s9sF0j07fDu7LegJcwpWh+YO3OeGOJznHObbtq9w9u2WgYTHc5XmtDpob92XCCGwCkD7DO5moG4HS8br9tV75mNizL1zalIfZeGdN3w9uPjT1m4C28q6u9W7oyMyvBG4syFjjSOfdeM4v3TouvJabj9dsfz2dXpc2pxTtAp8eZWe834tWjG/Guur4gi2SpJdvenIaD/Hak1SP/KrxP2vy1QG9/nE9TSdPpwELn3HkZcWZ7W3u2x4MVNF7Ps6n7B+GdiA9xzs1Ii7Otx9d1eI+YSNcXb6zLNXw2bqPBELzt/AqteCyKmR2B10L5CM3f2t+w79e2dB14x59vmtl2zht/FoZ1eJ+Rpm5uWJ62XGBdcM5V4R0rL/cHFJ+MNzatDq87Pdv1NWY9Xp3PPI9tlza/PTV8HvfES5iew2sJPRbvvf8cfxzuGLwuw/YQxvrvwjvuJWhBb0hr5LpL7jd4B9DfNTbTzIaZWcPA58X+79Fp83sCX8p42TN4B44q59zMRn5a8yFvrReBA827QwbYNtj9NGC2c26zn1XPAM72r+4b09Bysu3KyD9pnNXIsnV88cpvPt7BYPcm9knDwM538a6aMg8opwdsZ3qcmVdvjXXpxBuJsSmL8A5OO2VM/w3e4On0n9/6886mFXfx+C15/8QbW3OSc+71gJcMoxUtRM655XhX8ReaWWYTfEMsJ6X9u5i0eu87NqPMrXiDIPfCGx/3hfe5uZhase3NeR2vHmbWm9PwLtKm+///B6+ltbn3qhLvQJjuHLzWtHQNF1yZ9Srb48FreJ/VIQ0vNO9ZWdlclDT2+ewFnJhljE2ZBwzJSLxW8sV6PwGvJWya//cMWsivh4/hncDODkiuG5K41rSO/gnvYuEvjXR1YWZ9zXu2VEs8g9fi0qOJ93h52nItOjc45xY75/6A1xU2uoXra8yLeOfdUzKmn4X3mWn0rtkQNZxPG7pVH8ZrEb3GMp6t5R8TrsO7ELu2neIJY/334fXA/MY5t6Gd4vSEOSCqNT94XSspvCbts/Cy9hP8HbQVONFfrifeVfQsvIFz/wP8F+9ksiitvBK8SrkM7+GIR+DdmnsJ3gG62YHVeFfXJ+MlDQ6v+fJk/yfotdP5/KDvhjEIH+Ld5XAcXldCEpiUttx+eM35b+OdDCbgNTFe788vxUscFvpxnMhnd9U5YGhaWbPxDrRH+tuyvT/9GLwD+n3+vjvM38Y/A99Le/1V/vvxe7+MK/AqdOCgb7y7f1L+aybiXQEvyHwtMNmf9i1/2/fIYr8+nkVdOo9GBvqlTR8f8Pqb/OWuxhvPkP4zOGNZw7savLqRWBdlEWtXvMH+1XhdLMfgjW84D++zsCFt2a/7cf0Jrz5/Dy+5zdyv++IN2n8WL1k5zH+vf4V3MAll2xt57fjM/eu/986vX0f57/kWvKQu/SaFB/16+Tu8boLj/bo33p9/Uca2/wivGX8DaYPK8T4TDq/L+gBgbEuOB3gtNxvwBsifhtfd/QpeV4AL2P5+eHfAzsRLZE/135+F6a/FO1Gu9cs9DO/z2SeL/bpvFvVpEY0M+vanTw947Si8urzIX+fn3v9Glp+Md3KvbCTW87KI9RS85PFNvOPcof57cg1e683kjDInZrz+PL543Jvqv38/Bb6Md+y6AK+1bJcW1oXX8FqYjuOzB6ImG+LKdn1NbHsE7zOwBe/cdyRe3XbANY3sz8Btb2I90/Fa2Rvex0P97VyF9/npmbbsPn69/AjvrtpD/ffoebyLlSbfU9o46Ls16yeLZ64FrbO1P6EV1KYgvFaiB/CaxevxPrz/wWspSD+4jsP7kFXjnYjPJuMuOX+5cj4b6xP3y3vTn9bsg+388lwTP9lU0ukZ00biNY9vwmspeZ20ZCmj0jyBlxTW+LH/KG3+3nhXjtV+hf8l3pV55oHjYLykspYvnlAPwrtFdYM/fxFeE+ZBactE8U6aK/04puN1f2WTMFXgnXjX4B0Q/oV3NZoZRxe8ge8b/HmLAsr9Fl4i0KU1H0y8Rzk4YNeA1y9q5r2fkrHswf700RnT38QbeJhNvS/xY3sV7/kodXhdBreS9sBWvIPsz/AuDqrxbo3euYm4dvXf09V4dX8p3tXXMWFteyOvHc8XEybDe0TGfH+7VuA1m3fPeG3D3Z4L/OXW4F1UjEzb9qvxujmq8U54+5Bx56Bfb2/0tzvF5xOVrI4HeAnny3ifjWV4J8NfpJfVzD44HO9ipQbvwH8ZjdzZi5eIzcE7zjWbYPjbtAz4eRbrX0TjCdMa4N4sPzeN/jSy/LPAgxnTjvWX/8KxrYl17o53rP3Uf983+fv+20BZRr3KJmGK4CVy7/jv3yb/79/htQRlXRfwWqpn+2VsxWtduiwjhqzW18S2d8e7222Fv+0L8D4rlrZM1tvexDqmZ7yPdX69vJlGLoDwHsvxF78eNXwOH6WJB+umva7NCVNL108OE6aG2zJF8pZ5DztcivewuxZ/X5aZTcW7ojomxJhuwkuWDkmb1gUv4T3LOZd5p6FIi5n3UM6z8FotWnSwNrNd8BLWA5xzb4QUz/Z4rW5HOeeeS5t+DV7PwB4tjVOkUGQ1hsnMJpn3NNKFZvbj4FeIhMc5txnvqu+Hrbwd9lA++z6jNjOz7fAeHHdlxqwv4XXDPBjWuqTT+xPecIQmH4bYjMPwnqMVSrLk+wHwYnqylLaua5QsSTELbGHyB+YtwOtrXYrXfHmGa4dn34g0xR8Q/wPgVtf8oMqOiOVAYB/n3E25jEM6B/O+Sqm3c66lT5QPOw7D+xqrx51zrXn6u0hByyZhOghvDMOX/f8vB3DONfrt2SIiIiLFJpsuuUF8/qFRS2nFl3GKiIiIFKrQHlxpZhcCF/r/jgmrXBEREZF2ttY516+5BbJJmJbhPeyrwWAaebqyc+4W4BYAM9PAPxERESkUi4MWyCZhehMY4X/FxTK8B+Kdmc3aJ57Z7MOFJcO0qWO3/a1913Lp+2/yda36GrlO7drLum37W/WvZfTZbRvtv7bR/mub9P3XnMCEyXnf+XYJ3sPyosDtzrkPAl4mIiIiUjSyGsPknHsK7+m7IiIiIp1Orr98V0RERCTvKWESERERCaCESURERCSAEiYRERGRAEqYRERERAIoYRIREREJoIRJREREJIASJhEREZEASphEREREAihhEhEREQmghElEREQkgBImERERkQBKmEREREQCKGESERERCaCESURERCSAEiYRERGRALFcB9De4ltXsu7TaWxaNZOaTR+TStYRiZXTpddIegwYS58djqSkvGeuwxQREZE8VrQJU82WJXzyxq/ZvOZtAFyq7nPz41VL2bj8FRa99Sd6Dx7P0DHfp7SiTw4iFRERkXxXlAnTivn38unb15NK1YNLNblcKlkLwPolL7Bx+SsMP+gX9B4yvoOiFBERkUJRdGOYFr99PZ++fQOpZLzZZCmdc/UkE1v58NUrWbXw0fYNUERERApOUSVMqz9+gpXz79vWctRSqWScRbN+z+bVb4UcmYiIiBSyokmY4tWr+WTm71qdLDVIJeMsmHE5yURNSJGJiIhIoSuahGnJuzeRStYFL5iFRH0VKxfcH0pZ0vm8/tQ13Hz5jk3O/+8zv+XhG47nph9sz7WXdWPzusUdGJ2IiLRGUSRMifoq1i7+D7hkKOW5ZJwV86bishwDJdIS779yO6lUgsEjDsl1KCIikqWiuEtu88qZRCxGknhoZSYT1dRs+pjKnsNDK1ME4Bu/mItFInz8/tN8/P5TuQ5HRESyUBQtTFvWvd8uY46q1s8LvUwRixTFx05EpFMpiiN39caFQLjdZ6lEDbWbNbZEREREiiRhcqlEu5SbStW3S7kiIiJSWIoiYSop7xV+oRbVd8yJiIgIUCQJU7e+e2LRslDLjMYq6NJrVKhlioiISGEqjoSp354YFmqZqWQdXXrvGmqZIiIiUpiKImGq7LkLpZX9QizR6LHd/pSU9QixTBERESlURfEcJjNj8B4X8fF/r27zV6MARKJlDB59fgiRSWeVStTz4exHvzB90PCDWb9yPjVVa1m9ZDYAi+Y8S0XXvvTebhR9BqobWEQkHxVFwgTQd8cvs+rDh9iy9t02PfHbIqX0HTqJbn33CDE66Wzq4lt46u/nfGH6/1z6FK8/fQ3LFs7YNu2FB74LwAGTLqfPwCs6LEYREcle0SRMZsYuB1/DO0+fSSK+EXCtKCRGWZeBDN33e2GHJ53IgcdcwYHHNJ34nDzi6Q6MRkREwlAUY5galFb2Y4+j/k5JeW8sUtqi10ai5VR0G8LoI28jWlLZThGKiIhIISqqhAmgvNtg9j7uIfoMOZxItBwsYBMtRiRaxna7nMKeR/9Tz14SERGRLyiaLrl0sdKujDj4aqrWz2P53LtZv+R5LBKlIhnHAfFYBS6VBDP6DTuOgSPPoKL7DrkOW0RERPJUUSZMDbr2HsUuB1+NSyWp2fIpp7z8Q+pw3LfXJVT2Gk5Zl0GYhfv8JhERESk+RZ0wNbBIlMoew5jgf4XKs0PG5zYgERERKShFN4ZJREREJGxKmEREREQCKGESERERCaCESURERCSAEiYRERGRAEqYRERERAIoYRIREREJoIRJREREJIASJhEREZEASphEREREAihhEhEREQmghElEREQkgBImERERkQBKmEREREQCKGESERERCaCESURERCRAYMJkZreb2Woze78jAhIRERHJN9m0MN0BTGrnOERERETyVixoAefcS2Y2tANiERGRTmby/IuYPGbMZxPmX5S7YApU5v67duTNuQumiJlzLnghL2H6l3NudFaFmgUXmgMv+L8n5DQKERFp8ET6yV5CcfysWbkOoRDNcs6NbW6BwBambJnZhcCFYZUnIiIiki9CS5icc7cAt0D+tjCJiIiItEZoCVNjJp45sz2Lb7Fe07wGsIkTb8lxJI2bNvWz1sB823eFQPuvbdL33+TrtuQwksJz7WXdtv2tutdCGrMUOtXBlkk/9jUnm8cK3AO8Bow0s6Vmdn4bYxMREREpKNncJXdGRwQiIiIikq/0pG8RERGRAEqYRERERAIoYRIREREJoIRJRERE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jRxJ12HDsGg01+GJiIhInivqhGnD7Nks/NvfWPXCC0RLS7GaGhzAFVfgnMMlkww6/nh2Pv98uo0YketwRUREJE8VZcJUt3Ej7155JatfeolkbS04R6K+/rMFtm7d9ueSRx5h2b/+xQ6nnspuP/wh0fLyHEQsIiIi+azoxjBVffIJLxx1FKteeIFkTQ041/wLkklStbV8ev/9vHjcccTXreuYQEVERKRgFFXCVLN8OTNOOYW6DRtI1dW16LWp2lqqly5lximnkKiqaqcIRUREpBAVTcLknGPW5MkktmwJblVqqoxEgtpVq3jvl78MOToREREpZEWTMC199FE2z5uHSybbVE4qHmfF00+zftaskCITERGRQlcUCZNzjgXXX++NWQpBsraWBTfeGEpZIiIiUviKImHa9MEHxNeuDa9A51j3+uvUbdgQXpkiIiJSsIoiYdowe3abu+IyRcrK2Pjee6GWKSIiIoWpOBKmt94iFY+HWmaypobNc+eGWqaIiIgUpqJImNqj68wlEsTXrw+9XBERESk8RZEwWUlJu5QbLS1tl3JFRESksBRFwtR91CiIhLsp0cpKuuy0U6hlioiISGEqioSp1157EausDL3cnrvvHnqZIiIiUniKImHqe9BBpBKJUMss6dqVrsOHh1qmiIiIFKaiSJhiXbow+MQTsVgslPIi5eXsdP75WMjdfCIiIlKYiiYjGDl5MpGQBmmX9OjBjmeeGUpZIiIiUviKJmEq79+fPa+6imhFRZvKiZSXM/a664i1sRwREREpHkWTMAEMPvFEdvrmN1udNEXKy9nz6qvpPWZMyJGJiIhIISuqhAlg1OTJ7H7llUTLy7FoNKvXWEkJsW7dGHv99Qw56aT2DVBEREQKTtElTAA7nn464595hn6HHkqktJRIeXmjy0UrKoiUlTHouOM44vnnGTBhQgdHKiIiIoUgnNvK8lDl4MEc8Le/Ubt6NSueeYZ1b7xB9QsvkHQOhgyh5x570Gf//Rk4aRIl3bvnOlwRERHJY0WbMDUo79+fYeeey7Bzz2Wgf+fbiqlTcxyViIiIFJKi7JITERERCZMSJhEREZEASphEREREAihhEhEREQmghElEREQkgBImERERkQBKmEREREQCKGESERERCaCESURERCSAEiYRERGRAEqYRERERAIoYRIREREJoIRJREREJIASJhER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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "all_locations = np.vstack(history_of_locs).astype(float) # create a matrix containing the agent's Y/X locations over time (each coordinate in one row of the matrix)\n", - "\n", - "fig, ax = plt.subplots(figsize=(10, 6)) \n", - "\n", - "# create the grid visualization\n", - "X, Y = np.meshgrid(np.arange(grid_dims[1]+1), np.arange(grid_dims[0]+1))\n", - "h = ax.pcolormesh(X, Y, np.ones(grid_dims), edgecolors='k', vmin = 0, vmax = 30, linewidth=3, cmap = 'coolwarm')\n", - "ax.invert_yaxis()\n", - "\n", - "# get generative process global parameters (the locations of the Cues, the reward condition, etc.)\n", - "cue1_loc, cue2_loc, reward_condition = my_env.cue1_loc, my_env.cue2_loc, my_env.reward_condition\n", - "reward_top = ax.add_patch(patches.Rectangle((reward_locations[0][1],reward_locations[0][0]),1.0,1.0,linewidth=5,edgecolor=[0.5, 0.5, 0.5],facecolor='none'))\n", - "reward_bottom = ax.add_patch(patches.Rectangle((reward_locations[1][1],reward_locations[1][0]),1.0,1.0,linewidth=5,edgecolor=[0.5, 0.5, 0.5],facecolor='none'))\n", - "reward_loc = reward_locations[0] if reward_condition == \"TOP\" else reward_locations[1]\n", - "\n", - "if reward_condition == \"TOP\":\n", - " reward_top.set_edgecolor('g')\n", - " reward_top.set_facecolor('g')\n", - " reward_bottom.set_edgecolor([0.7, 0.2, 0.2])\n", - " reward_bottom.set_facecolor([0.7, 0.2, 0.2])\n", - "elif reward_condition == \"BOTTOM\":\n", - " reward_bottom.set_edgecolor('g')\n", - " reward_bottom.set_facecolor('g')\n", - " reward_top.set_edgecolor([0.7, 0.2, 0.2])\n", - " reward_top.set_facecolor([0.7, 0.2, 0.2])\n", - "reward_top.set_zorder(1)\n", - "reward_bottom.set_zorder(1)\n", - "\n", - "text_offsets = [0.4, 0.6]\n", - "cue_grid = np.ones(grid_dims)\n", - "cue_grid[cue1_loc[0],cue1_loc[1]] = 15.0\n", - "for ii, loc_ii in enumerate(cue2_locations):\n", - " row_coord, column_coord = loc_ii\n", - " cue_grid[row_coord, column_coord] = 5.0\n", - " ax.text(column_coord+text_offsets[0], row_coord+text_offsets[1], cue2_loc_names[ii], fontsize = 15, color='k')\n", - " \n", - "h.set_array(cue_grid.ravel())\n", - "\n", - "cue1_rect = ax.add_patch(patches.Rectangle((cue1_loc[1],cue1_loc[0]),1.0,1.0,linewidth=8,edgecolor=[0.5, 0.2, 0.7],facecolor='none'))\n", - "cue2_rect = ax.add_patch(patches.Rectangle((cue2_loc[1],cue2_loc[0]),1.0,1.0,linewidth=8,edgecolor=[0.5, 0.2, 0.7],facecolor='none'))\n", - "\n", - "ax.plot(all_locations[:,1]+0.5,all_locations[:,0]+0.5, 'r', zorder = 2)\n", - "\n", - "temporal_colormap = cm.hot(np.linspace(0,1,T+1))\n", - "dots = ax.scatter(all_locations[:,1]+0.5,all_locations[:,0]+0.5, 450, c = temporal_colormap, zorder=3)\n", - "\n", - "ax.set_title(f\"Cue 1 located at {cue2_loc}, Cue 2 located at {cue2_loc}, Cheese on {reward_condition}\", fontsize=16)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Experimenting with different environmental structure\n", - "\n", - "Try changing around the locations of the rewards, the cues, the agent's beliefs, etc. For example, below we'll change the location of the rewards, both in the generative model and the generative process." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "# names of the reward conditions and their locations\n", - "reward_conditions = [\"LEFT\", \"RIGHT\"]\n", - "reward_locations = [(2, 2), (2, 4)] # DIFFERENT REWARD LOCATIONS\n", - "\n", - "## reset `A[3]`, the reward observation model\n", - "\n", - "A[3] = np.zeros([num_obs[3]] + num_states)\n", - "# make the reward observation depend on the location (being at reward location) and the reward condition\n", - "A[3][0,:,:,:] = 1.0 # default makes Null the most likely observation everywhere\n", - "\n", - "rew_top_idx = loc_list.index(reward_locations[0]) # linear index of the location of the \"TOP\" reward location\n", - "rew_bott_idx = loc_list.index(reward_locations[1]) # linear index of the location of the \"BOTTOM\" reward location\n", - "\n", - "# fill out the contingencies when the agent is in the \"TOP\" reward location\n", - "A[3][0,rew_top_idx,:,:] = 0.0\n", - "A[3][1,rew_top_idx,:,0] = 1.0\n", - "A[3][2,rew_top_idx,:,1] = 1.0\n", - "\n", - "# fill out the contingencies when the agent is in the \"BOTTOM\" reward location\n", - "A[3][0,rew_bott_idx,:,:] = 0.0\n", - "A[3][1,rew_bott_idx,:,1] = 1.0\n", - "A[3][2,rew_bott_idx,:,0] = 1.0\n", - "\n", - "class GridWorldEnv():\n", - " \n", - " def __init__(self,starting_loc = (4,0), cue1_loc = (2, 0), cue2 = 'L1', reward_condition = 'LEFT'):\n", - "\n", - " self.init_loc = starting_loc\n", - " self.current_location = self.init_loc\n", - "\n", - " self.cue1_loc = cue1_loc\n", - " self.cue2_name = cue2\n", - " self.cue2_loc_names = ['L1', 'L2', 'L3', 'L4']\n", - " self.cue2_loc = cue2_locations[self.cue2_loc_names.index(self.cue2_name)]\n", - "\n", - " self.reward_condition = reward_condition\n", - " print(f'Starting location is {self.init_loc}, Reward condition is {self.reward_condition}, cue is located in {self.cue2_name}')\n", - " \n", - " def step(self,action_label):\n", - "\n", - " (Y, X) = self.current_location\n", - "\n", - " if action_label == \"UP\": \n", - " \n", - " Y_new = Y - 1 if Y > 0 else Y\n", - " X_new = X\n", - "\n", - " elif action_label == \"DOWN\": \n", - "\n", - " Y_new = Y + 1 if Y < (grid_dims[0]-1) else Y\n", - " X_new = X\n", - "\n", - " elif action_label == \"LEFT\": \n", - " Y_new = Y\n", - " X_new = X - 1 if X > 0 else X\n", - "\n", - " elif action_label == \"RIGHT\": \n", - " Y_new = Y\n", - " X_new = X +1 if X < (grid_dims[1]-1) else X\n", - "\n", - " elif action_label == \"STAY\":\n", - " Y_new, X_new = Y, X \n", - " \n", - " self.current_location = (Y_new, X_new) # store the new grid location\n", - "\n", - " loc_obs = self.current_location # agent always directly observes the grid location they're in \n", - "\n", - " if self.current_location == self.cue1_loc:\n", - " cue1_obs = self.cue2_name\n", - " else:\n", - " cue1_obs = 'Null'\n", - "\n", - " if self.current_location == self.cue2_loc:\n", - " cue2_obs = cue2_names[reward_conditions.index(self.reward_condition)+1]\n", - " else:\n", - " cue2_obs = 'Null'\n", - " \n", - " # @NOTE: here we use the same variable `reward_locations` to create both the agent's generative model (the `A` matrix) as well as the generative process. \n", - " # This is just for simplicity, but it's not necessary - you could have the agent believe that the Cheese/Shock are actually stored in arbitrary, incorrect locations.\n", - "\n", - " if self.current_location == reward_locations[0]:\n", - " if self.reward_condition == 'LEFT':\n", - " reward_obs = 'Cheese'\n", - " else:\n", - " reward_obs = 'Shock'\n", - " elif self.current_location == reward_locations[1]:\n", - " if self.reward_condition == 'RIGHT':\n", - " reward_obs = 'Cheese'\n", - " else:\n", - " reward_obs = 'Shock'\n", - " else:\n", - " reward_obs = 'Null'\n", - "\n", - " return loc_obs, cue1_obs, cue2_obs, reward_obs\n", - "\n", - " def reset(self):\n", - " self.current_location = self.init_loc\n", - " print(f'Re-initialized location to {self.init_loc}')\n", - " loc_obs = self.current_location\n", - " cue1_obs = 'Null'\n", - " cue2_obs = 'Null'\n", - " reward_obs = 'Null'\n", - "\n", - " return loc_obs, cue1_obs, cue2_obs, reward_obs" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Starting location is (0, 0), Reward condition is RIGHT, cue is located in L1\n", - "Re-initialized location to (0, 0)\n", - "Action at time 0: DOWN\n", - "Grid location at time 0: (1, 0)\n", - "Reward at time 0: Null\n", - "Action at time 1: DOWN\n", - "Grid location at time 1: (2, 0)\n", - "Reward at time 1: Null\n", - "Action at time 2: UP\n", - "Grid location at time 2: (1, 0)\n", - "Reward at time 2: Null\n", - "Action at time 3: RIGHT\n", - "Grid location at time 3: (1, 1)\n", - "Reward at time 3: Null\n", - "Action at time 4: UP\n", - "Grid location at time 4: (0, 1)\n", - "Reward at time 4: Null\n", - "Action at time 5: RIGHT\n", - "Grid location at time 5: (0, 2)\n", - "Reward at time 5: Null\n", - "Action at time 6: RIGHT\n", - "Grid location at time 6: (0, 3)\n", - "Reward at time 6: Null\n", - "Action at time 7: DOWN\n", - "Grid location at time 7: (1, 3)\n", - "Reward at time 7: Null\n", - "Action at time 8: DOWN\n", - "Grid location at time 8: (2, 3)\n", - "Reward at time 8: Null\n", - "Action at time 9: RIGHT\n", - "Grid location at time 9: (2, 4)\n", - "Reward at time 9: Cheese\n" - ] - } - ], - "source": [ - "my_agent = Agent(A = A, B = B, C = C, D = D, policy_len = 4)\n", - "\n", - "my_env = GridWorldEnv(starting_loc = (0,0), cue1_loc = (2, 0), cue2 = 'L1', reward_condition = 'RIGHT')\n", - "\n", - "loc_obs, cue1_obs, cue2_obs, reward_obs = my_env.reset()\n", - "\n", - "history_of_locs = [loc_obs]\n", - "obs = [loc_list.index(loc_obs), cue1_names.index(cue1_obs), cue2_names.index(cue2_obs), reward_names.index(reward_obs)]\n", - "\n", - "T = 10 # number of total timesteps\n", - "\n", - "for t in range(T):\n", - "\n", - " qs = my_agent.infer_states(obs)\n", - " \n", - " my_agent.infer_policies()\n", - " chosen_action_id = my_agent.sample_action()\n", - "\n", - " movement_id = int(chosen_action_id[0])\n", - "\n", - " choice_action = actions[movement_id]\n", - "\n", - " print(f'Action at time {t}: {choice_action}')\n", - "\n", - " loc_obs, cue1_obs, cue2_obs, reward_obs = my_env.step(choice_action)\n", - "\n", - " obs = [loc_list.index(loc_obs), cue1_names.index(cue1_obs), cue2_names.index(cue2_obs), reward_names.index(reward_obs)]\n", - "\n", - " history_of_locs.append(loc_obs)\n", - "\n", - " print(f'Grid location at time {t}: {loc_obs}')\n", - "\n", - " print(f'Reward at time {t}: {reward_obs}')" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Cue 1 located at (0, 2), Cue 2 located at (0, 2), Cheese on RIGHT')" - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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JUwiIiIiAZQwiYiIiARQwiQiIiISQAmTiIiISAAlTCIiIiIBlDCJiIiIBFDCJCIiIhJACZOIiIhIACVMIiIiIgGUMImIiIgEUMIkIiIiEkAJk4iIiEgAJUwiIXv16au59bI90pr3ydtP44aLO/HOC7e2clQiItISSphEsmTJ3P+watHr2Q5DRETSoIRJJAtisTpmPfxjxk75ebZDERGRNChhEsmCt2f+L0XF5ex38FnZDkVERNKghEmkjW3fsobX/3UNR3z5t1hEH0ERkXygo7VIG3vxsZ+xx95H02/o+GyHIiIiaVLCJNKGVi16jYVvP8r4k67KdigiIpKBomwHINKezHr4J+w/7huUlnWmpnLTZ9Pr66qoqdpMaXmX7AUnIiKNUsIk0oY2rv2INUtm8/bMW3aa/uJjP+OlJ6Zx8fWbshOYiIg0SQmTSBs64bz7cfHYTtMeuuk4DjriOwwZcUKWohIRkSBKmERaQby+jo/eenSX6f2GjqOiU69dpnftNYT+e2kQuIhIrlLCJNIKamu28vSduz5j6SsXPZ0yYRIRkdymhEkkZIccdzmHHHd52vNPvXFrK0YjIiJh0GMFRERERAIoYRIREREJoIRJREREJIASJhEREZEASphEREREAihhEhEREQmghElEREQkgBImERERkQBKmEREREQCKGESERERCaCESURERCSAEiYRERGRAEqYRERERAIoYRIREREJoIRJREREJIASJhEREZEASphEREREAihhEhEREQmghElEREQkgBImERERkQBKmEREREQCFKUzk5ktBrYCMaDeOTe6NYMSERERySVpJUy+I51z61otEhEREZEcpS45ERERkQDmnAueyWwRsBFwwK3OudsC5g8uVERERCQ3zAkabpRul9x459wKM+sNPGdm85xzLyTOYGbnAef5/9YA72ccrgD0BNT12Xzafy2j/dd82ncto/3XMtp/LTM8aIa0Wph2WsBsGrDNOfeHJuaZrYHhzaN91zLafy2j/dd82ncto/3XMtp/LZPO/gscw2RmHcysU8PfwDGo9UhERETakXS65HYDHjGzhvnvdc4926pRiYiIiOSQwITJOfcJcGCG5TY5KFyapH3XMtp/LaP913zady2j/dcy2n8tE7j/Mh7DJCIiItLe6DlMIiIiIgFCTZjMbLKZzTezhWb2kzDLLnRmdoeZrTUzDahvBjMbYGYzzOxDM/vAzKZmO6Z8YWZlZva6mb3j77tfZDumfGRmUTN7y8yezHYs+cbMFpvZe2b2tpnNznY8+cTMuprZg2Y2z8zmmtnYbMeUL8xsuF/nGn62mNn3Gp0/rC45M4sCC4BJwHLgDeA059yHoaygwJnZ4cA24G/Ouf2zHU++MbO+QF/n3Jv+XZ1zgJNU/4KZd0dHB+fcNjMrBl4EpjrnXs1yaHnFzH4AjAY6O+emZDuefOJ/X+loff1W5szsbuC/zrnbzawEqHDObcpyWHnHz2FWAAc755akmifMFqYxwELn3CfOuVrgPuDEEMsvaP6DQDdkO4585Zxb5Zx70/97KzAX6JfdqPKD82zz/y32fzS4MQNm1h/4InB7tmOR9sPMugCHA38FcM7VKllqtqOBjxtLliDchKkfsCzh/+XohCVZYGaDgJHAa1kOJW/43UlvA2uB55xz2neZuR74MRDPchz5ygH/NrM5/rdGSHoGA58Cd/rdwbf7z0uUzJ0K/LOpGTToWwqKmXUEHgK+55zbku148oVzLuacOwjoD4wxM3ULp8nMpgBrnXNzsh1LHhvvnPsccCzwXX+IggQrAj4H/Mk5NxLYDmj8cIb8rswTgAeami/MhGkFMCDh//7+NJE24Y+/eQj4h3Pu4WzHk4/85vwZwOQsh5JPxgEn+ONw7gOOMrN7shtSfnHOrfB/rwUewRviIcGWA8sTWoQfxEugJDPHAm8659Y0NVOYCdMbwF5mNtjP1k4FHg+xfJFG+QOX/wrMdc79Mdvx5BMz62VmXf2/y/Fu3JiX1aDyiHPuMudcf+fcILzj3vPOuTOzHFbe0NdvNZ9zbjWwzMwavjj2aEA3umTuNAK64yC9r0ZJi3Ou3swuBP4FRIE7nHMfhFV+oTOzfwITgJ5mthy40jn31+xGlVfGAWcB7/ljcQAud849nb2Q8kZf4G7/LpEIcL9zTrfGS1vR12+1zEXAP/yGik+Ar2c5nrziJ+mTgPMD59WTvkVERESapkHfIiIiIgGUMImIiIgEUMIkIiIiEkAJk4iIiEgAJUwiIiIiAZQwiYiIiARQwiQiIiISQAmTiIiISID/B3AH/qLhpUPPAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "\n", - "all_locations = np.vstack(history_of_locs).astype(float) # create a matrix containing the agent's Y/X locations over time (each coordinate in one row of the matrix)\n", - "\n", - "fig, ax = plt.subplots(figsize=(10, 6)) \n", - "\n", - "# create the grid visualization\n", - "X, Y = np.meshgrid(np.arange(grid_dims[1]+1), np.arange(grid_dims[0]+1))\n", - "h = ax.pcolormesh(X, Y, np.ones(grid_dims), edgecolors='k', vmin = 0, vmax = 30, linewidth=3, cmap = 'coolwarm')\n", - "ax.invert_yaxis()\n", - "\n", - "# get generative process global parameters (the locations of the Cues, the reward condition, etc.)\n", - "cue1_loc, cue2_loc, reward_condition = my_env.cue1_loc, my_env.cue2_loc, my_env.reward_condition\n", - "reward_top = ax.add_patch(patches.Rectangle((reward_locations[0][1],reward_locations[0][0]),1.0,1.0,linewidth=5,edgecolor=[0.5, 0.5, 0.5],facecolor='none'))\n", - "reward_bottom = ax.add_patch(patches.Rectangle((reward_locations[1][1],reward_locations[1][0]),1.0,1.0,linewidth=5,edgecolor=[0.5, 0.5, 0.5],facecolor='none'))\n", - "reward_loc = reward_locations[0] if reward_condition == \"LEFT\" else reward_locations[1]\n", - "\n", - "if reward_condition == \"LEFT\":\n", - " reward_top.set_edgecolor('g')\n", - " reward_top.set_facecolor('g')\n", - " reward_bottom.set_edgecolor([0.7, 0.2, 0.2])\n", - " reward_bottom.set_facecolor([0.7, 0.2, 0.2])\n", - "elif reward_condition == \"RIGHT\":\n", - " reward_bottom.set_edgecolor('g')\n", - " reward_bottom.set_facecolor('g')\n", - " reward_top.set_edgecolor([0.7, 0.2, 0.2])\n", - " reward_top.set_facecolor([0.7, 0.2, 0.2])\n", - "reward_top.set_zorder(1)\n", - "reward_bottom.set_zorder(1)\n", - "\n", - "text_offsets = [0.4, 0.6]\n", - "cue_grid = np.ones(grid_dims)\n", - "cue_grid[cue1_loc[0],cue1_loc[1]] = 15.0\n", - "for ii, loc_ii in enumerate(cue2_locations):\n", - " row_coord, column_coord = loc_ii\n", - " cue_grid[row_coord, column_coord] = 5.0\n", - " ax.text(column_coord+text_offsets[0], row_coord+text_offsets[1], cue2_loc_names[ii], fontsize = 15, color='k')\n", - " \n", - "h.set_array(cue_grid.ravel())\n", - "\n", - "cue1_rect = ax.add_patch(patches.Rectangle((cue1_loc[1],cue1_loc[0]),1.0,1.0,linewidth=8,edgecolor=[0.5, 0.2, 0.7],facecolor='none'))\n", - "cue2_rect = ax.add_patch(patches.Rectangle((cue2_loc[1],cue2_loc[0]),1.0,1.0,linewidth=8,edgecolor=[0.5, 0.2, 0.7],facecolor='none'))\n", - "\n", - "ax.plot(all_locations[:,1]+0.5,all_locations[:,0]+0.5, 'r', zorder = 2)\n", - "\n", - "temporal_colormap = cm.hot(np.linspace(0,1,T+1))\n", - "dots = ax.scatter(all_locations[:,1]+0.5,all_locations[:,0]+0.5, 450, c = temporal_colormap, zorder=3)\n", - "\n", - "ax.set_title(f\"Cue 1 located at {cue2_loc}, Cue 2 located at {cue2_loc}, Cheese on {reward_condition}\", fontsize=16)" - ] - } - ], - "metadata": { - "interpreter": { - "hash": "24ee14d9f6452059a99d44b6cbd71d1bb479b0539b0360a6a17428ecea9f0810" - }, - "kernelspec": { - "display_name": "Python 3.8.10 64-bit ('pymdp_env2': conda)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - }, - "orig_nbformat": 4 - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/notebooks/free_energy_calculation.ipynb b/docs/notebooks/free_energy_calculation.ipynb deleted file mode 100644 index c33fb821..00000000 --- a/docs/notebooks/free_energy_calculation.ipynb +++ /dev/null @@ -1,764 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Computing the variational free energy in categorical models\n", - "\n", - "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/infer-actively/pymdp/blob/main/docs/notebooks/free_energy_calculation.ipynb)\n", - "\n", - "*Author: Conor Heins*\n", - "\n", - "This notebook walks the user through the computation of the variational free energy (or *VFE*) for discrete generative models, composed of categorical distributions. We can represent these sorts of generative models easily in array-focused programming languages like `NumPy` and `MATLAB` using matrices and vectors.\n", - "\n", - "In the discrete state-space formulation, the variational free energy is very straightforward to compute when we take advantage of the NDarray representation of probability distributions. The highly-optimized matrix algebra built into today's numerical computing paradigms can be exploited to write simple, one-line expressions for information-theoretic terms (like Kullback-Leibler divergences, cross-entropies, log-likelihoods, etc.). All these terms end up being variants of things like inner products, matrix-vector products or matrix-matrix multiplications.\n", - "\n", - "This notebook is inspired by the supplementary MATLAB script for the paper [\"A Step-by-Step Tutorial on Active Inference Modelling and its Application to Empirical Data\"](https://www.sciencedirect.com/science/article/pii/S0022249621000973) by Ryan Smith, Karl Friston, and Christopher Whyte. The original MATLAB script is called `VFE_calculation_example.m`, and can be found on [Ryan Smith's GitHub repository](https://github.com/rssmith33/Active-Inference-Tutorial-Scripts), which also contains a set of tutorial scripts that are supplementary to their paper." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Note*: When running this notebook in Google Colab, you may have to run `!pip install inferactively-pymdp` at the top of the notebook, before you can `import pymdp`. That cell is left commented out below, in case you are running this notebook from Google Colab." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# ! pip install inferactively-pymdp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Imports\n", - "\n", - "First, import `pymdp` and the modules we'll need." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from IPython.display import display, Latex\n", - "\n", - "from pymdp import utils, maths" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### A simple generative model composed of a likelihood and a prior\n", - "\n", - "We begin by constructing a simple generative model composed of two sets of categorical distributions: a likelihood distribution $P(o|s)$ and a prior distribution $P(s)$. \n", - "\n", - "Because both of these distributions are categorical distributions, we can represent them easily in code using matrices and vectors. The likelihood distribution is a conditional distribution that tells the probability that the generative model assigns to different observations, given different hidden states. Since observations and hidden states are both discrete, this can be efficiently represented as a matrix, each of whose **columns** store the conditional probabilities of all the observations (the **rows**), given a particular hidden state. Each hidden state setting is thus indexed by a column. For this reason, each column of this matrix is a categorical probability distributions and its entries must sum to one. \n", - "\n", - "The prior is represented as a 1-D vector and stores the prior probabilities that the generative model assigns to each hidden state. \n", - "\n", - "Finally, to set ourselves up later for showing model inversion and free energy calculations, we initialize an observation that we assume the agent or generative model has \"gathered\" or \"seen.\" In `pymdp` we can represent these observations either as one-hot vectors (a `1` in one entry, and `0`'s everywhere else) or more sparsely as simple indices (integers) that represent *which* of the observations was observed. Because observations are not distributions (or technically, they are Dirac distributions), you don't need to store a whole vector of elements, you can just store a particular index.\n", - "\n", - "Below we create 3 main variables: \n", - "\n", - "- An `observation` that represents a real observation that the agent or generative model \"sees\". \n", - "- The `prior` distribution that represents the agent's prior beliefs about the hidden states\n", - "- the `likliheood_dist` that represents the agent's beliefs about how hidden states probabilistically relate to observations.\n" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "## Define a quick helper function for printing arrays nicely (see https://gist.github.com/braingineer/d801735dac07ff3ac4d746e1f218ab75)\n", - "def matprint(mat, fmt=\"g\"):\n", - " col_maxes = [max([len((\"{:\"+fmt+\"}\").format(x)) for x in col]) for col in mat.T]\n", - " for x in mat:\n", - " for i, y in enumerate(x):\n", - " print((\"{:\"+str(col_maxes[i])+fmt+\"}\").format(y), end=\" \")\n", - " print(\"\")" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Observation: 0\n", - "\n", - "Prior:[0.5 0.5]\n", - "\n", - "Likelihood:\n", - "0.8 0.2 \n", - "0.2 0.8 \n" - ] - } - ], - "source": [ - "num_obs = 2 # dimensionality of observations (2 possible observation levels)\n", - "num_states = 2 # dimensionality of observations (2 possible hidden state levels)\n", - "\n", - "observation = 0 # index representation\n", - "# observation = np.array([1, 0]) # one hot representation\n", - "# observation = utils.onehot(0, num_obs) # one hot representation, but use one of pymdp's utility functions to create a one-hot\n", - "\n", - "prior = np.array([0.5, 0.5]) # simply set it by hand\n", - "# prior = np.ones(num_states) / num_states # create a uniform prior distribution by creating a vector of ones and dividing each by the number of states\n", - "# prior = utils.norm_dist(np.ones(num_states)) # use one of pymdp's utility functions to normalize any vector into a probability distribution\n", - "\n", - "likelihood_dist = np.array([ [0.8, 0.2],\n", - " [0.2, 0.8] ])\n", - "\n", - "if isinstance(observation, np.ndarray):\n", - " print(f'Observation:{observation}\\n')\n", - "else:\n", - " print(f'Observation: {observation}\\n')\n", - "print(f'Prior:{prior}\\n')\n", - "print('Likelihood:')\n", - "matprint(likelihood_dist)\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Bayesian inference\n", - "\n", - "Before we define variational free energy for this generative model, let's step through the computations involved in inverting this model using Bayes' rule, i.e. computing the optimal Bayesian posterior over hidden states, given our sensory observation (which we will formally refer to as $o_t$). By performing exact Bayesian inference first, we can directly compares its results to that of variational free energy minimization. This will help us better understand the meaning of the free energy calculations that come later.\n", - "\n", - "#### 1. Compute the likelihood over hidden states, given the observation \n", - "\n", - "Now that we have a generative model and have fixed a particular observatio $o_t$ (`observation`), we have to perform Bayes' rule to compute the posterior. Mathematically, this can be expressed as follows:\n", - "\n", - "### $ \\hspace{60mm} P(s | o _t) = \\frac{P(o = o_t | s)P(s)}{P(o = o_t)} $\n", - "\n", - "Computing the posterior via Bayes' rule (also known as \"model inversion\") is the essence of optimal statistical inference, when one has a generative model of how one's data is caused, and some data. \n", - "\n", - "To start with, let's computing the likelihood term $P(o = o_t | s)$. We can represent the computation of the likelihood with this line of `NumPy`: ``likelihood_dist[observation,:]``. By doing so, we are providing a numerical answer to the question: \"What is the likelihood that State 1 vs State 2 caused the actual sensory data $o_t$ that I've observed?\".\n", - "\n", - " Mathematically, our likelihood function $P(o = o_t | s)$ (in the statistics literature also referred to as $L(\\theta)$) is a *function of the hidden states*. The particular function over hidden states we use is *defined* by the observation $o_t$. So you can think of the likelihood as a multi-dimensional function or simply a space of functions, where the particular function you use for inference is determined by your data.\n", - "\n", - "This act of computing the likelihood via an indexing operation ``likelihood_dist[observation,:]``, is similar in spirit to the operation of *conditioning*. We are, in some sense, \"conditioning\" on a particular observation (slicing out a \"row\" of our ``likelihood_dist`` matrix), and then looking at the *induced* likelihood over possible causes (hidden states) that could've have been the latent source of that observation. This operation captures the essence of what we mean when we speak of \"inverting\" generative models. Generative models are referred to as *generative* because they can be used to generate fictive observations, given some fixed setting of latent parameters. *Inversion* is thus moving in the opposite direction -- given some sensory data, what is the consequent likelihood over the *causes* or hidden states that might have generated that data?\n", - "\n", - "**Note**: We can also compute the likelihood using a matrix-vector product, if the observation is represented as a one-hot vector.\n", - "\n", - "```\n", - "likelihood_s = likelihood_dist.T @ observation\n", - "```\n", - "\n", - "You can see think of this as a weighted average of the rows of the likelihood matrix, where the weights are provided by the observations. Since we have insisted that the observations are a one-hot vector, this is equivalent to just selecting a single row of the likelihood matrix (the one indexed by the entry of the observation that is `1.0`)." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$P(o=o_t|s):$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0.8 0.2]\n", - "==================\n", - "\n" - ] - } - ], - "source": [ - "\n", - "if isinstance(observation, np.ndarray): # use the matrix-vector version if your observation is a one-hot vector\n", - " likelihood_s = likelihood_dist.T @ observation\n", - "elif isinstance(observation, int): # use the index version if your observation is an integer index\n", - " likelihood_s = likelihood_dist[observation,:] \n", - "display(Latex('$P(o=o_t|s):$'))\n", - "print(f'{likelihood_s}')\n", - "print('==================\\n')\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 2. The joint distribution $P(o = o_t, s) = P(o = o_t|s)P(s)$ \n", - "\n", - "To compute the full numerator on the right-hand side of the Bayes' rule equation, we need to compute the joint distribution $P(o = o_t|s)P(s)$.\n", - "\n", - "The joint distribution, which also fully defines the generative model, is the product of the likelihood and prior distributions. The joint distribution expresses the joint probability of observations and hidden states, given the likelihood distribution and the prior over hidden states. If we condition on an actual observation $o_t$, as we have done here, then this joint distribution is, like the likelihood, a function of hidden states. " - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$P(o = o_t,s) = P(o = o_t|s)P(s):$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[0.4 0.1]\n", - "==================\n", - "\n" - ] - } - ], - "source": [ - "joint_prob = likelihood_s * prior # element-wise product of the likelihood of each hidden state, given the observation, with the prior probability assigned to each hidden state\n", - "display(Latex('$P(o = o_t,s) = P(o = o_t|s)P(s):$'))\n", - "print(f'{joint_prob}')\n", - "print('==================\\n')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 3. Marginal probability or marginal likelihood: $\\sum_s P(o = o_t, s) = P(o = o_t)$\n", - "\n", - "Let's remind ourselves of Bayes' rule below:\n", - "\n", - "#### $ \\hspace{60mm} P(s | o _t) = \\frac{P(o = o_t | s)P(s)}{P(o = o_t)} $\n", - "\n", - "So far, using the likelihood, the observation, and the prior, we have computed the numerator of this term: the unnormalized joint distribution $P(o = o_t,s)$. All that's left is to do is then divide this term by the denominator $P(o=o_t)$. This term is also referred to as the model evidence or the marginal likelihood. \n", - "\n", - "This can be thought of as the probability of having seen the particular observation you saw, under all possible settings of the hidden states. This can be computed by marginalizing the joint distribution, using the prior probabilities of the hidden states:\n", - "\n", - "#### $ \\hspace{60mm}P(o) = \\sum_s P(o|s)P(s)$" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "p_o = joint_prob.sum()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "#### 4. Compute the posterior $P(s|o=o_t)$\n", - "\n", - "Now to compute the Bayes-optimal posterior, simply divide the numerator by the denominator!" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$P(s|o = o_t) = \\frac{P(o = o_t,s)}{P(o=o_t)}$:" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Posterior over hidden states: [0.8 0.2]\n", - "==================\n" - ] - } - ], - "source": [ - "posterior = joint_prob / p_o # divide the joint by the marginal\n", - "display(Latex('$P(s|o = o_t) = \\\\frac{P(o = o_t,s)}{P(o=o_t)}$:'))\n", - "print(f'Posterior over hidden states: {posterior}')\n", - "print('==================')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### The variational free energy\n", - "\n", - "The variational free energy is an upper bound on **surprise**: surprise is define as $ - \\ln p(o)$, and is also known as the negative (log) evidence. By minimizing free energy, we are **minimizing** surprise and thus **maximizing** log evidence. This evidence is simply the (log of the) term we computed in the previous step, the normalizing denominator used in Bayes' rule. We can thus first compute the surprise associated with the observation we saw earlier:" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$- \\ln P(o=o_t)$:" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Surprise: 0.693\n", - "==================\n" - ] - } - ], - "source": [ - "surprise = - np.log(p_o)\n", - "\n", - "display(Latex('$- \\ln P(o=o_t)$:'))\n", - "print(f'Surprise: {surprise.round(3)}')\n", - "print('==================')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "By minimizing variational free energy with respect to the parameters of an arbitrary, parametrized distribution, also known as the approximate or variational posterior $Q(s)$, we are forcing the surprise to go down, and the model evidence to go up. In doing so, the approximate posterior distribution will get \"closer\" to the true posterior distribution (the $P(s|o)$ we computed above), $Q(s) \\approx P(s|o)$.\n", - "\n", - "This idea of minimizing a bound on surprise, is the core principle underlying the variational free energy principle, active inference, and the statistical methodology of variational principles more generally. This comes in handy because in many realistic scenarios where agents or systems need to make inferences about the hidden causes of sensory perturbations, performing Bayesian inference exactly becomes intractable (due mostly to the computation of the $P(o)$ denominator term, also known as the normalizing constant). Variational inference turns this intractable marginalization problem into a tractable optimization problem, where one only needs to change the approximate posterior $Q(s)$ in order to minimize a bound on surprise.\n", - "\n", - "But what is the variational free energy exactly, mathematically? It is commonly written as the expectation, under the approximate posterior, of the log ratio between the approximate posterior and the generative model:\n", - "\n", - "#### $ \\hspace{60mm} \\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\frac{Q(s)}{P(o, s)}] $\n", - "\n", - "Because of the rules of logarithms, we can also express this as an expected difference between the log posterior and the log generative model:\n", - "\n", - "#### $ \\hspace{60mm} \\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)] $\n", - "\n", - "By doing taking advantage of some more mathematical relationships (the factorization of the joint, rules for logarithms of products, and the definition of the conditional expectation), we can re-write this as an upper bound on surprise:\n", - "\n", - "#### $ \\hspace{60mm} \\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(s|o)] - \\ln P(o) $\n", - "\n", - "By re-arranging this equality and taking advantage of the fact that the quantity $\\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(s|o)]$ (also known as the Kullback-Leibler divergence) is greater than or equal to 0, we can easily show that the VFE is an upper bound on surprise:\n", - "\n", - "#### $ \\hspace{60mm} \\mathcal{F} \\geq - \\ln P(o) $\n", - "\n", - "Let's now compute the VFE numerically for our generative model and fixed observation. Given we already defined those two things ($o_t$ and $P(o,s)$), the last thing we need to do, is to define an initial setting of our approximate posterior $Q(s)$, and compute the variational free energy using one of the formulas above." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\frac{Q(s)}{P(o, s)}] = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)]:$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Variational free energy (F) = 0.916\n", - "==================\n" - ] - } - ], - "source": [ - "# to begin with, set our initial Q(s) equal to our prior distribution -- i.e. a flat/uninformative belief about hidden states\n", - "initial_qs = np.array([0.5, 0.5])\n", - "\n", - "# redefine generative model and observation, for ease\n", - "observation = 0\n", - "likelihood_dist = np.array([[0.8, 0.2], [0.2, 0.8]])\n", - "prior = utils.norm_dist(np.ones(2))\n", - "\n", - "# compute the joint or generative model using the factorization: P(o=o|s)P(s)\n", - "joint_prob = likelihood_dist[observation,:] * prior\n", - "\n", - "# compute the variational free energy using the expected log difference formulation\n", - "initial_F = initial_qs.dot(np.log(initial_qs) - np.log(joint_prob))\n", - "## @NOTE: because of log-rules, `initial_F` can also be computed using the division inside the logarithm:\n", - "# initial_F = initial_qs.dot(np.log(initial_qs/joint_prob))\n", - "\n", - "display(Latex('$\\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\\\frac{Q(s)}{P(o, s)}] = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)]:$'))\n", - "print(f'Variational free energy (F) = {initial_F.round(3)}')\n", - "print('==================')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now let's then change the approximate posterior $Q(s)$ and see what happens to the variational free energy.\n", - "\n", - "By definition, optimal inference (and 'perfect' VFE minimization) obtains when we set the approximate posterior $Q(s)$ to be equal to the true posterior, $Q(s) = P(s|o)$. \n", - "\n", - "As an extreme case, let's do this and then measure the variational free energy. We can see that it has decreased, relative to it's initial setting when the approximate posterior was equal to the prior $P(s)$." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\frac{Q(s)}{P(o, s)}] = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)]:$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "F = 0.693\n", - "==================\n" - ] - } - ], - "source": [ - "final_qs = posterior.copy() # now we just assert that the approximate posterior is equal to the true posterior\n", - "final_F = final_qs.dot(np.log(final_qs) - np.log(joint_prob))\n", - "\n", - "display(Latex('$\\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\\\frac{Q(s)}{P(o, s)}] = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)]:$'))\n", - "print(f'F = {final_F.round(3)}')\n", - "print('==================')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Notice that the free energy is 0.693 -- if you recall, this is exactly the **surprise** or negative log marginal likelihood $-\\ln P(o = o_t)$, related to the marginal likelihood quantity $P(o=o_t)$ that we had to compute when performing exact Bayesian inference earlier. \n", - "\n", - "It is easy to see why this equality should hold, when we consider the VFE in terms of the surprise bound:\n", - "\n", - "#### $ \\hspace{60mm} \\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(s|o)] - \\ln P(o) $\n", - "\n", - "When $Q(s) = P(s|o)$, as we have enforced with the line ``final_qs = posterior.copy()`` above, the first term $\\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(s|o)]$ will become 0. This is a property of the Kullback-Leibler divergence between two distributions $\\operatorname{D}_{KL}(Q \\parallel P) = \\mathbb{E}_{Q}[\\ln Q - \\ln P]$. \n", - "\n", - "So since that KL divergence is 0, this is a case when the bound on surprise is exact:\n", - "\n", - "#### $ \\hspace{60mm} \\mathcal{F} = 0 - \\ln P(o) = - \\ln P(o)$\n", - "\n", - "In other words, minimizing free energy \"as much as possible\" in the case of this generative model, means that the approximate posterior equals the true posterior, and the free energy bound becomes \"tight\", i.e. the free energy simply IS the negative log evidence!" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$-\\ln P(o):$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0.693\n", - "==================\n", - "\n" - ] - } - ], - "source": [ - "# compute the surprise (which we can do analytically for this simple generative model)\n", - "p_o = joint_prob.sum()\n", - "surprise = - np.log(p_o)\n", - "display(Latex('$-\\ln P(o):$'))\n", - "print(f'{surprise.round(3)}')\n", - "print('==================\\n')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Bonus material: auto-differentiation to perform gradient descent on the variational free energy\n", - "\n", - "In this section, we are going to numerically differentiate the variational free energy with respect to the parameters of the approximate posterior. We can take advantage of modern autodifferentiation software, that can calculate the derivatives of arbitrary computer programs, to compute these derivatives without doing any analytic differentiation." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [], - "source": [ - "import autograd.numpy as np_auto # Thinly-wrapped version of Numpy that is auto-differentiable\n", - "from autograd import grad # this is the function that we use to evaluate derivatives\n", - "from functools import partial" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "First, let's create a variational free energy function, that takes as input the variational posterior `qs`, an observation `obs`, the likelihood matrix `likelihood` and a prior distribution `prior`.\n", - "\n", - "By defining this computation as a function, we can calculate its derivatives automatically using the autodifferentiation package `autograd`, which allows users to pass gradients through arbitrary Python code. It includes a special version of `numpy` (`autograd.numpy`) that has a differentiable back-end. We will thus use this \"special\" verison of `numpy` when we instantiate our arrays and perform numerical operations on them." - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [], - "source": [ - "# define the variational free energy as a function of the approximate posterior, an observation, and the generative model\n", - "def vfe(qs, obs, likelihood, prior):\n", - " \"\"\"\n", - " Quick docstring below on inputs\n", - " Arguments:\n", - " =========\n", - " `qs` [1D np_auto.ndarray]: variational posterior over hidden states\n", - " `obs` [int]: index of the observation\n", - " `likelihood` [2D np_auto.ndarray]: likelihood distribution P(o|s), relating hidden states probabilistically to observations\n", - " `prior` [1D np_auto.ndarray]: prior over hidden states\n", - " \"\"\"\n", - "\n", - " likelihood_s = likelihood[obs,:]\n", - "\n", - " joint = likelihood_s * prior\n", - "\n", - " vfe = qs @ (np_auto.log(qs) - np_auto.log(joint))\n", - "\n", - " return vfe\n", - "\n", - "# initialize an observation, an initial variational posterior, a prior, and a likelihood matrix\n", - "obs = 0\n", - "init_qs = np_auto.array([0.5, 0.5])\n", - "prior = np_auto.array([0.5, 0.5])\n", - "likelihood_dist = np_auto.array([ [0.8, 0.2],\n", - " [0.2, 0.8] ])\n", - "\n", - "# this use of `partial` creates a version of the vfe function that is a function of Qs only, \n", - "# with the other parameters (the observation, the generative model) fixed as constant parameters\n", - "vfe_qs = partial(vfe, obs = obs, likelihood = likelihood_dist, prior = prior)\n", - "\n", - "# By calling `grad` on a function, we get out a function that can be used to compute the gradients of the VFE with respect to its input (in our case, `qs`)\n", - "grad_vfe_qs = grad(vfe_qs)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now that we have a variational free energy function, and a derivative function that will give us the gradients of the VFE, with respect $Q(s)$, we can use it to perform a gradient descent on VFE, with respect to the parameters of $Q(s)$. In other words, we will implement this discretized differential equation to update the approximate posterior:\n", - "\n", - "#### $ \\hspace{60mm} Q(s)_{t+1} =Q(s)_{t} - \\frac{\\partial \\mathcal{F}}{\\partial Q(s)_{t}} $\n", - "\n", - "Where the gradient term $\\frac{\\partial \\mathcal{F}}{\\partial Q(s)_{t}}$ will simply be the output of the gradient function `grad_vfe_qs` we've defined above.\n", - "\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "# number of iterations of gradient descent to perform\n", - "n_iter = 40\n", - "\n", - "qs_hist = np_auto.zeros((n_iter, 2))\n", - "qs_hist[0,:] = init_qs\n", - "\n", - "vfe_hist = np_auto.zeros(n_iter)\n", - "vfe_hist[0] = vfe_qs(qs = init_qs)\n", - "\n", - "learning_rate = 0.1 # learning rate to prevent gradient steps that are too big (overshooting)\n", - "for i in range(n_iter-1): \n", - "\n", - " dFdqs = grad_vfe_qs(qs_hist[i,:])\n", - "\n", - " ln_qs = np_auto.log(qs_hist[i,:]) - learning_rate * dFdqs # transform qs to log-space to perform gradient descent\n", - " qs_hist[i+1,:] = maths.softmax(ln_qs) # re-normalize to make it a proper, categorical Q(s) again\n", - "\n", - " vfe_hist[i+1] = vfe_qs(qs = qs_hist[i+1,:]) # measure final variational free energy" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Since we were storing the history of the variational free energy over the course of the gradient descent, we can plot its trajectory below." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "Text(0.5, 1.0, 'Gradient descent on VFE')" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "fig = plt.figure(figsize=(8,6))\n", - "plt.plot(vfe_hist)\n", - "plt.ylabel('$\\\\mathcal{F}$', fontsize = 22)\n", - "plt.xlabel(\"Iteration\", fontsize = 22)\n", - "plt.xlim(0, n_iter)\n", - "plt.ylim(vfe_hist[-1], vfe_hist[0])\n", - "plt.title('Gradient descent on VFE', fontsize = 24)" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [ - { - "data": { - "text/latex": [ - "$\\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\frac{Q(s)}{P(o, s)}] = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)]:$" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Initial F = 0.916\n", - "==================\n", - "Final posterior:\n", - "[0.8 0.2]\n", - "==================\n", - "Final F = 0.693\n", - "==================\n" - ] - } - ], - "source": [ - "final_qs, initial_F, final_F = qs_hist[-1,:], vfe_hist[0], vfe_hist[-1]\n", - "\n", - "display(Latex('$\\mathcal{F} = \\mathbb{E}_{Q(s)}[\\ln \\\\frac{Q(s)}{P(o, s)}] = \\mathbb{E}_{Q(s)}[\\ln Q(s) - \\ln P(o, s)]:$'))\n", - "print(f'Initial F = {initial_F.round(3)}')\n", - "print('==================')\n", - "\n", - "print('Final posterior:')\n", - "print(f'{final_qs.round(1)}') # note that because of numerical imprecision in the gradient descent (constant learning rate, etc.), the approximate posterior will not exactly be the optimal posterior\n", - "print('==================')\n", - "print(f'Final F = {vfe_qs(final_qs).round(3)}')\n", - "print('==================')\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.7.10 ('pymdp_env')", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - }, - "vscode": { - "interpreter": { - "hash": "43ee964e2ad3601b7244370fb08e7f23a81bd2f0e3c87ee41227da88c57ff102" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/notebooks/tmaze_demo.ipynb b/docs/notebooks/tmaze_demo.ipynb deleted file mode 100644 index 221e888f..00000000 --- a/docs/notebooks/tmaze_demo.ipynb +++ /dev/null @@ -1,793 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Active Inference Demo: T-Maze Environment\n", - "\n", - "[![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/infer-actively/pymdp/blob/main/docs/notebooks/tmaze_demo.ipynb)\n", - "\n", - "*Author: Conor Heins*\n", - "\n", - "This demo notebook provides a full walk-through of active inference using the `Agent()` class of `pymdp`. The canonical example used here is the 'T-maze' task, often used in the active inference literature in discussions of epistemic behavior (see, for example, [\"Active Inference and Epistemic Value\"](https://pubmed.ncbi.nlm.nih.gov/25689102/))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Note*: When running this notebook in Google Colab, you may have to run `!pip install inferactively-pymdp` at the top of the notebook, before you can `import pymdp`. That cell is left commented out below, in case you are running this notebook from Google Colab." - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": {}, - "outputs": [], - "source": [ - "# ! pip install inferactively-pymdp" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Imports\n", - "\n", - "First, import `pymdp` and the modules we'll need." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "import copy\n", - "\n", - "from pymdp.agent import Agent\n", - "from pymdp.utils import plot_beliefs, plot_likelihood\n", - "from pymdp import utils\n", - "from pymdp.envs import TMazeEnv" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Auxiliary Functions\n", - "\n", - "Define some utility functions that will be helpful for plotting." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Environment\n", - "\n", - "Here we consider an agent navigating a three-armed 'T-maze,' with the agent starting in a central location of the maze. The bottom arm of the maze contains an informative cue, which signals in which of the two top arms ('Left' or 'Right', the ends of the 'T') a reward is likely to be found. \n", - "\n", - "At each timestep, the environment is described by the joint occurrence of two qualitatively-different 'kinds' of states (hereafter referred to as _hidden state factors_). These hidden state factors are independent of one another.\n", - "\n", - "The first hidden state factor (`Location`) is a discrete random variable with 4 levels, that encodes the current position of the agent. Each of its four levels can be mapped to the following values: {`CENTER`, `RIGHT ARM`, `LEFT ARM`, or `CUE LOCATION`}. The random variable `Location` taking a particular value can be represented as a one-hot vector with a `1` at the appropriate level, and `0`'s everywhere else. For example, if the agent is in the `CUE LOCATION`, the current state of this factor would be $s_1 = \\begin{bmatrix} 0 & 0 & 0 & 1 \\end{bmatrix}$.\n", - "\n", - "We represent the second hidden state factor (`Reward Condition`) is a discrete random variable with 2 levels, that encodes the reward condition of the trial: {`Reward on Right`, or `Reward on Left`}. A trial where the condition is reward is `Reward on Left` is thus encoded as the state $s_2 = \\begin{bmatrix} 0 & 1\\end{bmatrix}$.\n", - "\n", - "The environment is designed such that when the agent is located in the `RIGHT ARM` and the reward condition is `Reward on Right`, the agent has a specified probability $a$ (where $a > 0.5$) of receiving a reward, and a low probability $b = 1 - a$ of receiving a 'loss' (we can think of this as an aversive or unpreferred stimulus). If the agent is in the `LEFT ARM` for the same reward condition, the reward probabilities are swapped, and the agent experiences loss with probability $a$, and reward with lower probability $b = 1 - a$. These reward contingencies are intuitively swapped for the `Reward on Left` condition. \n", - "\n", - "For instance, we can encode the state of the environment at the first time step in a `Reward on Right` trial with the following pair of hidden state vectors: $s_1 = \\begin{bmatrix} 1 & 0 & 0 & 0\\end{bmatrix}$, $s_2 = \\begin{bmatrix} 1 & 0\\end{bmatrix}$, where we assume the agent starts sitting in the central location. If the agent moved to the right arm, then the corresponding hidden state vectors would now be $s_1 = \\begin{bmatrix} 0 & 1 & 0 & 0\\end{bmatrix}$, $s_2 = \\begin{bmatrix} 1 & 0\\end{bmatrix}$. This highlights the _independence_ of the two hidden state factors. In other words, the location of the agent ($s_1$) can change without affecting the identity of the reward condition ($s_2$).\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Initialize environment\n", - "Now we can initialize the T-maze environment using the built-in `TMazeEnv` class from the `pymdp.envs` module." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Choose reward probabilities $a$ and $b$, where $a$ and $b$ are the probabilities of reward / loss in the 'correct' arm, and the probabilities of loss / reward in the 'incorrect' arm. Which arm counts as 'correct' vs. 'incorrect' depends on the reward condition (state of the 2nd hidden state factor)." - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [], - "source": [ - "reward_probabilities = [0.98, 0.02] # probabilities used in the original SPM T-maze demo" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Initialize an instance of the T-maze environment" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [], - "source": [ - "env = TMazeEnv(reward_probs = reward_probabilities)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Structure of the state --> outcome mapping\n", - "We can 'peer into' the rules encoded by the environment (also known as the _generative process_ ) by looking at the probability distributions that map from hidden states to observations. Following the SPM version of active inference, we refer to this collection of probabilistic relationships as the `A` array. In the case of the true rules of the environment, we refer to this array as `A_gp` (where the suffix `_gp` denotes the generative process). \n", - "\n", - "It is worth outlining what constitute the agent's observations in this task. In this T-maze demo, we have three sensory channels or observation modalities: `Location`, `Reward`, and `Cue`. \n", - "\n", - "1. The `Location` observation values are identical to the `Location` hidden state values. In this case, the agent always unambiguously observes its own state - if the agent is in `RIGHT ARM`, it receives a `RIGHT ARM` observation in the corresponding modality. This might be analogized to a 'proprioceptive' sense of one's own place.\n", - "\n", - "2. The `Reward` observation modality assumes the values `No Reward`, `Reward` or `Loss`. The `No Reward` (index 0) observation is observed whenever the agent isn't occupying one of the two T-maze arms (the right or left arms). The `Reward` (index 1) and `Loss` (index 2) observations are observed in the right and left arms of the T-maze, with associated probabilities that depend on the reward condition (i.e. on the value of the second hidden state factor).\n", - "\n", - "3. The `Cue` observation modality assumes the values `Cue Right`, `Cue Left`. This observation unambiguously signals the reward condition of the trial, and therefore in which arm the `Reward` observation is more probable. When the agent occupies the other arms, the `Cue` observation will be `Cue Right` or `Cue Left` with equal probability. However (as we'll see below when we intialise the agent), the agent's beliefs about the likelihood mapping render these observations uninformative and irrelevant to state inference.\n", - "\n", - "In `pymdp`, we store the set of probability distributions encoding the conditional probabilities of observations, under different configurations of hidden states, as a set of matrices referred to as the likelihood mapping or `A` array (this is a convention borrowed from SPM). The likelihood mapping _for a single modality_ is stored as a single multidimensional array (a `numpy.ndarray`) `A[m]` with the larger likelihood array, where `m` is the index of the corresponding modality. Each modality-specific A array has `num_obs[m]` rows, and as many lagging dimensions (e.g. columns, 'slices' and higher-order dimensions) as there are hidden state factors. `num_obs[m]` tells you the number of observation values (also known as \"levels\") for observation modality `m`.\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [], - "source": [ - "# here, we can get the likelihood mapping directly from the environmental class. So this is the likelihood mapping that truly describes the relatinoship between the \n", - "# environment's hidden state and the observations the agent will get\n", - "\n", - "A_gp = env.get_likelihood_dist()" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(A_gp[1][:,:,0],'Reward Right')" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(A_gp[1][:,:,1],'Reward Left')" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(A_gp[2][:,3,:],'Cue Mapping')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Transition Dynamics\n", - "\n", - "We represent the dynamics of the environment (e.g. changes in the location of the agent and changes to the reward condition) as conditional probability distributions that encode the likelihood of transitions between the states of a given hidden state factor. These distributions are collected into the so-called `B` array, also known as _transition likelihoods_ or _transition distribution_ . As with the `A` array, we denote the true probabilities describing the environmental dynamics as `B_gp`. Each sub-matrix `B_gp[f]` of the larger array encodes the transition probabilities between state-values of a given hidden state factor with index `f`. These matrices encode dynamics as Markovian transition probabilities, such that the entry $i,j$ of a given matrix encodes the probability of transition to state $i$ at time $t+1$, given state $j$ at $t$. " - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [], - "source": [ - "# here, we can get the transition mapping directly from the environmental class. So this is the transition mapping that truly describes the environment's dynamics\n", - "\n", - "B_gp = env.get_transition_dist()" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "For example, we can inspect the 'dynamics' of the `Reward Condition` factor by indexing into the appropriate sub-matrix of `B_gp`" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(B_gp[1][:,:,0],'Reward Condition Transitions')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The above transition array is the 'trivial' identity matrix, meaning that the reward condition doesn't change over time (it's mapped from whatever it's current value is to the same value at the next timestep)." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### (Controllable-) Transition Dynamics\n", - "\n", - "Importantly, some hidden state factors are _controllable_ by the agent, meaning that the probability of being in state $i$ at $t+1$ isn't merely a function of the state at $t$, but also of actions (or from the agent's perspective, _control states_ ). So now each transition likelihood encodes conditional probability distributions over states at $t+1$, where the conditioning variables are both the states at $t-1$ _and_ the actions at $t-1$. This extra conditioning on actions is encoded via an optional third dimension to each factor-specific `B` array.\n", - "\n", - "For example, in our case the first hidden state factor (`Location`) is under the control of the agent, which means the corresponding transition likelihoods `B[0]` are index-able by both previous state and action." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(B_gp[0][:,:,0],'Transition likelihood for \"Move to Center\"')" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(B_gp[0][:,:,1],'Transition likelihood for \"Move to Right Arm\"')" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(B_gp[0][:,:,2],'Transition likelihood for \"Move to Left Arm\"')" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(B_gp[0][:,:,3],'Transition likelihood for \"Move to Cue Location\"')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## The generative model\n", - "Now we can move onto setting up the *generative model* of the agent - namely, the agent's *beliefs* or assumptions about how hidden states give rise to observations, and how hidden states transition among eachother.\n", - "\n", - "In almost all MDPs, the critical building blocks of this generative model are the agent's representation of the observation likelihood, which we'll refer to as `A_gm`, and its representation of the transition likelihood, which we'll call `B_gm`. \n", - "\n", - "Here, we assume the agent has a veridical representation of the rules of the T-maze (namely, how hidden states cause observations) as well as its ability to control its own movements with certain consequences (i.e. 'noiseless' transitions). So in other words, the agent will have a veridical representation of the \"rules\" of the environment, as encoded in the arrays `A_gp` and `B_gp` of the generative process." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "metadata": {}, - "outputs": [], - "source": [ - "A_gm = copy.deepcopy(A_gp) # make a copy of the true observation likelihood to initialize the observation model\n", - "B_gm = copy.deepcopy(B_gp) # make a copy of the true transition likelihood to initialize the transition model" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### **Important Concept to Note Here!!!**\n", - "It is not necessary, or even in many cases _important_ , that the generative model is a veridical representation of the generative process. This distinction between generative model (essentially, beliefs entertained by the agent and its interaction with the world) and the generative process (the actual dynamical system 'out there' generating sensations) is of crucial importance to the active inference formalism and (in our experience) often overlooked in code.\n", - "\n", - "It is for notational and computational convenience that we encode the generative process using `A` and `B` matrices. By doing so, it simply puts the rules of the environment in a data structure that can easily be converted into the Markovian-style conditional distributions useful for encoding the agent's generative model.\n", - "\n", - "Strictly speaking, however, all the generative process needs to do is generate observations that are 'digestible' by the agent, and be 'perturbable' by actions issued by the agent. The way in which it does so can be arbitrarily complex, non-linear, and unaccessible by the agent. Namely, it doesn't have to be encoded by `A` and `B` arrays (what amount to Markovian, conditional probability tables), but could be described by arbitrarily complex nonlinear or non-differentiable transformations of hidden states that generate observatons." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Introducing the `Agent()` class\n", - "\n", - "In `pymdp`, we have abstracted much of the computations required for active inference into the `Agent` class, a flexible object that can be used to store necessary aspects of the generative model, the agent's instantaneous observations and actions, and perform action / perception using functions like `Agent.infer_states` and `Agent.infer_policies`. \n", - "\n", - "An instance of `Agent` is straightforwardly initialized with a call to the `Agent()` constructor with a list of optional arguments.\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "In our call to `Agent()`, we need to constrain the default behavior with some of our T-Maze-specific needs. For example, we want to make sure that the agent's beliefs about transitions are constrained by the fact that it can only control the `Location` factor - _not_ the `Reward Condition` (which we assumed stationary across an epoch of time). Therefore we specify this using a list of indices that will be passed as the `control_fac_idx` argument of the `Agent()` constructor. \n", - "\n", - "Each element in the list specifies a hidden state factor (in terms of its index) that is controllable by the agent. Hidden state factors whose indices are _not_ in this list are assumed to be uncontrollable." - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "metadata": {}, - "outputs": [], - "source": [ - "controllable_indices = [0] # this is a list of the indices of the hidden state factors that are controllable" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can construct our agent..." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": {}, - "outputs": [], - "source": [ - "agent = Agent(A=A_gm, B=B_gm, control_fac_idx=controllable_indices)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can inspect properties (and change) of the agent as we see fit. Let's look at the initial beliefs the agent has about its starting location and reward condition, encoded in the prior over hidden states $P(s)$, known in SPM-lingo as the `D` array." - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_beliefs(agent.D[0],\"Beliefs about initial location\")" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_beliefs(agent.D[1],\"Beliefs about reward condition\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Let's make it so that agent starts with precise and accurate prior beliefs about its starting location." - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": {}, - "outputs": [], - "source": [ - "agent.D[0] = utils.onehot(0, agent.num_states[0])" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The `onehot(value, dimension)` function within `pymdp.utils` is a nice function for quickly generating a one-hot vector of dimensions `dimension` with a `1` at the index `value`.\n", - "\n", - "And now confirm that our agent knows (i.e. has accurate beliefs about) its initial state by visualizing its priors again." - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_beliefs(agent.D[0],\"Beliefs about initial location\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Another thing we want to do in this case is make sure the agent has a 'sense' of reward / loss and thus a motivation to be in the 'correct' arm (the arm that maximizes the probability of getting the reward outcome).\n", - "\n", - "We can do this by changing the prior beliefs about observations, the `C` array (also known as the _prior preferences_ ). This is represented as a collection of distributions over observations for each modality. It is initialized by default to be all 0s. This means agent has no preference for particular outcomes. Since the second modality (index `1` of the `C` array) is the `Reward` modality, with the index of the `Reward` outcome being `1`, and that of the `Loss` outcome being `2`, we populate the corresponding entries with values whose relative magnitudes encode the preference for one outcome over another (technically, this is encoded directly in terms of relative log-probabilities). \n", - "\n", - "Our ability to make the agent's prior beliefs that it tends to observe the outcome with index `1` in the `Reward` modality, more often than the outcome with index `2`, is what makes this modality a Reward modality in the first place -- otherwise, it would just be an arbitrary observation with no extrinsic value _per se_. " - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "metadata": {}, - "outputs": [], - "source": [ - "agent.C[1][1] = 3.0\n", - "agent.C[1][2] = -3.0" - ] - }, - { - "cell_type": "code", - "execution_count": 23, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXIAAAEICAYAAABCnX+uAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8qNh9FAAAACXBIWXMAAAsTAAALEwEAmpwYAAATpUlEQVR4nO3dfbBtdX3f8fcHLgbLvYQazOHpwk0EiZRYLUdNaxMPBBtkkhppjNKODGq9NqkG2xCrxUYy0ZjGSTrTqqk0EoJa0MQwGCSj0LAlpoqey6DlSUNQwgUMTyocksYg3/6x1qWb7Tmcfe7e5+77u+f9mtkza6+H3/qutfb+7HV+a+19UlVIktq136wLkCRNxiCXpMYZ5JLUOINckhpnkEtS4wxySWqcQb6PSLKU5Aen1Nb5ST406bJJju7r2n/MZd+R5P4kX9+dda/Q5tlJPjOt9qYpSSU5dtZ1rEWSH03y5VnXoScyyPdSSb6W5G/6IPyrJBcl2bzS/FW1uapu35M1rqaq/rKv6zurzZvkaOAXgROq6rD1r25y/TE6ddZ1rKfRD5uq+tOqOn6WNem7GeR7t5+qqs3APwLmgbeNzpBk0yQrmHT5KToaeKCq7p11IfuScf8aUtsM8gZU1V3AHwMnwuNnSf82yZ8Dfz407th++HuTXJzkviR3JHlbkv36aWcn+bMk/yXJA8D5K6z2wCQfSfJwkuuT/MNdE5IckeRjfftfTfILyzWQZFtf16ahuj6Q5J4kd/VdKfv3Z7VXAUf0f4FclOTAJB9K8kCSbyb5QpK5FdbzliR/0dd6c5KXffcseU+SbyW5NcmPj2zLx5M8mOS2JK8bmnZRkncMPV9IsrMf/iDdh88f9TW/eYXaXte3+2C/niNGZjk9ye19l9K7h47TsUk+3dd8f5KPDLX5Q0mu6tv8cpKfHan5t5NcmeQR4NwkXx8O9CQvS/Klfvj5ST7b7+N7+v30lH7atf0iX+y38RXD+6Cf51lJBv3yNyX55yO1vDfJJ/pjc12SZ+w6IP1r8N4kDyX5P0lOXG4fagxV5WMvfABfA07th7cCNwG/2j8vuuB7GvDUoXHH9sMXA5cDW4BtwFeA1/bTzgYeBd4IbNq1/Mi6zwf+DvgZ4ADgXOCr/fB+wA7gl4GnAD8I3A78xNCyH+qHt/V1beqfXwa8HzgI+H7g88Dr+2kLwM6hGl4P/BHw94D9gZOAg1fYVy8HjuhrewXwCHD4yPb+u77+VwDfAp7WT78WeB9wIPAc4D7glH7aRcA7htYzWuPjx2iFuk4B7qf7i+p7gP8GXDs0vYBr+uN4dH+c/nU/7RLgvH6bDgT+aT/+IOBO4NX98Xtuv44Thmr+FvDCoWX/Anjx0Hp/H3hLP3wS8CN9W9uAW4A3jdR47HL7oN+ftwH/sX8tnAI8DBw/VMsDwPP79j8MXNpP+wm619EhQIBn7TpmPnYjL2ZdgI8VDkwXEkvAN4E7+rAZDu1TRuYv4Fi60Pv2rjd2P+31wKAfPhv4y1XWfT7wuaHn+wH3AD8KvGB0eeCtwO8OLftdQQ7MAX/L0AcHcCZwTT/8eED0z18D/G/g2bux724AXjq0vXcDGZr+eeBVdB+Q3wG2DE17F3BRP3wRkwX5B4DfGHq+me4DctvQMTttaPrPA/+rH74YuAA4aqTNVwB/OjLu/cDbh2q+eGT6O4AL++EtdB90x6xQ85uAy0ZfV8vtg/718HVgv6HplwDnD9XyO0PTTgdu7YdPofvg+pHh5X3s3sOulb3bT1fVIVV1TFX9fFX9zdC0O1dY5lC6M6U7hsbdARw5xrLDHp+nqh4DdtKd9R5D1wXyzV0PujOyZbs9hhzT13XP0HLvpzszX84HgU8Clya5O8lvJDlguRmTnJXkhqF2T6TbD7vcVX169O7ot+UI4MGqenhk2vC+msQRDB2HqlqiO0Nd6VjsqgvgzXRnqp/vuyxe048/BnjByP7/V8DwBeLR4/s/gTOSfA9wBnB9Vd0BkOSZSa7ou18eAn6NJ+671bbvzv71MbwNw9s3fAfSX9N9mFFVfwK8B3gvcG+SC5IcPOZ6NcIgb9dKP1t5P91Z3zFD444G7hpj2WFbdw30/bZH0Z3Z3gl8tf+A2fXYUlWnr9LenXRn5IcOLXdwVf2D5Wauqr+rql+pqhOAfwL8JHDW6HxJjgH+B/AG4Puq6hDgRroQ3OXIJMPPj+635W7gaUm2jEzbta8eoeva2WX0bprV9uPdDB2HJAcB38cTj8XWoeFddVFVX6+q11XVEXR/Ub0v3TWQO4FPj+z/zVX1cyvVVVU30wXsS4B/SRfsu/w2cCtwXFUdTPehPLyvVtu+rbv69Ye24a4V5n+CqvqvVXUScALwTOCXxlyvRhjk+5jqbvX7KPDOJFv6oPv3wFrvCz8pyRnpLlS+iS6EP0fXLfFwkv+Q5KnpLlaemOR5q9R1D/Ap4DeTHJxkvyTPSPKi5eZPcnKSH+4v0j1E9+H02DKzHkQXXPf1y72a/qLwkO8HfiHJAUleTtcfe2VV3UnXffOudBdXnw28lv+/r26guxj5tCSH9fth2F/RXSNYySXAq5M8pz8b/jXguqr62tA8v5Tk7yfZCpwDfKTfjpcnOaqf5xv9Nj4GXAE8M8mr+u05IMnzkjzrSeqALrzPAX6Mro98ly10+3cpyQ8BPzey3JNt43V0Z9lv7utYAH4KuHSVWuhrfkH/V9YjwP9l+eOrMRjk+6Y30r05bgc+Q/cmvnCNbVxO1x/7Dbr+5DP6s+Tv0J0dP4fuAuj9wO8A3ztGm2fRXRS7uW/3D4DDV5j3sH76Q3QX4D5N193yBP3Z5m8Cn6ULnR8G/mxktuuA4/pa3wn8TFU90E87k64v/266i7Fvr6qr+2kfBL5I1xf+KfqQHfIu4G19F8e5y9R2NfCfgI/RXWN4BvDKkdkup7vodwPwCbp+dYDnAdclWQI+DpxTVbf33UD/rG/nbrqui/9MdzH1yVwCvAj4k6q6f2j8uXRn6Q/T/WUzuo3nA7/Xb+PPDk+oqm/TBfdL6Pbt+4CzqurWVWoBOLhf3zfo/lp4AHj3GMtpGXli16EkqTWekUtS4wxySWqcQS5JjTPIJalxM/nBpEMPPbS2bds2i1XvcY888ggHHXTQrMvQmDxe7dlIx2zHjh33V9XTR8fPJMi3bdvG4uLiLFa9xw0GAxYWFmZdhsbk8WrPRjpmSe5YbrxdK5LUOINckhpnkEtS4wxySWqcQS5JjZs4yPtfjft8ki/2v5v8K9MoTJI0nmncfvi3dP+tZqn/ScrPJPnjqvrcFNqWJK1i4iDv//PKUv/0gP7hTypK0h4ylS8E9T/+v4Puf0a+t6quW2ae7cB2gLm5OQaDwTRWvddbWlraMNu6koWTT551CWNbmHUBazS45ppZlzBzvsem/HvkSQ6h+3H+N1bVjSvNNz8/X36zcwPJuP85TGvm/xPYUO+xJDuqan50/FTvWqmqbwLXAKdNs11J0sqmcdfK0/szcZI8FXgx3T9zlSTtAdPoIz+c7n/67U/3wfDRqrpiCu1KksYwjbtWvgQ8dwq1SJJ2g9/slKTGGeSS1DiDXJIaZ5BLUuMMcklqnEEuSY0zyCWpcQa5JDXOIJekxhnkktQ4g1ySGmeQS1LjDHJJapxBLkmNM8glqXEGuSQ1ziCXpMYZ5JLUOINckhpnkEtS4wxySWqcQS5JjTPIJalxBrkkNW7iIE+yNck1SW5OclOSc6ZRmCRpPJum0MajwC9W1fVJtgA7klxVVTdPoW1J0iomPiOvqnuq6vp++GHgFuDISduVJI1nGmfkj0uyDXgucN0y07YD2wHm5uYYDAbTXPVea2lpacNs60oWZl3APmyjv7bA9xhAqmo6DSWbgU8D76yqP3yyeefn52txcXEq693bDQYDFhYWZl3GbCWzrmDfNaX3b8s20nssyY6qmh8dP5W7VpIcAHwM+PBqIS5Jmq5p3LUS4APALVX1W5OXJElai2mckb8QeBVwSpIb+sfpU2hXkjSGiS92VtVnADtBJWlG/GanJDXOIJekxhnkktQ4g1ySGmeQS1LjDHJJapxBLkmNM8glqXEGuSQ1ziCXpMYZ5JLUOINckhpnkEtS4wxySWqcQS5JjTPIJalxBrkkNc4gl6TGGeSS1DiDXJIaZ5BLUuMMcklqnEEuSY0zyCWpcVMJ8iQXJrk3yY3TaE+SNL5pnZFfBJw2pbYkSWswlSCvqmuBB6fRliRpbTbtqRUl2Q5sB5ibm2MwGOypVc/U0tLShtnWlSzMuoB92EZ/bYHvMYBU1XQaSrYBV1TViavNOz8/X4uLi1NZ795uMBiwsLAw6zJmK5l1BfuuKb1/W7aR3mNJdlTV/Oh471qRpMYZ5JLUuGndfngJ8Fng+CQ7k7x2Gu1KklY3lYudVXXmNNqRJK2dXSuS1DiDXJIaZ5BLUuMMcklqnEEuSY0zyCWpcQa5JDXOIJekxhnkktQ4g1ySGmeQS1LjDHJJapxBLkmNM8glqXEGuSQ1ziCXpMYZ5JLUOINckhpnkEtS4wxySWqcQS5JjTPIJalxBrkkNc4gl6TGTSXIk5yW5MtJbkvylmm0KUkaz8RBnmR/4L3AS4ATgDOTnDBpu5Kk8UzjjPz5wG1VdXtVfRu4FHjpFNqVJI1h0xTaOBK4c+j5TuAFozMl2Q5sB5ibm2MwGExh1Xu/paWlDbOtK7rmmllXMLalpSU2b9486zLGt06vrYWTT16XdtfDwqwLWKPBOrwfphHkY6mqC4ALAObn52thYWFPrXqmBoMBG2Vb9wUeL6239Xh9TaNr5S5g69Dzo/pxkqQ9YBpB/gXguCQ/kOQpwCuBj0+hXUnSGCbuWqmqR5O8AfgksD9wYVXdNHFlkqSxTKWPvKquBK6cRluSpLXxm52S1DiDXJIaZ5BLUuMMcklqnEEuSY0zyCWpcQa5JDXOIJekxhnkktQ4g1ySGmeQS1LjDHJJapxBLkmNM8glqXEGuSQ1ziCXpMYZ5JLUOINckhpnkEtS4wxySWqcQS5JjTPIJalxBrkkNc4gl6TGTRTkSV6e5KYkjyWZn1ZRkqTxTXpGfiNwBnDtFGqRJO2GTZMsXFW3ACSZTjWSpDWbKMjXIsl2YDvA3Nwcg8FgT616ppaWljbMtu4LPF6dhVkXsA9bj9dXqurJZ0iuBg5bZtJ5VXV5P88AOLeqFsdZ6fz8fC0ujjVr8waDAQsLC7MuQ2PyePX8K3v9rJK5TybJjqr6ruuRq56RV9Wpu71WSdK68/ZDSWrcpLcfvizJTuAfA59I8snplCVJGtekd61cBlw2pVokSbvBrhVJapxBLkmNM8glqXEGuSQ1ziCXpMYZ5JLUOINckhpnkEtS4wxySWqcQS5JjTPIJalxBrkkNc4gl6TGGeSS1DiDXJIaZ5BLUuMMcklqnEEuSY0zyCWpcQa5JDXOIJekxhnkktQ4g1ySGmeQS1LjJgryJO9OcmuSLyW5LMkhU6pLkjSmSc/IrwJOrKpnA18B3jp5SZKktZgoyKvqU1X1aP/0c8BRk5ckSVqLTVNs6zXAR1aamGQ7sB1gbm6OwWAwxVXvvZaWljbMtu4LPF6dhVkXsA9bj9dXqurJZ0iuBg5bZtJ5VXV5P895wDxwRq3WIDA/P1+Li4u7UW57BoMBCwsLsy5DY/J49ZJZV7DvWj0iV5RkR1XNj45f9Yy8qk5dpeGzgZ8EfnycEJckTddEXStJTgPeDLyoqv56OiVJktZi0rtW3gNsAa5KckOS/z6FmiRJazDRGXlVHTutQiRJu8dvdkpS4wxySWqcQS5JjTPIJalxBrkkNc4gl6TGGeSS1DiDXJIaZ5BLUuMMcklqnEEuSY0zyCWpcQa5JDXOIJekxhnkktQ4g1ySGmeQS1LjDHJJapxBLkmNM8glqXEGuSQ1ziCXpMYZ5JLUOINckho3UZAn+dUkX0pyQ5JPJTliWoVJksYz6Rn5u6vq2VX1HOAK4JcnL0mStBYTBXlVPTT09CCgJitHkrRWqZose5O8EzgL+BZwclXdt8J824HtAHNzcyddeumlE623FUtLS2zevHnWZWhMHq/2bKRjdvLJJ++oqvnR8asGeZKrgcOWmXReVV0+NN9bgQOr6u2rFTM/P1+Li4urV70PGAwGLCwszLoMjcnj1Z6NdMySLBvkm1ZbsKpOHXMdHwauBFYNcknS9Ex618pxQ09fCtw6WTmSpLVa9Yx8Fb+e5HjgMeAO4N9MXpIkaS0mCvKq+hfTKkSStHv8ZqckNc4gl6TGGeSS1DiDXJIaN/E3O3drpcl9dHe5bASHAvfPugiNzePVno10zI6pqqePjpxJkG8kSRaX+yaW9k4er/Z4zOxakaTmGeSS1DiDfP1dMOsCtCYer/Zs+GNmH7kkNc4zcklqnEEuSY0zyNdJktOSfDnJbUneMut69OSSXJjk3iQ3zroWjSfJ1iTXJLk5yU1Jzpl1TbNiH/k6SLI/8BXgxcBO4AvAmVV180wL04qS/BiwBFxcVSfOuh6tLsnhwOFVdX2SLcAO4Kc34vvMM/L18Xzgtqq6vaq+DVxK9483tJeqqmuBB2ddh8ZXVfdU1fX98MPALcCRs61qNgzy9XEkcOfQ851s0BeYtCck2QY8F7huxqXMhEEuqWlJNgMfA95UVQ/Nup5ZMMjXx13A1qHnR/XjJE1RkgPoQvzDVfWHs65nVgzy9fEF4LgkP5DkKcArgY/PuCZpn5IkwAeAW6rqt2ZdzywZ5Ougqh4F3gB8ku4CzEer6qbZVqUnk+QS4LPA8Ul2JnntrGvSql4IvAo4JckN/eP0WRc1C95+KEmN84xckhpnkEtS4wxySWqcQS5JjTPIJalxBrkkNc4gl6TG/T9rPdkpWKXk+wAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_beliefs(agent.C[1],\"Prior beliefs about observations\")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Active Inference\n", - "Now we can start off the T-maze with an initial observation and run active inference via a loop over a desired time interval." - ] - }, - { - "cell_type": "code", - "execution_count": 24, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " === Starting experiment === \n", - " Reward condition: Right, Observation: [CENTER, No reward, Cue Left]\n", - "[Step 0] Action: [Move to CUE LOCATION]\n", - "[Step 0] Observation: [CUE LOCATION, No reward, Cue Right]\n", - "[Step 1] Action: [Move to RIGHT ARM]\n", - "[Step 1] Observation: [RIGHT ARM, Reward!, Cue Right]\n", - "[Step 2] Action: [Move to RIGHT ARM]\n", - "[Step 2] Observation: [RIGHT ARM, Reward!, Cue Left]\n", - "[Step 3] Action: [Move to RIGHT ARM]\n", - "[Step 3] Observation: [RIGHT ARM, Reward!, Cue Right]\n", - "[Step 4] Action: [Move to RIGHT ARM]\n", - "[Step 4] Observation: [RIGHT ARM, Reward!, Cue Right]\n" - ] - } - ], - "source": [ - "T = 5 # number of timesteps\n", - "\n", - "obs = env.reset() # reset the environment and get an initial observation\n", - "\n", - "# these are useful for displaying read-outs during the loop over time\n", - "reward_conditions = [\"Right\", \"Left\"]\n", - "location_observations = ['CENTER','RIGHT ARM','LEFT ARM','CUE LOCATION']\n", - "reward_observations = ['No reward','Reward!','Loss!']\n", - "cue_observations = ['Cue Right','Cue Left']\n", - "msg = \"\"\" === Starting experiment === \\n Reward condition: {}, Observation: [{}, {}, {}]\"\"\"\n", - "print(msg.format(reward_conditions[env.reward_condition], location_observations[obs[0]], reward_observations[obs[1]], cue_observations[obs[2]]))\n", - "\n", - "for t in range(T):\n", - " qx = agent.infer_states(obs)\n", - "\n", - " q_pi, efe = agent.infer_policies()\n", - "\n", - " action = agent.sample_action()\n", - "\n", - " msg = \"\"\"[Step {}] Action: [Move to {}]\"\"\"\n", - " print(msg.format(t, location_observations[int(action[0])]))\n", - "\n", - " obs = env.step(action)\n", - "\n", - " msg = \"\"\"[Step {}] Observation: [{}, {}, {}]\"\"\"\n", - " print(msg.format(t, location_observations[obs[0]], reward_observations[obs[1]], cue_observations[obs[2]]))" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The agent begins by moving to the `CUE LOCATION` to resolve its uncertainty about the reward condition - this is because it knows it will get an informative cue in this location, which will signal the true reward condition unambiguously. At the beginning of the next timestep, the agent then uses this observaiton to update its posterior beliefs about states `qx[1]` to reflect the true reward condition. Having resolved its uncertainty about the reward condition, the agent then moves to `RIGHT ARM` to maximize utility and continues to do so, given its (correct) beliefs about the reward condition and the mapping between hidden states and reward observations. \n", - "\n", - "Notice, perhaps confusingly, that the agent continues to receive observations in the 3rd modality (i.e. samples from `A_gp[2]`). These are observations of the form `Cue Right` or `Cue Left`. However, these 'cue' observations are random and totally umambiguous unless the agent is in the `CUE LOCATION` - this is reflected by totally entropic distributions in the corresponding columns of `A_gp[2]` (and the agents beliefs about this ambiguity, reflected in `A_gm[2]`. See below." - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "metadata": { - "scrolled": false - }, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(A_gp[2][:,:,0],'Cue Observations when condition is Reward on Right, for Different Locations')" - ] - }, - { - "cell_type": "code", - "execution_count": 26, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_likelihood(A_gp[2][:,:,1],'Cue Observations when condition is Reward on Left, for Different Locations')" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "The final column on the right side of these matrices represents the distribution over cue observations, conditioned on the agent being in `CUE LOCATION` and the appropriate Reward Condition. This demonstrates that cue observations are uninformative / lacking epistemic value for the agent, _unless_ they are in `CUE LOCATION.`" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Now we can inspect the agent's final beliefs about the reward condition characterizing the 'trial,' having undergone 10 timesteps of active inference." - ] - }, - { - "cell_type": "code", - "execution_count": 27, - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], - "source": [ - "plot_beliefs(qx[1],\"Final posterior beliefs about reward condition\")" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3.8.8 ('base')", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.8.8" - }, - "vscode": { - "interpreter": { - "hash": "70b7ceca5df5387258d861d4588082cea9500e731be001548c95afd8cd8c3af8" - } - } - }, - "nbformat": 4, - "nbformat_minor": 2 -} diff --git a/docs/requirements.txt b/docs/requirements.txt deleted file mode 100644 index 1987806b..00000000 --- a/docs/requirements.txt +++ /dev/null @@ -1,17 +0,0 @@ -# sphinx <4 required by myst-nb v0.12.0 (Feb 2021) -# sphinx >=3 required by sphinx-autodoc-typehints v1.11.1 (Oct 2020) -# sphinx >=3, <4 # old version of sphinx dependency, based on two comments above - -# New commit to myst-nb (September 2021) suggests it can work with sphinx >4 (see https://github.com/executablebooks/MyST-NB/commit/9f6fae2da3f1ce3e726320eade079b8e25a878fa) -sphinx==4.2.0 -sphinx_rtd_theme -sphinx-autodoc-typehints==1.11.1 -jupyter-sphinx>=0.3.2 -myst-nb -jinja2==3.0.0 - -# Packages used for notebook execution -matplotlib -numpy -seaborn -. \ No newline at end of file diff --git a/docs/notebooks/active_inference_from_scratch.ipynb b/examples/legacy/active_inference_from_scratch.ipynb similarity index 100% rename from docs/notebooks/active_inference_from_scratch.ipynb rename to examples/legacy/active_inference_from_scratch.ipynb diff --git a/docs/notebooks/pymdp_fundamentals.ipynb b/examples/legacy/pymdp_fundamentals.ipynb similarity index 100% rename from docs/notebooks/pymdp_fundamentals.ipynb rename to examples/legacy/pymdp_fundamentals.ipynb diff --git a/docs/notebooks/using_the_agent_class.ipynb b/examples/legacy/using_the_agent_class.ipynb similarity index 100% rename from docs/notebooks/using_the_agent_class.ipynb rename to examples/legacy/using_the_agent_class.ipynb