Getting start#
ARCANA is a library built on PyTorch to provide a simulation model of the DYNAP-SE hardware
Dynap-SE model Equation Image
Quickstart#
The following code demonstrate how to define a simple neural network in ARCANA. In this example a single neuron is created with and trained the leakage and gain current to have an specific output firing rate.
1import matplotlib.pyplot as plt
2import numpy as np
3import seaborn as sns
4import torch
5from tqdm import tqdm
6
7from arcana.model import DPINeuron
8
9neuron = DPINeuron(
10 1,
11 1,
12 Itau_mem=4e-12,
13 Igain_mem=20e-12,
14 Ith=0.012,
15 Idc=50e-12,
16 refP=0.0,
17 Ipfb_th=20e-12,
18 Ipfb_norm=2e9,
19 dt=1e-3,
20 train_Igain_mem=True,
21 train_Itau_mem=True,
22)
Next, we define the training and test function. The training function will receive the neuron, optimizer and the number of epochs to train. To calculate the loss, the mean squared error of the number of output spikes will be used.
1def train(neuron, optimizer, epochs):
2 loss_hist = []
3 Itau_hist = []
4 Igain_hist = []
5 Vmem_hist = []
6 neuron.train()
7 pbar = tqdm(range(epochs))
8 for _ in pbar:
9 outAcum = 0.0
10 state = None
11 totalVmem = []
12 for t in range(2000):
13 out, state = neuron(torch.zeros(1, 1), state)
14 (Imem, _, _, _, _, _) = state
15 outAcum += out
16
17 totalVmem.append(neuron.I2V(Imem).detach().numpy().item())
18 totalVmem = np.stack(totalVmem)
19
20 loss = (outAcum.sum() - torch.tensor(5.0)) ** 2
21 optimizer.zero_grad()
22 loss.backward()
23 optimizer.step()
24 loss_hist.append(loss.item())
25 with torch.no_grad():
26 Vmem_hist.append(totalVmem)
27 Itau_hist.append(neuron.Itau_mem.numpy().item())
28 Igain_hist.append(neuron.Igain_mem.numpy().item())
29 pbar.set_postfix({"Loss": loss.item()})
30 return loss_hist, Vmem_hist, Itau_hist, Igain_hist
1@torch.no_grad()
2def test(neuron):
3 state = None
4 totalImem = []
5 totalVmem = []
6 neuron.eval()
7 for t in tqdm(range(2000)):
8 out, state = neuron(torch.zeros(1, 1), state)
9 (Imem, Iampa, _, _, _, _) = state
10 totalImem.append(Imem.numpy().item())
11 totalVmem.append(neuron.I2V(Imem).numpy().item())
12 return totalImem, totalVmem
Next, we create the optimizer to train the network. In this case is the Adam optimizer with a learning rate of 5e-3.
1optimizer = torch.optim.Adam(neuron.parameters(), lr=5e-3)
2optimizer.register_step_post_hook(neuron.UpdateParams)
3print(optimizer)
Finally we train the network for 20 epochs, and we see difference of the model behaviour before and after training.
1epochs = 20
2Imem_pre, Vmem_pre = test(neuron)
3(loss, _, Itau, Igain) = train(neuron, optimizer, epochs)
4Imem_post, Vmem_post = test(neuron)