def test_post_pre(self): # Connection test network = Network(dt=1.0) network.add_layer(Input(n=100, traces=True), name='input') network.add_layer(LIFNodes(n=100, traces=True), name='output') network.add_connection(Connection(source=network.layers['input'], target=network.layers['output'], nu=1e-2, update_rule=PostPre), source='input', target='output') network.run( inpts={'input': torch.bernoulli(torch.rand(250, 100)).byte()}, time=250) # Conv2dConnection test network = Network(dt=1.0) network.add_layer(Input(shape=[1, 1, 10, 10], traces=True), name='input') network.add_layer(LIFNodes(shape=[1, 32, 8, 8], traces=True), name='output') network.add_connection(Conv2dConnection( source=network.layers['input'], target=network.layers['output'], kernel_size=3, stride=1, nu=1e-2, update_rule=PostPre), source='input', target='output') network.run(inpts={ 'input': torch.bernoulli(torch.rand(250, 1, 1, 10, 10)).byte() }, time=250)
def test_weight_dependent_post_pre(self): # Connection test network = Network(dt=1.0) network.add_layer(Input(n=100, traces=True), name="input") network.add_layer(LIFNodes(n=100, traces=True), name="output") network.add_connection( Connection( source=network.layers["input"], target=network.layers["output"], nu=1e-2, update_rule=WeightDependentPostPre, wmin=-1, wmax=1, ), source="input", target="output", ) network.run( inputs={"input": torch.bernoulli(torch.rand(250, 100)).byte()}, time=250, ) # Conv2dConnection test network = Network(dt=1.0) network.add_layer(Input(shape=[1, 10, 10], traces=True), name="input") network.add_layer( LIFNodes(shape=[32, 8, 8], traces=True), name="output" ) network.add_connection( Conv2dConnection( source=network.layers["input"], target=network.layers["output"], kernel_size=3, stride=1, nu=1e-2, update_rule=WeightDependentPostPre, wmin=-1, wmax=1, ), source="input", target="output", ) network.run( inputs={ "input": torch.bernoulli(torch.rand(250, 1, 1, 10, 10)).byte() }, time=250, )
def test_add_objects(self): network = Network(dt=1.0, learning=False) inpt = Input(100) network.add_layer(inpt, name="X") lif = LIFNodes(50) network.add_layer(lif, name="Y") assert inpt == network.layers["X"] assert lif == network.layers["Y"] conn = Connection(inpt, lif) network.add_connection(conn, source="X", target="Y") assert conn == network.connections[("X", "Y")] monitor = Monitor(lif, state_vars=["s", "v"]) network.add_monitor(monitor, "Y") assert monitor == network.monitors["Y"] network.save("net.pt") _network = load("net.pt", learning=True) assert _network.learning assert "X" in _network.layers assert "Y" in _network.layers assert ("X", "Y") in _network.connections assert "Y" in _network.monitors del _network os.remove("net.pt")
def create_hmax(network): for size in FILTER_SIZES: s1 = Input(shape=(FILTER_TYPES, IMAGE_SIZE, IMAGE_SIZE), traces=True) network.add_layer(layer=s1, name=get_s1_name(size)) # network.add_monitor(Monitor(s1, ["s"]), get_s1_name(size)) c1 = LIFNodes(shape=(FILTER_TYPES, IMAGE_SIZE // 2, IMAGE_SIZE // 2), thresh=-64, traces=True) network.add_layer(layer=c1, name=get_c1_name(size)) # network.add_monitor(Monitor(c1, ["s", "v"]), get_c1_name(size)) max_pool = MaxPool2dConnection(s1, c1, kernel_size=2, stride=2, decay=0.2) network.add_connection(max_pool, get_s1_name(size), get_c1_name(size)) for feature in FEATURES: for size in FILTER_SIZES: s2 = LIFNodes(shape=(1, IMAGE_SIZE // 2, IMAGE_SIZE // 2), thresh=-64, traces=True) network.add_layer(layer=s2, name=get_s2_name(size, feature)) # network.add_monitor(Monitor(s2, ["s", "v"]), get_s2_name(size, feature)) conv = Conv2dConnection(network.layers[get_c1_name(size)], s2, 15, padding=7, update_rule=PostPre, wmin=0, wmax=1) network.add_monitor( Monitor(conv, ["w"]), "conv%d%d" % (feature, size) ) network.add_connection(conv, get_c1_name(size), get_s2_name(size, feature)) c2 = LIFNodes(shape=(1, 1, 1), thresh=-64, traces=True) network.add_layer(layer=c2, name=get_c2_name(size, feature)) # network.add_monitor(Monitor(c2, ["s", "v"]), get_c2_name(size, feature)) max_pool = MaxPool2dConnection(s2, c2, kernel_size=IMAGE_SIZE // 2, decay=0.0) network.add_connection(max_pool, get_s2_name(size, feature), get_c2_name(size, feature))
def test_add_objects(self): network = Network(dt=1.0, learning=False) inpt = Input(100) network.add_layer(inpt, name='X') lif = LIFNodes(50) network.add_layer(lif, name='Y') assert inpt == network.layers['X'] assert lif == network.layers['Y'] conn = Connection(inpt, lif) network.add_connection(conn, source='X', target='Y') assert conn == network.connections[('X', 'Y')] monitor = Monitor(lif, state_vars=['s', 'v']) network.add_monitor(monitor, 'Y') assert monitor == network.monitors['Y'] network.save('net.pt') _network = load('net.pt', learning=True) assert _network.learning assert 'X' in _network.layers assert 'Y' in _network.layers assert ('X', 'Y') in _network.connections assert 'Y' in _network.monitors del _network os.remove('net.pt')
def create_bindsnet(input_width, input_height, action_num=3): from bindsnet.network import Network from bindsnet.learning import MSTDP from bindsnet.network.nodes import Input, LIFNodes from bindsnet.network.topology import Connection network = Network(dt=1.0) # Layers of neurons. inpt = Input(n=input_height * input_width, shape=[input_height, input_width], traces=True) middle = LIFNodes(n=100, traces=True) out = LIFNodes(n=action_num, refrac=0, traces=True) # Connections between layers. inpt_middle = Connection(source=inpt, target=middle, wmin=0, wmax=1e-1) middle_out = Connection(source=middle, target=out, wmin=0, wmax=1, update_rule=MSTDP, nu=1e-1, norm=0.5 * middle.n) # Add all layers and connections to the network. network.add_layer(inpt, name='Input Layer') network.add_layer(middle, name='Hidden Layer') network.add_layer(out, name='Output Layer') network.add_connection(inpt_middle, source='Input Layer', target='Hidden Layer') network.add_connection(middle_out, source='Hidden Layer', target='Output Layer') return network
def lif_feed_forward_benchmark(parameters: BenchmarkParameters): T = parameters.dt * parameters.sequence_length network = Network(batch_size=parameters.batch_size, dt=parameters.dt) network.add_layer(Input(n=parameters.features), name="Input") network.add_layer(LIFNodes(n=parameters.features), name="Neurons") network.add_connection( Connection(source=network.layers["Input"], target=network.layers["Neurons"]), source="Input", target="Neurons", ) input_spikes = ( PoissonEncoder(time=T, dt=parameters.dt)( 0.3 * torch.ones(parameters.batch_size, parameters.features) ) .to(parameters.device) .float() ) input_spikes.requires_grad = False input_data = {"Input": input_spikes} network.to(parameters.device) for param in network.parameters(): param.requires_grad = False start = time.time() network.run(inputs=input_data, time=T) end = time.time() duration = end - start return duration
def test_mstdpet(self): # Connection test network = Network(dt=1.0) network.add_layer(Input(n=100), name="input") network.add_layer(LIFNodes(n=100), name="output") network.add_connection( Connection( source=network.layers["input"], target=network.layers["output"], nu=1e-2, update_rule=MSTDPET, ), source="input", target="output", ) network.run( inputs={"input": torch.bernoulli(torch.rand(250, 100)).byte()}, time=250, reward=1.0, ) # Conv2dConnection test network = Network(dt=1.0) network.add_layer(Input(shape=[1, 10, 10]), name="input") network.add_layer(LIFNodes(shape=[32, 8, 8]), name="output") network.add_connection( Conv2dConnection( source=network.layers["input"], target=network.layers["output"], kernel_size=3, stride=1, nu=1e-2, update_rule=MSTDPET, ), source="input", target="output", ) network.run( inputs={ "input": torch.bernoulli(torch.rand(250, 1, 1, 10, 10)).byte() }, time=250, reward=1.0, )
def test_hebbian(self): # Connection test network = Network(dt=1.0) network.add_layer(Input(n=100, traces=True), name="input") network.add_layer(LIFNodes(n=100, traces=True), name="output") network.add_connection( Connection( source=network.layers["input"], target=network.layers["output"], nu=1e-2, update_rule=Hebbian, ), source="input", target="output", ) network.run( inputs={"input": torch.bernoulli(torch.rand(250, 100)).byte()}, time=250, ) # Conv2dConnection test network = Network(dt=1.0) network.add_layer(Input(shape=[1, 10, 10], traces=True), name="input") network.add_layer( LIFNodes(shape=[32, 8, 8], traces=True), name="output" ) network.add_connection( Conv2dConnection( source=network.layers["input"], target=network.layers["output"], kernel_size=3, stride=1, nu=1e-2, update_rule=Hebbian, ), source="input", target="output", ) # shape is [time, batch, channels, height, width] network.run( inputs={ "input": torch.bernoulli(torch.rand(250, 1, 1, 10, 10)).byte() }, time=250, )
def test_add_objects(self): network = Network(dt=1.0) inpt = Input(100); network.add_layer(inpt, name='X') lif = LIFNodes(50); network.add_layer(lif, name='Y') assert inpt == network.layers['X'] assert lif == network.layers['Y'] conn = Connection(inpt, lif); network.add_connection(conn, source='X', target='Y') assert conn == network.connections[('X', 'Y')] monitor = Monitor(lif, state_vars=['s', 'v']); network.add_monitor(monitor, 'Y') assert monitor == network.monitors['Y']
def test_rmax(self): # Connection test network = Network(dt=1.0) network.add_layer(Input(n=100, traces=True, traces_additive=True), name='input') network.add_layer(SRM0Nodes(n=100), name='output') network.add_connection(Connection(source=network.layers['input'], target=network.layers['output'], nu=1e-2, update_rule=Rmax), source='input', target='output') network.run( inpts={'input': torch.bernoulli(torch.rand(250, 100)).byte()}, time=250, reward=1.)
def BindsNET_cpu(n_neurons, time): t0 = t() torch.set_default_tensor_type('torch.FloatTensor') t1 = t() network = Network() network.add_layer(Input(n=n_neurons), name='X') network.add_layer(LIFNodes(n=n_neurons), name='Y') network.add_connection(Connection(source=network.layers['X'], target=network.layers['Y']), source='X', target='Y') data = {'X': poisson(datum=torch.rand(n_neurons), time=time)} network.run(inpts=data, time=time) return t() - t0, t() - t1
def BindsNET_cpu(n_neurons, time): t0 = t() torch.set_default_tensor_type("torch.FloatTensor") t1 = t() network = Network() network.add_layer(Input(n=n_neurons), name="X") network.add_layer(LIFNodes(n=n_neurons), name="Y") network.add_connection( Connection(source=network.layers["X"], target=network.layers["Y"]), source="X", target="Y", ) data = {"X": poisson(datum=torch.rand(n_neurons), time=time)} network.run(inputs=data, time=time) return t() - t0, t() - t1
class TestMonitor: """ Testing Monitor object. """ network = Network() inpt = Input(75) network.add_layer(inpt, name="X") _if = IFNodes(25) network.add_layer(_if, name="Y") conn = Connection(inpt, _if, w=torch.rand(inpt.n, _if.n)) network.add_connection(conn, source="X", target="Y") inpt_mon = Monitor(inpt, state_vars=["s"]) network.add_monitor(inpt_mon, name="X") _if_mon = Monitor(_if, state_vars=["s", "v"]) network.add_monitor(_if_mon, name="Y") network.run( inputs={"X": torch.bernoulli(torch.rand(100, inpt.n))}, time=100 ) assert inpt_mon.get("s").size() == torch.Size([100, 1, inpt.n]) assert _if_mon.get("s").size() == torch.Size([100, 1, _if.n]) assert _if_mon.get("v").size() == torch.Size([100, 1, _if.n]) del network.monitors["X"], network.monitors["Y"] inpt_mon = Monitor(inpt, state_vars=["s"], time=500) network.add_monitor(inpt_mon, name="X") _if_mon = Monitor(_if, state_vars=["s", "v"], time=500) network.add_monitor(_if_mon, name="Y") network.run( inputs={"X": torch.bernoulli(torch.rand(500, inpt.n))}, time=500 ) assert inpt_mon.get("s").size() == torch.Size([500, 1, inpt.n]) assert _if_mon.get("s").size() == torch.Size([500, 1, _if.n]) assert _if_mon.get("v").size() == torch.Size([500, 1, _if.n])
def __init__(self, parameters: BenchmarkParameters): super(BindsNetModule, self).__init__() network = Network(batch_size=parameters.batch_size, dt=parameters.dt) lif_nodes = LIFNodes(n=parameters.features) monitor = Monitor(obj=lif_nodes, state_vars=("s"), time=parameters.sequence_length) network.add_layer(Input(n=parameters.features), name="Input") network.add_layer(lif_nodes, name="Neurons") network.add_connection( Connection(source=network.layers["Input"], target=network.layers["Neurons"]), source="Input", target="Neurons", ) network.add_monitor(monitor, "Monitor") network.to(parameters.device) self.parameters = parameters self.network = network self.monitor = monitor
class TestMonitor: """ Testing Monitor object. """ network = Network() inpt = Input(75) network.add_layer(inpt, name='X') _if = IFNodes(25) network.add_layer(_if, name='Y') conn = Connection(inpt, _if, w=torch.rand(inpt.n, _if.n)) network.add_connection(conn, source='X', target='Y') inpt_mon = Monitor(inpt, state_vars=['s']) network.add_monitor(inpt_mon, name='X') _if_mon = Monitor(_if, state_vars=['s', 'v']) network.add_monitor(_if_mon, name='Y') network.run(inpts={'X': torch.bernoulli(torch.rand(100, inpt.n))}, time=100) assert inpt_mon.get('s').size() == torch.Size([inpt.n, 100]) assert _if_mon.get('s').size() == torch.Size([_if.n, 100]) assert _if_mon.get('v').size() == torch.Size([_if.n, 100]) del network.monitors['X'], network.monitors['Y'] inpt_mon = Monitor(inpt, state_vars=['s'], time=500) network.add_monitor(inpt_mon, name='X') _if_mon = Monitor(_if, state_vars=['s', 'v'], time=500) network.add_monitor(_if_mon, name='Y') network.run(inpts={'X': torch.bernoulli(torch.rand(500, inpt.n))}, time=500) assert inpt_mon.get('s').size() == torch.Size([inpt.n, 500]) assert _if_mon.get('s').size() == torch.Size([_if.n, 500]) assert _if_mon.get('v').size() == torch.Size([_if.n, 500])
class TestNetworkMonitor: """ Testing NetworkMonitor object. """ network = Network() inpt = Input(25) network.add_layer(inpt, name="X") _if = IFNodes(75) network.add_layer(_if, name="Y") conn = Connection(inpt, _if, w=torch.rand(inpt.n, _if.n)) network.add_connection(conn, source="X", target="Y") mon = NetworkMonitor(network, state_vars=["s", "v", "w"]) network.add_monitor(mon, name="monitor") network.run(inputs={"X": torch.bernoulli(torch.rand(50, inpt.n))}, time=50) recording = mon.get() assert recording["X"]["s"].size() == torch.Size([50, 1, inpt.n]) assert recording["Y"]["s"].size() == torch.Size([50, 1, _if.n]) assert recording["Y"]["s"].size() == torch.Size([50, 1, _if.n]) del network.monitors["monitor"] mon = NetworkMonitor(network, state_vars=["s", "v", "w"], time=50) network.add_monitor(mon, name="monitor") network.run(inputs={"X": torch.bernoulli(torch.rand(50, inpt.n))}, time=50) recording = mon.get() assert recording["X"]["s"].size() == torch.Size([50, 1, inpt.n]) assert recording["Y"]["s"].size() == torch.Size([50, 1, _if.n]) assert recording["Y"]["s"].size() == torch.Size([50, 1, _if.n])
class TestNetworkMonitor: """ Testing NetworkMonitor object. """ network = Network() inpt = Input(25) network.add_layer(inpt, name='X') _if = IFNodes(75) network.add_layer(_if, name='Y') conn = Connection(inpt, _if, w=torch.rand(inpt.n, _if.n)) network.add_connection(conn, source='X', target='Y') mon = NetworkMonitor(network, state_vars=['s', 'v', 'w']) network.add_monitor(mon, name='monitor') network.run(inpts={'X': torch.bernoulli(torch.rand(50, inpt.n))}, time=50) recording = mon.get() assert recording['X']['s'].size() == torch.Size([inpt.n, 50]) assert recording['Y']['s'].size() == torch.Size([_if.n, 50]) assert recording['Y']['s'].size() == torch.Size([_if.n, 50]) del network.monitors['monitor'] mon = NetworkMonitor(network, state_vars=['s', 'v', 'w'], time=50) network.add_monitor(mon, name='monitor') network.run(inpts={'X': torch.bernoulli(torch.rand(50, inpt.n))}, time=50) recording = mon.get() assert recording['X']['s'].size() == torch.Size([inpt.n, 50]) assert recording['Y']['s'].size() == torch.Size([_if.n, 50]) assert recording['Y']['s'].size() == torch.Size([_if.n, 50])
def main(seed=0, n_train=60000, n_test=10000, kernel_size=(16, ), stride=(4, ), n_filters=25, padding=0, inhib=100, time=25, lr=1e-3, lr_decay=0.99, dt=1, intensity=1, progress_interval=10, update_interval=250, plot=False, train=True, gpu=False): assert n_train % update_interval == 0 and n_test % update_interval == 0, \ 'No. examples must be divisible by update_interval' params = [ seed, n_train, kernel_size, stride, n_filters, padding, inhib, time, lr, lr_decay, dt, intensity, update_interval ] model_name = '_'.join([str(x) for x in params]) if not train: test_params = [ seed, n_train, n_test, kernel_size, stride, n_filters, padding, inhib, time, lr, lr_decay, dt, intensity, update_interval ] np.random.seed(seed) if gpu: torch.set_default_tensor_type('torch.cuda.FloatTensor') torch.cuda.manual_seed_all(seed) else: torch.manual_seed(seed) n_examples = n_train if train else n_test input_shape = [20, 20] if kernel_size == input_shape: conv_size = [1, 1] else: conv_size = (int((input_shape[0] - kernel_size[0]) / stride[0]) + 1, int((input_shape[1] - kernel_size[1]) / stride[1]) + 1) n_classes = 10 n_neurons = n_filters * np.prod(conv_size) total_kernel_size = int(np.prod(kernel_size)) total_conv_size = int(np.prod(conv_size)) # Build network. if train: network = Network() input_layer = Input(n=400, shape=(1, 1, 20, 20), traces=True) conv_layer = DiehlAndCookNodes(n=n_filters * total_conv_size, shape=(1, n_filters, *conv_size), thresh=-64.0, traces=True, theta_plus=0.05 * (kernel_size[0] / 20), refrac=0) conv_layer2 = LIFNodes(n=n_filters * total_conv_size, shape=(1, n_filters, *conv_size), refrac=0) conv_conn = Conv2dConnection(input_layer, conv_layer, kernel_size=kernel_size, stride=stride, update_rule=WeightDependentPostPre, norm=0.05 * total_kernel_size, nu=[0, lr], wmin=0, wmax=0.25) conv_conn2 = Conv2dConnection(input_layer, conv_layer2, w=conv_conn.w, kernel_size=kernel_size, stride=stride, update_rule=None, wmax=0.25) w = -inhib * torch.ones(n_filters, conv_size[0], conv_size[1], n_filters, conv_size[0], conv_size[1]) for f in range(n_filters): for f2 in range(n_filters): if f != f2: w[f, :, :f2, :, :] = 0 w = w.view(n_filters * conv_size[0] * conv_size[1], n_filters * conv_size[0] * conv_size[1]) recurrent_conn = Connection(conv_layer, conv_layer, w=w) network.add_layer(input_layer, name='X') network.add_layer(conv_layer, name='Y') network.add_layer(conv_layer2, name='Y_') network.add_connection(conv_conn, source='X', target='Y') network.add_connection(conv_conn2, source='X', target='Y_') network.add_connection(recurrent_conn, source='Y', target='Y') # Voltage recording for excitatory and inhibitory layers. voltage_monitor = Monitor(network.layers['Y'], ['v'], time=time) network.add_monitor(voltage_monitor, name='output_voltage') else: network = load_network(os.path.join(params_path, model_name + '.pt')) network.connections['X', 'Y'].update_rule = NoOp( connection=network.connections['X', 'Y'], nu=network.connections['X', 'Y'].nu) network.layers['Y'].theta_decay = 0 network.layers['Y'].theta_plus = 0 # Load MNIST data. dataset = MNIST(data_path, download=True) if train: images, labels = dataset.get_train() else: images, labels = dataset.get_test() images *= intensity images = images[:, 4:-4, 4:-4].contiguous() # Record spikes during the simulation. spike_record = torch.zeros(update_interval, time, n_neurons) full_spike_record = torch.zeros(n_examples, n_neurons) # Neuron assignments and spike proportions. if train: logreg_model = LogisticRegression(warm_start=True, n_jobs=-1, solver='lbfgs', max_iter=1000, multi_class='multinomial') logreg_model.coef_ = np.zeros([n_classes, n_neurons]) logreg_model.intercept_ = np.zeros(n_classes) logreg_model.classes_ = np.arange(n_classes) else: path = os.path.join(params_path, '_'.join(['auxiliary', model_name]) + '.pt') logreg_coef, logreg_intercept = torch.load(open(path, 'rb')) logreg_model = LogisticRegression(warm_start=True, n_jobs=-1, solver='lbfgs', max_iter=1000, multi_class='multinomial') logreg_model.coef_ = logreg_coef logreg_model.intercept_ = logreg_intercept logreg_model.classes_ = np.arange(n_classes) # Sequence of accuracy estimates. curves = {'logreg': []} predictions = {scheme: torch.Tensor().long() for scheme in curves.keys()} if train: best_accuracy = 0 spikes = {} for layer in set(network.layers): spikes[layer] = Monitor(network.layers[layer], state_vars=['s'], time=time) network.add_monitor(spikes[layer], name='%s_spikes' % layer) # Train the network. if train: print('\nBegin training.\n') else: print('\nBegin test.\n') inpt_ims = None inpt_axes = None spike_ims = None spike_axes = None weights_im = None plot_update_interval = 100 start = t() for i in range(n_examples): if i % progress_interval == 0: print('Progress: %d / %d (%.4f seconds)' % (i, n_examples, t() - start)) start = t() if i % update_interval == 0 and i > 0: if train: network.connections['X', 'Y'].update_rule.nu[1] *= lr_decay if i % len(labels) == 0: current_labels = labels[-update_interval:] current_record = full_spike_record[-update_interval:] else: current_labels = labels[i % len(labels) - update_interval:i % len(labels)] current_record = full_spike_record[i % len(labels) - update_interval:i % len(labels)] # Update and print accuracy evaluations. curves, preds = update_curves(curves, current_labels, n_classes, full_spike_record=current_record, logreg=logreg_model) print_results(curves) for scheme in preds: predictions[scheme] = torch.cat( [predictions[scheme], preds[scheme]], -1) # Save accuracy curves to disk. to_write = ['train'] + params if train else ['test'] + params f = '_'.join([str(x) for x in to_write]) + '.pt' torch.save((curves, update_interval, n_examples), open(os.path.join(curves_path, f), 'wb')) if train: if any([x[-1] > best_accuracy for x in curves.values()]): print( 'New best accuracy! Saving network parameters to disk.' ) # Save network to disk. network.save(os.path.join(params_path, model_name + '.pt')) path = os.path.join( params_path, '_'.join(['auxiliary', model_name]) + '.pt') torch.save((logreg_model.coef_, logreg_model.intercept_), open(path, 'wb')) best_accuracy = max([x[-1] for x in curves.values()]) # Refit logistic regression model. logreg_model = logreg_fit(full_spike_record[:i], labels[:i], logreg_model) print() # Get next input sample. image = images[i % len(images)] sample = bernoulli(datum=image, time=time, dt=dt, max_prob=1).unsqueeze(1).unsqueeze(1) inpts = {'X': sample} # Run the network on the input. network.run(inpts=inpts, time=time) network.connections['X', 'Y_'].w = network.connections['X', 'Y'].w # Add to spikes recording. spike_record[i % update_interval] = spikes['Y_'].get('s').view( time, -1) full_spike_record[i] = spikes['Y_'].get('s').view(time, -1).sum(0) # Optionally plot various simulation information. if plot and i % plot_update_interval == 0: _input = inpts['X'].view(time, 400).sum(0).view(20, 20) w = network.connections['X', 'Y'].w _spikes = { 'X': spikes['X'].get('s').view(400, time), 'Y': spikes['Y'].get('s').view(n_filters * total_conv_size, time), 'Y_': spikes['Y_'].get('s').view(n_filters * total_conv_size, time) } inpt_axes, inpt_ims = plot_input(image.view(20, 20), _input, label=labels[i % len(labels)], ims=inpt_ims, axes=inpt_axes) spike_ims, spike_axes = plot_spikes(spikes=_spikes, ims=spike_ims, axes=spike_axes) weights_im = plot_conv2d_weights( w, im=weights_im, wmax=network.connections['X', 'Y'].wmax) plt.pause(1e-2) network.reset_() # Reset state variables. print(f'Progress: {n_examples} / {n_examples} ({t() - start:.4f} seconds)') i += 1 if i % len(labels) == 0: current_labels = labels[-update_interval:] current_record = full_spike_record[-update_interval:] else: current_labels = labels[i % len(labels) - update_interval:i % len(labels)] current_record = full_spike_record[i % len(labels) - update_interval:i % len(labels)] # Update and print accuracy evaluations. curves, preds = update_curves(curves, current_labels, n_classes, full_spike_record=current_record, logreg=logreg_model) print_results(curves) for scheme in preds: predictions[scheme] = torch.cat([predictions[scheme], preds[scheme]], -1) if train: if any([x[-1] > best_accuracy for x in curves.values()]): print('New best accuracy! Saving network parameters to disk.') # Save network to disk. network.save(os.path.join(params_path, model_name + '.pt')) path = os.path.join(params_path, '_'.join(['auxiliary', model_name]) + '.pt') torch.save((logreg_model.coef_, logreg_model.intercept_), open(path, 'wb')) if train: print('\nTraining complete.\n') else: print('\nTest complete.\n') print('Average accuracies:\n') for scheme in curves.keys(): print('\t%s: %.2f' % (scheme, float(np.mean(curves[scheme])))) # Save accuracy curves to disk. to_write = ['train'] + params if train else ['test'] + params to_write = [str(x) for x in to_write] f = '_'.join(to_write) + '.pt' torch.save((curves, update_interval, n_examples), open(os.path.join(curves_path, f), 'wb')) # Save results to disk. results = [np.mean(curves['logreg']), np.std(curves['logreg'])] to_write = params + results if train else test_params + results to_write = [str(x) for x in to_write] name = 'train.csv' if train else 'test.csv' if not os.path.isfile(os.path.join(results_path, name)): with open(os.path.join(results_path, name), 'w') as f: if train: columns = [ 'seed', 'n_train', 'kernel_size', 'stride', 'n_filters', 'padding', 'inhib', 'time', 'lr', 'lr_decay', 'dt', 'intensity', 'update_interval', 'mean_logreg', 'std_logreg' ] header = ','.join(columns) + '\n' f.write(header) else: columns = [ 'seed', 'n_train', 'n_test', 'kernel_size', 'stride', 'n_filters', 'padding', 'inhib', 'time', 'lr', 'lr_decay', 'dt', 'intensity', 'update_interval', 'mean_logreg', 'std_logreg' ] header = ','.join(columns) + '\n' f.write(header) with open(os.path.join(results_path, name), 'a') as f: f.write(','.join(to_write) + '\n') if labels.numel() > n_examples: labels = labels[:n_examples] else: while labels.numel() < n_examples: if 2 * labels.numel() > n_examples: labels = torch.cat( [labels, labels[:n_examples - labels.numel()]]) else: labels = torch.cat([labels, labels]) # Compute confusion matrices and save them to disk. confusions = {} for scheme in predictions: confusions[scheme] = confusion_matrix(labels, predictions[scheme]) to_write = ['train'] + params if train else ['test'] + test_params f = '_'.join([str(x) for x in to_write]) + '.pt' torch.save(confusions, os.path.join(confusion_path, f))
rtnn_layer_sz = 50 num_timesteps = 16 tnn_thresh = 64 rtnn_thresh = 8 max_weight = 16 max_weight_rtnn = 16 num_winners_tnn = 1 num_winners_rtnn = rtnn_layer_sz//10 time = num_timesteps torch.manual_seed(seed) # build network: network = Network(dt=1) input_layer_a = Input(n=input_slice) input_layer_b = Input(n=input_slice) tnn_layer_1a = TemporalNeurons( n=tnn_layer_sz, timesteps=num_timesteps, threshold=tnn_thresh, num_winners=num_winners_tnn ) tnn_layer_1b = TemporalNeurons( n=tnn_layer_sz, timesteps=num_timesteps, threshold=tnn_thresh, num_winners=num_winners_tnn ) rtnn_layer_1 = TemporalNeurons(
from bindsnet.network import Network from bindsnet.pipeline import EnvironmentPipeline from bindsnet.learning import MSTDP from bindsnet.encoding import bernoulli from bindsnet.network.topology import Connection from bindsnet.environment import GymEnvironment from bindsnet.network.nodes import Input, LIFNodes from bindsnet.pipeline.action import select_softmax # Build network. network = Network(dt=1.0) # Layers of neurons. inpt = Input(n=80 * 80, shape=[80, 80], traces=True) middle = LIFNodes(n=100, traces=True) out = LIFNodes(n=4, refrac=0, traces=True) # Connections between layers. inpt_middle = Connection(source=inpt, target=middle, wmin=0, wmax=1e-1) middle_out = Connection( source=middle, target=out, wmin=0, wmax=1, update_rule=MSTDP, nu=1e-1, norm=0.5 * middle.n, ) # Add all layers and connections to the network. network.add_layer(inpt, name="Input Layer")
import torch import matplotlib.pyplot as plt from bindsnet.network import Network from bindsnet.network.nodes import Input, LIFNodes, IO_Input from bindsnet.network.topology import Connection from bindsnet.network.monitors import Monitor from bindsnet.analysis.plotting import plot_spikes, plot_voltages, plot_weights from bindsnet.learning import MSTDP, PostPre, Hebbian from bindsnet.utils import Error2IO_Current from bindsnet.encoding import poisson time = 1000 network = Network(dt=1) # GR_Movement_layer = Input(n=100) GR_Joint_layer = Input(n=500, traces=True) PK = LIFNodes(n=8, traces=True) PK_Anti = LIFNodes(n=8, traces=True) IO = IO_Input(n=8) IO_Anti = IO_Input(n=8) DCN = LIFNodes(n=100, thresh=-57, traces=True) DCN_Anti = LIFNodes(n=100, thresh=-57, trace=True) # 输入motor相关 Parallelfiber = Connection( source=GR_Joint_layer, target=PK, wmin=0, wmax=10, update_rule=Hebbian, # 此处可替换为自己写的LTP nu=0.1, w=0.1 + torch.zeros(GR_Joint_layer.n, PK.n))
plot_voltages, plot_weights, ) from bindsnet.datasets import MNIST from bindsnet.encoding import poisson_loader from bindsnet.network import Network from bindsnet.network.nodes import Input # Build a simple two-layer, input-output network. from bindsnet.network.monitors import Monitor from bindsnet.network.nodes import LIFNodes from bindsnet.network.topology import Connection from bindsnet.utils import get_square_weights network = Network(dt=1.0) inpt = Input(784, shape=(28, 28)) network.add_layer(inpt, name="I") output = LIFNodes(625, thresh=-52 + torch.randn(625)) network.add_layer(output, name="O") C1 = Connection(source=inpt, target=output, w=torch.randn(inpt.n, output.n)) C2 = Connection(source=output, target=output, w=0.5 * torch.randn(output.n, output.n)) network.add_connection(C1, source="I", target="O") network.add_connection(C2, source="O", target="O") spikes = {} for l in network.layers: spikes[l] = Monitor(network.layers[l], ["s"], time=250) network.add_monitor(spikes[l], name="%s_spikes" % l)
def main(args): if args.gpu: torch.cuda.manual_seed_all(args.seed) else: torch.manual_seed(args.seed) conv_size = int( (28 - args.kernel_size + 2 * args.padding) / args.stride) + 1 # Build network. network = Network() input_layer = Input(n=784, shape=(1, 28, 28), traces=True) conv_layer = DiehlAndCookNodes( n=args.n_filters * conv_size * conv_size, shape=(args.n_filters, conv_size, conv_size), traces=True, ) conv_conn = Conv2dConnection( input_layer, conv_layer, kernel_size=args.kernel_size, stride=args.stride, update_rule=PostPre, norm=0.4 * args.kernel_size**2, nu=[0, args.lr], reduction=max_without_indices, wmax=1.0, ) w = torch.zeros(args.n_filters, conv_size, conv_size, args.n_filters, conv_size, conv_size) for fltr1 in range(args.n_filters): for fltr2 in range(args.n_filters): if fltr1 != fltr2: for i in range(conv_size): for j in range(conv_size): w[fltr1, i, j, fltr2, i, j] = -100.0 w = w.view(args.n_filters * conv_size * conv_size, args.n_filters * conv_size * conv_size) recurrent_conn = Connection(conv_layer, conv_layer, w=w) network.add_layer(input_layer, name="X") network.add_layer(conv_layer, name="Y") network.add_connection(conv_conn, source="X", target="Y") network.add_connection(recurrent_conn, source="Y", target="Y") # Voltage recording for excitatory and inhibitory layers. voltage_monitor = Monitor(network.layers["Y"], ["v"], time=args.time) network.add_monitor(voltage_monitor, name="output_voltage") if args.gpu: network.to("cuda") # Load MNIST data. train_dataset = MNIST( PoissonEncoder(time=args.time, dt=args.dt), None, os.path.join(ROOT_DIR, "data", "MNIST"), download=True, train=True, transform=transforms.Compose([ transforms.ToTensor(), transforms.Lambda(lambda x: x * args.intensity) ]), ) spikes = {} for layer in set(network.layers): spikes[layer] = Monitor(network.layers[layer], state_vars=["s"], time=args.time) network.add_monitor(spikes[layer], name="%s_spikes" % layer) voltages = {} for layer in set(network.layers) - {"X"}: voltages[layer] = Monitor(network.layers[layer], state_vars=["v"], time=args.time) network.add_monitor(voltages[layer], name="%s_voltages" % layer) # Train the network. print("Begin training.\n") start = time() weights_im = None for epoch in range(args.n_epochs): if epoch % args.progress_interval == 0: print("Progress: %d / %d (%.4f seconds)" % (epoch, args.n_epochs, time() - start)) start = time() train_dataloader = DataLoader( train_dataset, batch_size=args.batch_size, shuffle=True, num_workers=4, pin_memory=args.gpu, ) for step, batch in enumerate(tqdm(train_dataloader)): # Get next input sample. inpts = {"X": batch["encoded_image"]} if args.gpu: inpts = {k: v.cuda() for k, v in inpts.items()} # Run the network on the input. network.run(inpts=inpts, time=args.time, input_time_dim=0) # Decay learning rate. network.connections["X", "Y"].nu[1] *= 0.99 # Optionally plot various simulation information. if args.plot: weights = conv_conn.w weights_im = plot_conv2d_weights(weights, im=weights_im) plt.pause(1e-8) network.reset_() # Reset state variables. print("Progress: %d / %d (%.4f seconds)\n" % (args.n_epochs, args.n_epochs, time() - start)) print("Training complete.\n")
plot_interval = args.plot_interval render_interval = args.render_interval print_interval = args.print_interval gpu = args.gpu if gpu: torch.set_default_tensor_type('torch.cuda.FloatTensor') torch.cuda.manual_seed_all(seed) else: torch.manual_seed(seed) # Build network. network = Network(dt=dt) # Layers of neurons. inpt = Input(shape=(110, 84), traces=True) # Input layer exc = LIFNodes(n=n_neurons, refrac=0, traces=True) # Excitatory layer readout = LIFNodes(n=14, refrac=0, traces=True) # Readout layer layers = {'X' : inpt, 'E' : exc, 'R' : readout} # Connections between layers. # Input -> excitatory. w = 0.01 * torch.rand(layers['X'].n, layers['E'].n) input_exc_conn = Connection(source=layers['X'], target=layers['E'], w=0.01 * torch.rand(layers['X'].n, layers['E'].n), wmax=0.02, norm=0.01 * layers['X'].n) # Excitatory -> readout. exc_readout_conn = Connection(source=layers['E'], target=layers['R'], w=0.01 * torch.rand(layers['E'].n, layers['R'].n), update_rule=Hebbian, nu_pre=1e-2, nu_post=1e-2, norm=0.5 * layers['E'].n) # Spike recordings for all layers.
def __init__( self, n_inpt: int, n_neurons: int = 100, exc: float = 22.5, inh: float = 17.5, dt: float = 1.0, nu: Optional[Union[float, Sequence[float]]] = (1e-4, 1e-2), reduction: Optional[callable] = None, wmin: float = 0.0, wmax: float = 1000.0, norm: float = 78.4, theta_plus: float = 0.05 * 1000, tc_theta_decay: float = 1e7, inpt_shape: Optional[Iterable[int]] = None, ) -> None: # language=rst """ Constructor for class ``DiehlAndCook2015``. :param n_inpt: Number of input neurons. Matches the 1D size of the input data. :param n_neurons: Number of excitatory, inhibitory neurons. :param exc: Strength of synapse weights from excitatory to inhibitory layer. :param inh: Strength of synapse weights from inhibitory to excitatory layer. :param dt: Simulation time step. :param nu: Single or pair of learning rates for pre- and post-synaptic events, respectively. :param reduction: Method for reducing parameter updates along the minibatch dimension. :param wmin: Minimum allowed weight on input to excitatory synapses. :param wmax: Maximum allowed weight on input to excitatory synapses. :param norm: Input to excitatory layer connection weights normalization constant. :param theta_plus: On-spike increment of ``DiehlAndCookNodes`` membrane threshold potential. :param tc_theta_decay: Time constant of ``DiehlAndCookNodes`` threshold potential decay. :param inpt_shape: The dimensionality of the input layer. """ super().__init__(dt=dt) self.n_inpt = n_inpt self.inpt_shape = inpt_shape self.n_neurons = n_neurons self.exc = exc self.inh = inh self.dt = dt # Layers input_layer = Input(n=self.n_inpt, shape=self.inpt_shape, traces=True, tc_trace=20.0) exc_layer = DiehlAndCookNodes( n=self.n_neurons, traces=True, rest=0.0, reset=5.0, thresh=12.0 * 1000, refrac=5, tc_decay=100.0, tc_trace=20.0, theta_plus=theta_plus, tc_theta_decay=tc_theta_decay, ) inh_layer = LIFNodes( n=self.n_neurons, traces=False, rest=0.0, reset=15.0, thresh=20.0 * 1000, tc_decay=10.0, refrac=2, tc_trace=20.0, ) # Connections w = 0.3 * 1000 * torch.rand(self.n_inpt, self.n_neurons) input_exc_conn = Connection( source=input_layer, target=exc_layer, w=w, update_rule=PostPre, nu=nu, reduction=reduction, wmin=wmin, wmax=wmax, norm=norm, ) w = self.exc * torch.diag(torch.ones(self.n_neurons)) exc_inh_conn = Connection(source=exc_layer, target=inh_layer, w=w, wmin=0, wmax=self.exc) w = -self.inh * (torch.ones(self.n_neurons, self.n_neurons) - torch.diag(torch.ones(self.n_neurons))) inh_exc_conn = Connection(source=inh_layer, target=exc_layer, w=w, wmin=-self.inh, wmax=0) # Add to network self.add_layer(input_layer, name="X") self.add_layer(exc_layer, name="Ae") self.add_layer(inh_layer, name="Ai") self.add_connection(input_exc_conn, source="X", target="Ae") self.add_connection(exc_inh_conn, source="Ae", target="Ai") self.add_connection(inh_exc_conn, source="Ai", target="Ae")
def toLIF(network: Network): new_network = Network(dt=1, learning=True) input_layer = Input(n=network.X.n, shape=network.X.shape, traces=True, tc_trace=network.X.tc_trace.item()) exc_layer = LIFNodes( n=network.Ae.n, traces=True, rest=network.Ai.rest.item(), reset=network.Ai.reset.item(), thresh=network.Ai.thresh.item(), refrac=network.Ai.refrac.item(), tc_decay=network.Ai.tc_decay.item(), ) inh_layer = LIFNodes( n=network.Ai.n, traces=False, rest=network.Ai.rest.item(), reset=network.Ai.reset.item(), thresh=network.Ai.thresh.item(), tc_decay=network.Ai.tc_decay.item(), refrac=network.Ai.refrac.item(), ) # Connections w = network.X_to_Ae.w input_exc_conn = Connection( source=input_layer, target=exc_layer, w=w, update_rule=PostPre, nu=network.X_to_Ae.nu, reduction=network.X_to_Ae.reduction, wmin=network.X_to_Ae.wmin, wmax=network.X_to_Ae.wmax, norm=network.X_to_Ae.norm * 1, ) w = network.Ae_to_Ai.w exc_inh_conn = Connection(source=exc_layer, target=inh_layer, w=w, wmin=network.Ae_to_Ai.wmin, wmax=network.Ae_to_Ai.wmax) w = network.Ai_to_Ae.w inh_exc_conn = Connection(source=inh_layer, target=exc_layer, w=w, wmin=network.Ai_to_Ae.wmin, wmax=network.Ai_to_Ae.wmax) # Add to network new_network.add_layer(input_layer, name="X") new_network.add_layer(exc_layer, name="Ae") new_network.add_layer(inh_layer, name="Ai") new_network.add_connection(input_exc_conn, source="X", target="Ae") new_network.add_connection(exc_inh_conn, source="Ae", target="Ai") new_network.add_connection(inh_exc_conn, source="Ai", target="Ae") exc_voltage_monitor = Monitor(new_network.layers["Ae"], ["v"], time=500) inh_voltage_monitor = Monitor(new_network.layers["Ai"], ["v"], time=500) new_network.add_monitor(exc_voltage_monitor, name="exc_voltage") new_network.add_monitor(inh_voltage_monitor, name="inh_voltage") spikes = {} for layer in set(network.layers): spikes[layer] = Monitor(new_network.layers[layer], state_vars=["s"], time=time) new_network.add_monitor(spikes[layer], name="%s_spikes" % layer) return new_network
gpu = args.gpu if gpu: torch.cuda.manual_seed_all(seed) else: torch.manual_seed(seed) if not train: update_interval = n_test conv_size = int((28 - kernel_size + 2 * padding) / stride) + 1 per_class = int((n_filters * conv_size * conv_size) / 10) # Build network. network = Network() input_layer = Input(n=784, shape=(1, 28, 28), traces=True) conv_layer = DiehlAndCookNodes( n=n_filters * conv_size * conv_size, shape=(n_filters, conv_size, conv_size), traces=True, ) conv_conn = Conv2dConnection( input_layer, conv_layer, kernel_size=kernel_size, stride=stride, update_rule=PostPre, norm=0.4 * kernel_size**2, nu=[1e-4, 1e-2],
import torch from bindsnet.network import Network from bindsnet.pipeline import EnvironmentPipeline from bindsnet.learning import MSTDPET from bindsnet.encoding import BernoulliEncoder from bindsnet.network.topology import Connection from bindsnet.environment import GymEnvironment from bindsnet.network.nodes import Input, LIFNodes from bindsnet.pipeline.action import select_multinomial # Build network. network = Network(dt=1.0) # Layers of neurons. inpt = Input(n=78 * 84, shape=[1, 1, 78, 84], traces=True) middle = LIFNodes(n=225, traces=True, thresh=-52.0 + torch.randn(225)) out = LIFNodes(n=60, refrac=0, traces=True, thresh=-40.0) # Connections between layers. inpt_middle = Connection(source=inpt, target=middle, wmax=1e-2) middle_out = Connection( source=middle, target=out, wmax=0.5, update_rule=MSTDPET, nu=2e-2, norm=0.15 * middle.n, ) # Add all layers and connections to the network.
max_weight = num_timesteps num_winners = 3 #tnn_layer_sz time = num_timesteps gpu = False if gpu and torch.cuda.is_available(): torch.cuda.set_device(device_id) # torch.set_default_tensor_type('torch.cuda.FloatTensor') else: torch.manual_seed(seed) plot = True # build network: network = Network(dt=1) input_layer = Input(n=input_size) tnn_layer_1 = TemporalNeurons( \ n=tnn_layer_sz, \ timesteps=num_timesteps, \ threshold=tnn_thresh, \ num_winners=num_winners\ ) buffer_layer_1 = TemporalBufferNeurons( n=tnn_layer_sz, timesteps=num_timesteps, ) C1 = Connection(source=input_layer, target=tnn_layer_1,