From 979d63fad4a662c4ce621ea714746b120781c888 Mon Sep 17 00:00:00 2001 From: ackurth-nc Date: Wed, 21 Sep 2022 14:04:55 -0700 Subject: [PATCH] Fix typos, amend comments, add license --- tutorials/end_to_end/convert_params.py | 8 +- ...rial02_excitatory_inhibitory_network.ipynb | 152 +++++++++--------- 2 files changed, 80 insertions(+), 80 deletions(-) diff --git a/tutorials/end_to_end/convert_params.py b/tutorials/end_to_end/convert_params.py index be9b748b2..7bad45312 100644 --- a/tutorials/end_to_end/convert_params.py +++ b/tutorials/end_to_end/convert_params.py @@ -1,3 +1,6 @@ +# Copyright (C) 2021-22 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# See: https://spdx.org/licenses/ import numpy as np import warnings from scipy.optimize import fsolve @@ -5,7 +8,6 @@ from scipy.special import erf -# Method to convert parameters from rate to LIF def convert_rate_to_lif_params(**kwargs): '''Convert rate parameters to LIF parameters. The mapping is based on A unified view on weakly correlated recurrent @@ -87,13 +89,13 @@ def convert_rate_to_lif_params(**kwargs): # Define auxiliary functions for weight conversion def _mean_input(weight): ''' - Calculate mean input to single neuron given mean exciatory weight + Calculate mean input to single neuron given mean excitatory weight ''' return num_neurons_exc * (1 - gamma * g_factor) * weight * rate + bias def _std_input(weight): ''' - Calculate mean input to single neuron given mean exciatory weight + Calculate mean input to single neuron given mean excitatory weight ''' return num_neurons_exc * (1 + gamma * g_factor**2) * weight ** 2 * rate diff --git a/tutorials/end_to_end/tutorial02_excitatory_inhibitory_network.ipynb b/tutorials/end_to_end/tutorial02_excitatory_inhibitory_network.ipynb index d1e7cc2fd..1d7c8320c 100644 --- a/tutorials/end_to_end/tutorial02_excitatory_inhibitory_network.ipynb +++ b/tutorials/end_to_end/tutorial02_excitatory_inhibitory_network.ipynb @@ -101,7 +101,7 @@ "outputs": [], "source": [ "class EINetwork(AbstractProcess):\n", - " \"\"\"Network of recurrently connected neurons\n", + " \"\"\"Network of recurrently connected neurons.\n", " \"\"\"\n", " def __init__(self, **kwargs):\n", " super().__init__(**kwargs)\n", @@ -110,24 +110,24 @@ " bias_exc = kwargs.pop(\"bias_exc\", 1)\n", " shape_inh = kwargs.pop(\"shape_inh\", (1,))\n", " bias_inh = kwargs.pop(\"bias_inh\", 1)\n", - " # Factor controlling strength of inhibitory synapses relative to excitatory synapses\n", + " # Factor controlling strength of inhibitory synapses relative to excitatory synapses.\n", " self.g_factor = kwargs.pop(\"g_factor\", 4)\n", " # Factor controlling response properties of network.\n", - " # Larger q_factor -> longer lasting effect of provided input\n", + " # Larger q_factor implies longer lasting effect of provided input.\n", " self.q_factor = kwargs.pop(\"q_factor\", 1)\n", " weights = kwargs.pop(\"weights\")\n", " \n", " full_shape = shape_exc + shape_inh\n", " \n", " self.state = Var(shape=(full_shape,), init=0)\n", - " # Variable for possible alternative state\n", + " # Variable for possible alternative state.\n", " self.state_alt = Var(shape=(full_shape,), init=0)\n", - " # Biases provided to neuros\n", + " # Biases provided to neurons.\n", " self.bias_exc = Var(shape=(shape_exc,), init=bias_exc)\n", " self.bias_inh = Var(shape=(shape_inh,), init=bias_inh)\n", " self.weights = Var(shape=(full_shape, full_shape), init=weights)\n", "\n", - " # Ports for receiving input or sending output\n", + " # Ports for receiving input or sending output.\n", " self.inport = InPort(shape=(full_shape,))\n", " self.outport = OutPort(shape=(full_shape,))\n", " \n", @@ -135,27 +135,28 @@ " def generate_gaussian_weights(q_factor, g_factor, shape_exc, full_shape):\n", " '''Generate connectivity drawn from a Gaussian distribution with mean 0\n", " and std of q_factor ** 2 * sqrt(full_shape).\n", - " W[i, j] is connection weight from pre-synaptic neuron j to post-synaptic neuron i\n", + " W[i, j] is connection weight from pre-synaptic neuron j to post-synaptic neuron i.\n", " '''\n", - " # Set scaled standard deviation of recurrent weights\n", + " # Set scaled standard deviation of recurrent weights.\n", " J = q_factor**2 * 6 / full_shape\n", " weights = np.random.normal(0, J,\n", " (full_shape, full_shape))\n", " \n", " # Impose constraint that neurons can **either** be excitatory (positive weight)\n", - " # **or** inhibitory (negative weight)\n", + " # **or** inhibitory (negative weight),\n", " exc_conns = np.full(weights.shape, True)\n", - " exc_conns[:, shape_exc:] = False # Set entries for inhibitory neurons to False\n", + " exc_conns[:, shape_exc:] = False # Set entries for inhibitory neurons to False.\n", " inh_conns = np.invert(exc_conns)\n", " \n", " mask_pos_weights = (weights > 0)\n", " mask_neg_weights = (weights < 0)\n", "\n", - " # Set negative weights of exciatory neurons to zero and similarly for inhibitory neurons -> induce sparsity\n", + " # Set negative weights of exciatory neurons to zero and similarly for inhibitory neurons.\n", + " # This induce sparsity in the connectivity.\n", " weights[mask_neg_weights * exc_conns] = 0\n", " weights[mask_pos_weights * inh_conns] = 0\n", "\n", - " # We finally need to increase the inhibitory weights by a factor to control balance\n", + " # We finally need to increase the inhibitory weights by a factor to control balance.\n", " weights[inh_conns] *= g_factor\n", " \n", " return weights" @@ -176,14 +177,14 @@ "metadata": {}, "outputs": [], "source": [ - "# Import parent classes for ProcessModels for Hierarchical Processes\n", + "# Import parent classes for ProcessModels for Hierarchical Processes.\n", "from lava.magma.core.model.py.model import PyLoihiProcessModel\n", "from lava.magma.core.model.sub.model import AbstractSubProcessModel\n", "\n", - "# Import execution protocol\n", + "# Import execution protocol.\n", "from lava.magma.core.sync.protocols.loihi_protocol import LoihiProtocol\n", "\n", - "# Import decorators\n", + "# Import decorators..\n", "from lava.magma.core.decorator import implements, tag, requires" ] }, @@ -224,7 +225,7 @@ "from scipy.special import erf\n", "\n", "@implements(proc=EINetwork, protocol=LoihiProtocol)\n", - "@tag('rate_neurons') # tag allows for easy selection of ProcessModel in case multiple are defined\n", + "@tag('rate_neurons') # Tag allows for easy selection of ProcessModel in case multiple are defined.\n", "@requires(CPU)\n", "class RateEINetworkModel(PyLoihiProcessModel):\n", "\n", @@ -252,7 +253,7 @@ " self.weights_scaled = False\n", " \n", " def get_decay(self):\n", - " '''Construct decay factor\n", + " '''Construct decay factor.\n", " '''\n", " dr_full = np.array([self.dr_exc] * self.shape_exc + [self.dr_inh] * self.shape_inh)\n", " self.decay = 1 - dr_full\n", @@ -260,13 +261,13 @@ " self.got_decay= True\n", " \n", " def get_bias(self):\n", - " '''Construce biases\n", + " '''Construce biases.\n", " '''\n", " self.bias_full = np.hstack([self.bias_exc, self.bias_inh])\n", " self.got_bias = False \n", " \n", " def scale_weights(self):\n", - " '''Scale the weights with integration time step\n", + " '''Scale the weights with integration time step.\n", " '''\n", " \n", " self.weights[:, self.shape_exc:] *= self.dr_exc\n", @@ -276,12 +277,12 @@ " self.weights_scaled = True\n", " \n", " def state_update(self, state):\n", - " \"\"\"Update network state according to \n", + " \"\"\"Update network state according to:\n", " r[i + 1] = (1 - dr)r[i] + Wr[i]*r*dr + bias*dr\n", " \"\"\"\n", - " state_new = self.decay * state # decay state\n", - " state_new += self.bias_full # add bias\n", - " state_new += self.weights @ erf(state) # add recurrent input\n", + " state_new = self.decay * state # Decay the state.\n", + " state_new += self.bias_full # Add the bias.\n", + " state_new += self.weights @ erf(state) # Add the recurrent input.\n", " return state_new\n", " \n", " def run_spk(self):\n", @@ -328,19 +329,18 @@ "metadata": {}, "outputs": [], "source": [ - "# Fix randomness\n", + "# Fix the randomness.\n", "np.random.seed(1234)\n", "\n", - "# Dimensionality of network\n", + "# Define dimensionality of the network.\n", "dim = 400\n", "shape = (dim,)\n", "\n", - "# We represented the dimensionality by 400 neurons. As stated above 80% of the neurons will be excitatory\n", + "# We represent the dimensionality by 400 neurons. As stated above 80% of the neurons will be excitatory.\n", "num_neurons_exc = int(dim * 0.8)\n", "num_neurons_inh = dim - num_neurons_exc\n", "\n", - "# Single neuron paramters\n", - "# Bias_mant is set to make the neuron spike\n", + "# Single neuron paramters. Bias_mant is set to make the neuron spike.\n", "params_exc = {\n", " \"shape_exc\": num_neurons_exc,\n", " \"dr_exc\": 0.01,\n", @@ -351,13 +351,13 @@ " \"dr_inh\": 0.01,\n", " \"bias_inh\": 0.1}\n", "\n", - "# Inhibition-exciation balance for scaling inhibitory weights to maintain balance (4 times as many excitatory neurons)\n", + "# Inhibition-exciation balance for scaling inhibitory weights to maintain balance (4 times as many excitatory neurons).\n", "g_factor = 4.5\n", "\n", - "# Factor controlling the\n", + "# Factor controlling the response properties.\n", "q_factor = 1\n", "\n", - "# Parameters Paramters for E/I network\n", + "# Parameters Paramters for E/I network.\n", "network_params_balanced = {}\n", "\n", "network_params_balanced.update(params_exc)\n", @@ -384,22 +384,22 @@ "source": [ "from lava.magma.core.run_conditions import RunSteps\n", "from lava.magma.core.run_configs import Loihi1SimCfg\n", - "# Import io processes\n", + "# Import io processes.\n", "from lava.proc.io import sink, source\n", "from lava.proc.monitor.process import Monitor\n", "\n", - "# Configurations for execution\n", + "# Configurations for execution.\n", "num_steps = 750\n", "rcfg = Loihi1SimCfg(select_tag='rate_neurons')\n", "run_cond = RunSteps(num_steps=num_steps)\n", "\n", - "# Instantiating network and IO processes\n", + "# Instantiating network and IO processes.\n", "network_balanced = EINetwork(**network_params_balanced)\n", "state_monitor = Monitor()\n", "\n", "state_monitor.probe(target=network_balanced.state, num_steps=num_steps)\n", "\n", - "# Run the network\n", + "# Run the network.\n", "network_balanced.run(run_cfg=rcfg, condition=run_cond)\n", "states_balanced = state_monitor.get_data()[network_balanced.name][network_balanced.state.name]\n", "network_balanced.stop()" @@ -410,7 +410,7 @@ "id": "7febf4a0", "metadata": {}, "source": [ - "#### Visualizing the acitvity\n", + "#### Visualizing the activity\n", "We first have a look at the trajectories of the neurons in the network." ] }, @@ -477,7 +477,7 @@ "outputs": [], "source": [ "def auto_cov_fct(acts, max_lag=100, offset=200):\n", - " \"\"\"Auto-correlation function of parallel spike trains\n", + " \"\"\"Auto-correlation function of parallel spike trains.\n", " \n", " Parameters\n", " ----------\n", @@ -494,10 +494,10 @@ " auto_corr_fct : np.ndarray\n", " auto-correlation function\n", " \"\"\"\n", - " acts = acts[offset:] # disregard time steps at beginning -> network not setted yet\n", + " acts = acts[offset:] # Disregard time steps at beginning due to network not being settled yet.\n", " assert max_lag < acts.shape[0], 'Maximal lag must be smaller then total number of time points'\n", " num_neurons = acts.shape[1]\n", - " acts -= np.mean(acts, axis=0) # temporal averaging\n", + " acts -= np.mean(acts, axis=0) # Perform temporal averaging.\n", " auto_corr_fct = np.zeros(2 * max_lag + 1)\n", " lags = np.linspace(-1 * max_lag, max_lag, 2 * max_lag + 1, dtype=int)\n", " \n", @@ -534,7 +534,7 @@ "source": [ "lags, ac_fct_balanced = auto_cov_fct(acts=states_balanced)\n", "\n", - "# Plotting the auto-correlation function\n", + "# Plotting the auto-correlation function.\n", "plt.figure(figsize=(7,5))\n", "plt.xlabel('Lag')\n", "plt.ylabel('Covariance')\n", @@ -572,27 +572,27 @@ "metadata": {}, "outputs": [], "source": [ - "# Defining new, larger q_factor\n", + "# Defining new, larger q_factor.\n", "q_factor = np.sqrt(dim) / 3\n", "\n", - "# Changing the strenghts of the recurrent connections\n", + "# Changing the strenghts of the recurrent connections.\n", "network_params_critical = network_params_balanced.copy()\n", "network_params_critical['q_factor'] = q_factor\n", "network_params_critical['weights'] = EINetwork.generate_gaussian_weights(q_factor, g_factor, num_neurons_exc, dim)\n", "\n", "\n", - "# Configurations for execution\n", + "# Configurations for execution.\n", "num_steps = 750\n", "rcfg = Loihi1SimCfg(select_tag='rate_neurons')\n", "run_cond = RunSteps(num_steps=num_steps)\n", "\n", - "# Instantiating network and IO processes\n", + "# Instantiating network and IO processes.\n", "network_critical = EINetwork(**network_params_critical)\n", "state_monitor = Monitor()\n", "\n", "state_monitor.probe(target=network_critical.state, num_steps=num_steps)\n", "\n", - "# Run the network\n", + "# Run the network.\n", "network_critical.run(run_cfg=rcfg, condition=run_cond)\n", "states_critical = state_monitor.get_data()[network_critical.name][network_critical.state.name]\n", "network_critical.stop()" @@ -656,7 +656,7 @@ "source": [ "lags, ac_fct_critical = auto_cov_fct(acts=states_critical)\n", "\n", - "# Plotting the auto-correlation function\n", + "# Plotting the auto-correlation function.\n", "plt.figure(figsize=(7,5))\n", "plt.xlabel('Lag')\n", "plt.ylabel('Correlation')\n", @@ -719,7 +719,7 @@ " else:\n", " continue\n", " \n", - " # Fetch values for excitatory neurons or set default\n", + " # Fetch values for excitatory neurons or set default.\n", " shape_exc = proc.proc_params.get('shape_exc')\n", " shape_inh = proc.proc_params.get('shape_inh')\n", " du_exc = proc.proc_params.get('du_exc')\n", @@ -729,14 +729,14 @@ " bias_exp_exc = proc.proc_params.get('bias_exp_exc', 0)\n", " \n", " \n", - " # Fetch values for inhibitory neurons or set default\n", + " # Fetch values for inhibitory neurons or set default.\n", " du_inh = proc.proc_params.get('du_inh')\n", " dv_inh = proc.proc_params.get('dv_inh')\n", " vth_inh = proc.proc_params.get('vth_inh')\n", " bias_mant_inh = proc.proc_params.get('bias_mant_inh')\n", " bias_exp_inh = proc.proc_params.get('bias_exp_inh', 0)\n", " \n", - " # Create parameters for full network\n", + " # Create parameters for full network.\n", " du_full = np.array([du_exc] * shape_exc\n", " + [du_inh] * shape_inh)\n", " dv_full = np.array([dv_exc] * shape_exc\n", @@ -752,7 +752,7 @@ " \n", " full_shape = shape_exc + shape_inh\n", "\n", - " # Instantiate LIF and Dense Lava Processes\n", + " # Instantiate LIF and Dense Lava Processes.\n", " self.lif = LIF(shape=(full_shape,),\n", " du=du_full,\n", " dv=dv_full,\n", @@ -764,21 +764,21 @@ " weight_exp=weight_exp)\n", " \n", " \n", - " # Recurrently connect neurons to E/I Network\n", + " # Recurrently connect neurons to E/I Network.\n", " self.lif.s_out.connect(self.dense.s_in)\n", " self.dense.a_out.connect(self.lif.a_in)\n", "\n", - " # Connect incoming activation to neurons and elicited spikes to ouport\n", + " # Connect incoming activation to neurons and elicited spikes to ouport.\n", " proc.inport.connect(self.lif.a_in)\n", " self.lif.s_out.connect(proc.outport)\n", " \n", - " # Alias v with state and u with state_alt\n", + " # Alias v with state and u with state_alt.\n", " proc.vars.state.alias(self.lif.vars.v)\n", " proc.vars.state_alt.alias(self.lif.vars.u)\n", " \n", " def convert_rate_to_lif_params(**kwargs):\n", " '''Convert rate parameters to LIF parameters.\n", - " The mapping is based on A unified view on weakly correlated recurrent network, Grytskyy et al. 2013\n", + " The mapping is based on A unified view on weakly correlated recurrent network, Grytskyy et al. 2013.\n", " \n", " Parameters\n", " ----------\n", @@ -811,20 +811,20 @@ "source": [ "from lava.magma.core.run_conditions import RunSteps\n", "from lava.magma.core.run_configs import Loihi1SimCfg\n", - "# Import io processes\n", + "# Import io processes.\n", "from lava.proc import io\n", "\n", "from lava.proc.dense.models import PyDenseModelFloat\n", "from lava.proc.lif.models import PyLifModelFloat\n", "\n", "\n", - "# Configurations for execution\n", + "# Configurations for execution.\n", "num_steps = 750\n", "run_cond = RunSteps(num_steps=num_steps)\n", "\n", "class CustomRunConfigFloat(Loihi1SimCfg):\n", " def select(self, proc, proc_models):\n", - " # customize run config to always use float model for io.sink.RingBuffer\n", + " # Customize run config to always use float model for io.sink.RingBuffer.\n", " if isinstance(proc, io.sink.RingBuffer):\n", " return io.sink.PyReceiveModelFloat\n", " if isinstance(proc, LIF):\n", @@ -836,13 +836,11 @@ " \n", "rcfg = CustomRunConfigFloat(select_tag='lif_neurons', select_sub_proc_model=True)\n", "\n", - "# Convert the rates\n", "# Instantiating network and IO processes\n", - "# network_params_balanced['convert'] = True\n", "lif_network_balanced = EINetwork( **network_params_balanced, convert=True)\n", "outport_plug = io.sink.RingBuffer(shape=shape, buffer=num_steps)\n", "\n", - "# Instantiate Monitors to record the voltage and the current of the LIF neurons\n", + "# Instantiate Monitors to record the voltage and the current of the LIF neurons.\n", "monitor_v = Monitor()\n", "monitor_u = Monitor()\n", "\n", @@ -852,7 +850,7 @@ "\n", "lif_network_balanced.run(condition=run_cond, run_cfg=rcfg)\n", "\n", - "# Fetching spiking activity\n", + "# Fetching spiking activity.\n", "spks_balanced = outport_plug.data.get()\n", "data_v_balanced = monitor_v.get_data()[lif_network_balanced.name][lif_network_balanced.state.name]\n", "data_u_balanced = monitor_u.get_data()[lif_network_balanced.name][lif_network_balanced.state_alt.name]\n", @@ -878,7 +876,7 @@ "outputs": [], "source": [ "def raster_plot(spks, stride=6, fig=None, color='b', alpha=1):\n", - " \"\"\"Generate raster plot of spiking activity\n", + " \"\"\"Generate raster plot of spiking activity.\n", " \n", " Parameters\n", " ----------\n", @@ -958,7 +956,7 @@ "metadata": {}, "outputs": [], "source": [ - "window = np.ones(25) # window size of 25 time steps\n", + "window = np.ones(25) # Window size of 25 time steps for binning.\n", "binned_sps_balanced = np.asarray([np.convolve(spks_balanced[i], window) for i in range(dim)])" ] }, @@ -971,7 +969,7 @@ { "data": { "text/plain": [ - "[]" + "[]" ] }, "execution_count": 19, @@ -994,7 +992,7 @@ "source": [ "lags, ac_fct = auto_cov_fct(acts=binned_sps_balanced.T)\n", "\n", - "# Plotting the auto-correlation function\n", + "# Plotting the auto-correlation function.\n", "plt.figure(figsize=(7,5))\n", "plt.xlabel('Lag')\n", "plt.ylabel('Covariance')\n", @@ -1032,11 +1030,11 @@ "rcfg = CustomRunConfigFloat(select_tag='lif_neurons', select_sub_proc_model=True)\n", "run_cond = RunSteps(num_steps=num_steps)\n", "\n", - "# Creating new new network with changed weights\n", + "# Creating new new network with changed weights.\n", "lif_network_critical = EINetwork(**network_params_critical, convert=True)\n", "outport_plug = io.sink.RingBuffer(shape=shape, buffer=num_steps)\n", "\n", - "# Instantiate Monitors to record the voltage and the current of the LIF neurons\n", + "# Instantiate Monitors to record the voltage and the current of the LIF neurons.\n", "monitor_v = Monitor()\n", "monitor_u = Monitor()\n", "\n", @@ -1046,7 +1044,7 @@ "\n", "lif_network_critical.run(condition=run_cond, run_cfg=rcfg)\n", "\n", - "# Fetching spiking activity\n", + "# Fetching spiking activity.\n", "spks_critical = outport_plug.data.get()\n", "data_v_critical = monitor_v.get_data()[lif_network_critical.name][lif_network_critical.state.name]\n", "data_u_critical = monitor_u.get_data()[lif_network_critical.name][lif_network_critical.state_alt.name]\n", @@ -1160,7 +1158,7 @@ "outputs": [], "source": [ "def calculate_activation(weights, spks, num_exc_neurons):\n", - " \"\"\"Calculate excitatory, inhibitory and total activation to neurons\n", + " \"\"\"Calculate excitatory, inhibitory and total activation to neurons.\n", " \n", " Parameters\n", " ----------\n", @@ -1465,8 +1463,8 @@ " \n", " return scaling_funct\n", "\n", - "def float2fixed_lif_parameter(params):\n", - " '''Float- to fixed-point mapping for LIF parameters\n", + "def float2fixed_lif_parameter(lif_params):\n", + " '''Float- to fixed-point mapping for LIF parameters.\n", " \n", " Parameters\n", " ---------\n", @@ -1645,18 +1643,18 @@ "metadata": {}, "outputs": [], "source": [ - "# Import bit accurate ProcessModels\n", + "# Import bit accurate ProcessModels.\n", "from lava.proc.dense.models import PyDenseModelBitAcc\n", "from lava.proc.lif.models import PyLifModelBitAcc\n", "\n", - "# Configurations for execution\n", + "# Configurations for execution.\n", "num_steps = 750\n", "run_cond = RunSteps(num_steps=num_steps)\n", "\n", - "# Define custom Run Config for execution of bit accurate models\n", + "# Define custom Run Config for execution of bit accurate models.\n", "class CustomRunConfigFixed(Loihi1SimCfg):\n", " def select(self, proc, proc_models):\n", - " # customize run config to always use float model for io.sink.RingBuffer\n", + " # Customize run config to always use float model for io.sink.RingBuffer.\n", " if isinstance(proc, io.sink.RingBuffer):\n", " return io.sink.PyReceiveModelFloat\n", " if isinstance(proc, LIF):\n", @@ -1737,7 +1735,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 36, @@ -1760,7 +1758,7 @@ "source": [ "lags, ac_fct = auto_cov_fct(acts=binned_sps_balanced.T)\n", "\n", - "# Plotting the auto-correlation function\n", + "# Plotting the auto-correlation function.\n", "plt.figure(figsize=(7,5))\n", "plt.xlabel('Lag')\n", "plt.ylabel('Covariance')\n",