Skip to content

Commit

Permalink
Update plasticity.rst
Browse files Browse the repository at this point in the history
  • Loading branch information
ErbB4 authored Nov 11, 2024
1 parent 235ad2d commit 6de5e29
Showing 1 changed file with 50 additions and 50 deletions.
100 changes: 50 additions & 50 deletions doc/tutorial/plasticity.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,55 +32,55 @@ The Python file ``01-setup.py`` is the scaffolding we will build our simulation
around and thus contains some passages that might seem redundant now, but will
be helpful in later steps.

We begin by defining the global settings
We begin by defining the global settings:

.. literalinclude:: ../../python/example/plasticity/unconnected.py
:language: python
:lines: 7-15

- ``N`` is the cell count of the simulation
- ``T`` is the total runtime of the simulation in ``ms``
- ``t_interval`` defines the _interval_ such that the simulation is advance in
- ``N`` is the cell count of the simulation.
- ``T`` is the total runtime of the simulation in ``ms``.
- ``t_interval`` defines the _interval_ such that the simulation advances in
discrete steps ``[0, 1, 2, ...] t_interval``. Later, this will be the timescale of
plasticity.
- ``dt`` is the numerical timestep on which cells evolve
- ``dt`` is the numerical timestep on which cells evolve.

These parameters are used here
These parameters are used here:

.. literalinclude:: ../../python/example/plasticity/unconnected.py
:language: python
:lines: 52-62

where we run the simulation in increments of ``t_interval``.

Back to the recipe; we set a prototypical cell
Back to the recipe, we set a prototypical cell:

.. literalinclude:: ../../python/example/plasticity/unconnected.py
:language: python
:lines: 23

and deliver it for all ``gid`` s
and deliver it for all ``gid``:

.. literalinclude:: ../../python/example/plasticity/unconnected.py
:language: python
:lines: 42-43

Also, each cell has an event generator attached
Also, each cell has an event generator attached, using a Poisson point process seeded with the cell's ``gid``.

.. literalinclude:: ../../python/example/plasticity/unconnected.py
:language: python
:lines: 33-40

using a Poisson point process seeded with the cell's ``gid``. All other
parameters are set in the constructor

All other parameters are set in the constructor:

.. literalinclude:: ../../python/example/plasticity/unconnected.py
:language: python
:lines: 19-28

We also proceed to add spike recording and generate plots using a helper
function ``plot_spikes`` from ``util.py``. You can skip the following details
for now and come back later if you are interested how it works. Rates are
for now and come back later if you are interested in how it works. Rates are
computed by binning spikes into ``t_interval`` and the neuron id; the mean rate
is the average across the neurons smoothed using a Savitzky-Golay filter
(``scipy.signal.savgol_filter``).
Expand All @@ -91,7 +91,7 @@ We plot per-neuron and mean rates:
:width: 400
:align: center

We also generate raster plots via ``scatter``.
We also generate raster plots via ``scatter``:

.. figure:: ../../python/example/plasticity/01-raster.svg
:width: 400
Expand All @@ -103,7 +103,7 @@ A Randomly Wired Network

