Mismatch#

On this experiment we are going calculate the FF curve for different neurons with a mismatch of 10% on the different biases. First, we are going to import the necesary libraries and set the simulation timestep.

import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from tqdm import trange

from arcana.model import DPINeuron

# timestep = 20 * 1e-6
timestep = 1e-3

Input generation#

We are going to create a total of 16 neurons with an input spike frequency in the range [0, 500]Hz in steps of 30Hz

freq = np.arange(0, 200, 1)
# Parameters
pulse_start = 0  # second - Start time of input (Default: 0)
pulse_stop = 1  # second - Stop time of input (Default: 5)
inp_duration = 1.0  # second - Simulation duration (Default: 5)
##################

spikes = torch.zeros(len(freq), int(inp_duration / timestep))

for i, rate in enumerate(freq[1:]):
    dt = int((1 / timestep) / rate)
    spikes[
        i + 1, pulse_start * int(1 / timestep) : pulse_stop * int(1 / timestep) : dt
    ] = 1.0

spikes = spikes.transpose(0, 1)
input = spikes.unsqueeze(0).cuda()
t, b = np.where(spikes)
plt.figure(figsize=(16, 12))
plt.scatter(t * timestep, freq[b], marker=".", alpha=0.5)
# plt.yscale(u'log')
plt.ylabel("Frequency (Hz)")
plt.xlabel("Time (s)")
Text(0.5, 0, 'Time (s)')
../_images/2c1aabb9a9ba739584b93b7d2739c2b5303797594350194427fe0aed78371b43.png

Model creating and simulation#

Once we created the input, we instantiate a layer of 16 AdexLIF neurons with an AMPA synapse connected to each input. The simulation is processed in batches, where each batch correspond to a determinated frequency. To add mismatch to the DPI neuron in ARCANA, the model has the function python neuron.add_mismatch(BIAS_NAME, VARIABILITY) where we indicate the variability percentage of the bias we want to apply it to.

network = DPINeuron(
    len(freq),
    len(freq),
    Itau_mem=4e-12,
    Igain_mem=80e-12,
    Ith=0.012,
    Idc=10e-12,
    refP=0.0,
    Ipfb_th=0e-12,
    Ipfb_norm=1.4e9,
    Itau_ampa=2e-12,
    Igain_ampa=20e-12,
    Iw_ampa=200e-12,
    dt=timestep,
    train_Igain_mem=True,
    train_Itau_mem=True,
).cuda()
network.add_mismatch("Iw_ampa", 0.1)
network.add_mismatch("Itau_ampa", 0.1)
network.add_mismatch("Igain_ampa", 0.1)
network.add_mismatch("Itau_mem", 0.1)
network.add_mismatch("Igain_mem", 0.1)
network.dt = timestep
output = []

with torch.no_grad():
    network.W_ampa.data = torch.eye(len(freq), device="cuda") * 0.7
    network.W_gabab.data = torch.zeros_like(network.W_gabab)
    state = None
    V_record = []
    for t in trange(input.shape[1]):
        out, state = network(input[:, t], state)
        (Imem, Iampa, _, _) = state
        V_record.append(Imem)
        output.append(out)
    output_mean = torch.stack(output, dim=1).detach().cpu()
    V_record = torch.stack(V_record, dim=1).detach().cpu()
100%|██████████| 1000/1000 [00:01<00:00, 984.58it/s]
plt.plot(DPINeuron.I2V(V_record[0, :, 20]))
# plt.plot(V_record[0])
plt.show()
../_images/0105817fdfe36589fd752c5b33c5985b6ab984a52335a62a2e693410e6a9211e.png
plt.plot(freq, output_mean.sum(dim=(0, 1)) / inp_duration, "-.")
plt.xlabel("Input fr [Hz]")
plt.ylabel("Output fr [Hz]")
plt.title("FF curves")
plt.grid()
plt.show()
../_images/1ce5910098924a4643c6c9642de947e89fa12d577af1856059b1bbf9dd3e2aff.png