-
Notifications
You must be signed in to change notification settings - Fork 2
/
tutorial_2.py
142 lines (116 loc) · 5.17 KB
/
tutorial_2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import numpy as np
from os import path
from pygenn.genn_model import (create_custom_neuron_class,
create_custom_current_source_class,
GeNNModel)
from pygenn.genn_wrapper import NO_DELAY
# ----------------------------------------------------------------------------
# Parameters
# ----------------------------------------------------------------------------
IF_PARAMS = {"Vthr": 5.0}
TIMESTEP = 1.0
PRESENT_TIMESTEPS = 100
INPUT_CURRENT_SCALE = 1.0 / 100.0
# ----------------------------------------------------------------------------
# Custom GeNN models
# ----------------------------------------------------------------------------
# Very simple integrate-and-fire neuron model
if_model = create_custom_neuron_class(
"if_model",
param_names=["Vthr"],
var_name_types=[("V", "scalar"), ("SpikeCount", "unsigned int")],
sim_code="$(V) += $(Isyn) * DT;",
reset_code="""
$(V) = 0.0;
$(SpikeCount)++;
""",
threshold_condition_code="$(V) >= $(Vthr)")
# Current source model which injects current with a magnitude specified by a state variable
cs_model = create_custom_current_source_class(
"cs_model",
var_name_types=[("magnitude", "scalar")],
injection_code="$(injectCurrent, $(magnitude));")
# ----------------------------------------------------------------------------
# Build model
# ----------------------------------------------------------------------------
# Create GeNN model
model = GeNNModel("float", "tutorial_2")
model.dT = TIMESTEP
# Load weights
weights = []
while True:
filename = "weights_%u_%u.npy" % (len(weights), len(weights) + 1)
if path.exists(filename):
weights.append(np.load(filename))
else:
break
# Initial values to initialise all neurons to
if_init = {"V": 0.0, "SpikeCount":0}
# Create first neuron layer
neuron_layers = [model.add_neuron_population("neuron0", weights[0].shape[0],
if_model, IF_PARAMS, if_init)]
# Create subsequent neuron layer
for i, w in enumerate(weights):
neuron_layers.append(model.add_neuron_population("neuron%u" % (i + 1),
w.shape[1], if_model,
IF_PARAMS, if_init))
# Create synaptic connections between layers
for i, (pre, post, w) in enumerate(zip(neuron_layers[:-1], neuron_layers[1:], weights)):
model.add_synapse_population(
"synapse%u" % i, "DENSE_INDIVIDUALG", NO_DELAY,
pre, post,
"StaticPulse", {}, {"g": w.flatten()}, {}, {},
"DeltaCurr", {}, {})
# Create current source to deliver input to first layers of neurons
current_input = model.add_current_source("current_input", cs_model,
"neuron0" , {}, {"magnitude": 0.0})
# Build and load our model
model.build()
model.load()
# ----------------------------------------------------------------------------
# Simulate
# ----------------------------------------------------------------------------
# Load testing data
testing_images = np.load("testing_images.npy")
testing_labels = np.load("testing_labels.npy")
# Check dimensions match network
assert testing_images.shape[1] == weights[0].shape[0]
assert np.max(testing_labels) == (weights[1].shape[1] - 1)
# Get views to efficiently access state variables
current_input_magnitude = current_input.vars["magnitude"].view
output_spike_count = neuron_layers[-1].vars["SpikeCount"].view
layer_voltages = [l.vars["V"].view for l in neuron_layers]
# Simulate
num_correct = 0
while model.timestep < (PRESENT_TIMESTEPS * testing_images.shape[0]):
# Calculate the timestep within the presentation
timestep_in_example = model.timestep % PRESENT_TIMESTEPS
example = int(model.timestep // PRESENT_TIMESTEPS)
# If this is the first timestep of presenting the example
if timestep_in_example == 0:
current_input_magnitude[:] = testing_images[example] * INPUT_CURRENT_SCALE
current_input.push_var_to_device("magnitude")
# Loop through all layers and their corresponding voltage views
for l, v in zip(neuron_layers, layer_voltages):
# Manually 'reset' voltage
v[:] = 0.0
# Upload
l.push_var_to_device("V")
# Zero spike count
output_spike_count[:] = 0
neuron_layers[-1].push_var_to_device("SpikeCount")
# Advance simulation
model.step_time()
# If this is the LAST timestep of presenting the example
if timestep_in_example == (PRESENT_TIMESTEPS - 1):
# Download spike count from last layer
neuron_layers[-1].pull_var_from_device("SpikeCount")
# Find which neuron spiked the most to get prediction
predicted_label = np.argmax(output_spike_count)
true_label = testing_labels[example]
print("\tExample=%u, true label=%u, predicted label=%u" % (example,
true_label,
predicted_label))
if predicted_label == true_label:
num_correct += 1
print("Accuracy %f%%" % ((num_correct / float(testing_images.shape[0])) * 100.0))