We use inheritance to derive a new recipe that contains all the functionality of
the ```unconnected`` recipe. We then add a random connectivity matrix during
construction, fixed connection weights, and deliver the resulting connections
construction, fix connection weights, and deliver the resulting connections
via the ``connections_on`` callback, with the only extra consideration of
allowing multiple connections between two neurons.

Expand All @@ -114,13 +114,13 @@ incoming/outgoing connections per neuron, and the maximum for both directions
:language: python
:lines: 26-31

The connection matrix is used to construct connections
The connection matrix is used to construct connections,

.. literalinclude:: ../../python/example/plasticity/random_network.py
:language: python
:lines: 33-38

together with the fixed connection parameters
together with the fixed connection parameters:

.. literalinclude:: ../../python/example/plasticity/random_network.py
:language: python
Expand All @@ -129,31 +129,31 @@ together with the fixed connection parameters
We define helper functions ``add|del_connections`` to manipulate the connection
table while upholding these invariants:

- no self-connections, i.e. ``connection[i, i] == 0``
- no self-connections, i.e., ``connection[i, i] == 0``
- ``inc[i]`` the sum of ``connections[:, i]``
- no more incoming connections than allowed by ``max_inc``, i.e. ``inc[i] <= max_inc``
- no more incoming connections than allowed by ``max_inc``, i.e., ``inc[i] <= max_inc``
- ``out[i]`` the sum of ``connections[i, :]``
- no more outgoing connections than allowed by ``max_out``, i.e. ``out[i] <= max_out``
- no more outgoing connections than allowed by ``max_out``, i.e., ``out[i] <= max_out``

These methods return ``True`` on success and ``False`` otherwise
These methods return ``True`` on success and ``False`` otherwise.

.. literalinclude:: ../../python/example/plasticity/random_network.py
:language: python
:lines: 40-54

Both are used in ``rewire`` to produce a random connection matrix
Both are used in ``rewire`` to produce a random connection matrix.

.. literalinclude:: ../../python/example/plasticity/random_network.py
:language: python
:lines: 56-65

We then proceed to run the simulation
We then proceed to run the simulation:

.. literalinclude:: ../../python/example/plasticity/random_network.py
:language: python
:lines: 68-79

and plot the results as before
and plot the results as before:

.. figure:: ../../python/example/plasticity/02-rates.svg
:width: 400
Expand Down Expand Up @@ -181,34 +181,34 @@ which is used to determine the creation or destruction of synaptic connections v

.. math::
\frac{dC}{dt} = \alpha(\nu - \nu^*)
\frac{dC}{dt} = \alpha(\nu - \nu^*).
Thus we need to add some extra information to our simulation; namely the
Thus we need to add some extra information to our simulation, namely the
setpoint :math:`\nu^*_i` for each neuron :math:`i` and the sensitivity parameter
:math:`\alpha`. We will also use a simplified version of the differential
equation above, namely adding/deleting exactly one connection if the difference
of observed to desired spiking frequency exceeds :math:`\pm\alpha`. This is both
for simplicity and to avoid sudden changes in the network structure.

As before, we set up global parameters
As before, we set up global parameters:

.. literalinclude:: ../../python/example/plasticity/homeostasis.py
:language: python
:lines: 10-24

and prepare our simulation
and prepare our simulation:

.. literalinclude:: ../../python/example/plasticity/homeostasis.py
:language: python
:lines: 37-39

Note that our new recipe is almost unaltered from the random network
Note that our new recipe is almost unaltered from the random network.

.. literalinclude:: ../../python/example/plasticity/homeostasis.py
:language: python
:lines: 27-33

all changes are contained to the way we run the simulation. To add a further
All changes are contained in the way we run the simulation. To add a further
interesting feature, we skip the rewiring for the first half of the simulation.
The initial network is unconnected, but could be populated randomly (or any
other way) if desired by calling ``self.rewire()`` in the constructor of
Expand All @@ -233,57 +233,57 @@ recipe:

Important caveats:

- without ``update``, changes to the recipe have no effect
- vice versa ``update`` has no effect if the recipe doesn't return different
data than before
- without ``update``, changes to the recipe have no effect.
- vice versa ``update`` has no effect if the recipe doesn't return a different
data than before.
- ``update`` will delete all existing connections and their parameters, so
all connections to be kept must be explicitly re-instantiated
- ``update`` will **not** delete synapses or their state, e.g. ODEs will
still be integrated even if not connected and currents might be produced
all connections to be kept must be explicitly re-instantiated.
- ``update`` will **not** delete synapses or their state, e.g., ODEs will
still be integrated even if not connected and currents might be produced;
- neither synapses/targets nor detectors/sources can be altered. Create all
endpoints up front.
- only the network is updated (this might change in future versions!)
- only the network is updated (this might change in future versions!).
- be very aware that ``connections_on`` might be called in arbitrary order
and by multiples (potentially different) threads and processes! This
and by multiple (potentially different) threads and processes! This
requires some thought and synchronization when dealing with random numbers
and updating data *inside* ``connections_on``.

Changes are based on the difference of current rate we compute from the spikes
during the last interval
Changes are based on the difference from the current rate we compute from the spikes
during the last interval,

.. literalinclude:: ../../python/example/plasticity/homeostasis.py
:language: python
:lines: 49-54

and the setpoint times the sensitivity
and the setpoint times the sensitivity.

.. literalinclude:: ../../python/example/plasticity/homeostasis.py
:language: python
:lines: 55

Then, each potential pairing of target and source is checked in random
order for whether adding or removing a connection is required
order for whether adding or removing a connection is required:

.. literalinclude:: ../../python/example/plasticity/homeostasis.py
:language: python
:lines: 59-68

If we find an option to fulfill that requirement, we do so and proceed to the
next target. The randomization is important here, espcially for adding
connections as to avoid biases, in particular when there are too few eglible
next target. The randomization is important here, especially for adding
connections to avoid biases, in particular when there are too few eligible
connection partners. The ``randrange`` function produces a shuffled range ``[0,
N)``. We leverage the helper functions from the random network recipe to
manipulate the connection table, see the discussion above.

Finally, we plot spiking rates as before; the jump at the half-way point is the
effect of the plasticity activating after which each neuron moves to the
setpoint
setpoint.

.. figure:: ../../python/example/plasticity/03-rates.svg
:width: 400
:align: center

and the resulting network
And the resulting network:

.. figure:: ../../python/example/plasticity/03-final-graph.svg
:width: 400
Expand All @@ -294,14 +294,14 @@ Conclusion

This concludes our foray into structural plasticity. While the building blocks

- an explicit representation of the connections,
- running the simulation in batches (and calling ``simulation.update``!)
- a rule to derive the change
- an explicit representation of the connections;
- running the simulation in batches (and calling ``simulation.update``!);
- a rule to derive the change;

will likely be the same in all approaches, the concrete implementation of the
rules is the centerpiece here. For example, although spike rate homeostasis was
used here, mechanism states and ion concentrations --- extracted via the normal
probe and sample interface --- can be leveraged to build rules. Due to the way
used here, mechanism states and ion concentrations---extracted via the normal
probe and sample interface---can be leveraged to build rules. Due to the way
the Python interface is required to link to measurements, using the C++ API for
access to streaming spike and measurement data could help to address performance
issues. Plasticity as shown also meshes with the high-level connection builder.
Expand Down

0 comments on commit 6de5e29

Please sign in to comment.