From 3bc3b006cf14e755ffdb28d63cbc835bbb981a47 Mon Sep 17 00:00:00 2001 From: nikos Date: Thu, 7 Aug 2025 20:45:55 -0400 Subject: [PATCH 1/6] Draft --- examples/dosidicus/network.py | 38 +++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 examples/dosidicus/network.py diff --git a/examples/dosidicus/network.py b/examples/dosidicus/network.py new file mode 100644 index 00000000..0cccae22 --- /dev/null +++ b/examples/dosidicus/network.py @@ -0,0 +1,38 @@ +import torch + +from bindsnet.network import Network +from bindsnet.network.nodes import LIFNodes +from bindsnet.network.topology import MulticompartmentConnection +from bindsnet.network.topology_features import Weight, Bias, Mask +from bindsnet.learning.MCC_learning import PostPre + +network = Network(dt=1.0) +source_layer = LIFNodes(n=5, traces=True) +target_layer = LIFNodes(n=5, traces=True) + + +network.add_layer(source_layer, name="input") +network.add_layer(target_layer, name="output") + +weight = Weight( + name='weight_feature', + value=torch.rand(5, 5), + learning_rule=PostPre, + nu=(1e-4, 1e-2) +) +bias = Bias(name='bias_feature', value=torch.rand(5, 5)) + +mask = torch.tril(torch.ones((5, 5)), diagonal=-1).bool() + +connection = MulticompartmentConnection( + source=source_layer, + target=target_layer, + pipeline=[weight, Mask(name='mask', value=mask), bias], + device='cpu' +) +network.add_connection(connection, source="input", target="output") +print(connection.pipeline[0].value) +network.run( + inputs={"input": torch.bernoulli(torch.rand(250, 5)).byte()}, time=250 +) +print(connection.pipeline[0].value) \ No newline at end of file From bbfb0b387c05638423542238f9af6c8516a227a2 Mon Sep 17 00:00:00 2001 From: nikos Date: Sat, 9 Aug 2025 17:49:56 -0400 Subject: [PATCH 2/6] Zerro out --- bindsnet/network/topology.py | 12 +++++++++++- examples/dosidicus/network.py | 15 ++++++++++----- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/bindsnet/network/topology.py b/bindsnet/network/topology.py index cb5fafa1..219dce7d 100644 --- a/bindsnet/network/topology.py +++ b/bindsnet/network/topology.py @@ -209,7 +209,15 @@ def update(self, **kwargs) -> None: :param bool learning: Whether to allow connection updates. """ - pass + mask = kwargs.get("mask", None) + if mask is None: + return + + for f in self.pipeline: + if type(f).__name__ != 'Weight': + continue + + f.value.masked_fill_(mask, 0) @abstractmethod def reset_state_variables(self) -> None: @@ -484,6 +492,8 @@ def update(self, **kwargs) -> None: """ learning = kwargs.get("learning", False) if learning and not self.manual_update: + super().update(**kwargs) + # Pipeline learning for f in self.pipeline: f.update(**kwargs) diff --git a/examples/dosidicus/network.py b/examples/dosidicus/network.py index 0cccae22..e93b22d9 100644 --- a/examples/dosidicus/network.py +++ b/examples/dosidicus/network.py @@ -3,7 +3,7 @@ from bindsnet.network import Network from bindsnet.network.nodes import LIFNodes from bindsnet.network.topology import MulticompartmentConnection -from bindsnet.network.topology_features import Weight, Bias, Mask +from bindsnet.network.topology_features import Weight, Bias from bindsnet.learning.MCC_learning import PostPre network = Network(dt=1.0) @@ -22,17 +22,22 @@ ) bias = Bias(name='bias_feature', value=torch.rand(5, 5)) -mask = torch.tril(torch.ones((5, 5)), diagonal=-1).bool() - connection = MulticompartmentConnection( source=source_layer, target=target_layer, - pipeline=[weight, Mask(name='mask', value=mask), bias], + pipeline=[weight, bias], device='cpu' ) network.add_connection(connection, source="input", target="output") print(connection.pipeline[0].value) network.run( - inputs={"input": torch.bernoulli(torch.rand(250, 5)).byte()}, time=250 + inputs={"input": torch.bernoulli(torch.rand(250, 5)).byte()}, + time=250, + masks={ + ('input', 'output'): ~torch.tril(torch.ones((5, 5)), diagonal=-1).bool() + } ) + +print(network.layers['input'].v) +print(network.layers['output'].v) print(connection.pipeline[0].value) \ No newline at end of file From 2f709fb21236c8ff7c5746fae0c651b39be27c56 Mon Sep 17 00:00:00 2001 From: nikos Date: Sat, 9 Aug 2025 17:51:45 -0400 Subject: [PATCH 3/6] Remove prints --- .gitignore | 1 + examples/dosidicus/network.py | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 197e3bb3..c8c46f5e 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ dist/* logs/* .pytest_cache/* .vscode/* +.idea data/* \ No newline at end of file diff --git a/examples/dosidicus/network.py b/examples/dosidicus/network.py index e93b22d9..d8e20510 100644 --- a/examples/dosidicus/network.py +++ b/examples/dosidicus/network.py @@ -37,7 +37,4 @@ ('input', 'output'): ~torch.tril(torch.ones((5, 5)), diagonal=-1).bool() } ) - -print(network.layers['input'].v) -print(network.layers['output'].v) print(connection.pipeline[0].value) \ No newline at end of file From e13974be0c371036754fbe62da301e852838bcd2 Mon Sep 17 00:00:00 2001 From: nikos Date: Thu, 21 Aug 2025 20:56:35 -0400 Subject: [PATCH 4/6] Mask for connection --- bindsnet/network/topology.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/bindsnet/network/topology.py b/bindsnet/network/topology.py index 219dce7d..262f4072 100644 --- a/bindsnet/network/topology.py +++ b/bindsnet/network/topology.py @@ -209,15 +209,7 @@ def update(self, **kwargs) -> None: :param bool learning: Whether to allow connection updates. """ - mask = kwargs.get("mask", None) - if mask is None: - return - - for f in self.pipeline: - if type(f).__name__ != 'Weight': - continue - - f.value.masked_fill_(mask, 0) + pass @abstractmethod def reset_state_variables(self) -> None: @@ -403,6 +395,7 @@ def __init__( pipeline: list = [], manual_update: bool = False, traces: bool = False, + mask: torch.Tensor = None, **kwargs, ) -> None: # language=rst @@ -416,11 +409,13 @@ def __init__( :param manual_update: Set to :code:`True` to disable automatic updates (applying learning rules) to connection features. False by default, updates called after each time step :param traces: Set to :code:`True` to record history of connection activity (for monitors) + :param mask: A mask to zero out weights """ super().__init__(source, target, device, pipeline, **kwargs) self.traces = traces self.manual_update = manual_update + self.mask = mask if self.traces: self.activity = None @@ -446,6 +441,8 @@ def compute(self, s: torch.Tensor) -> torch.Tensor: # Run through pipeline for f in self.pipeline: + if type(f).__name__ == 'Weight' and self.mask: + f.value.masked_fill_(self.mask, 0) conn_spikes = f.compute(conn_spikes) # Sum signals for each of the output/terminal neurons @@ -492,8 +489,6 @@ def update(self, **kwargs) -> None: """ learning = kwargs.get("learning", False) if learning and not self.manual_update: - super().update(**kwargs) - # Pipeline learning for f in self.pipeline: f.update(**kwargs) From 7a2fdb9baa9d37e5fc9e07bfbf8874e739f768fc Mon Sep 17 00:00:00 2001 From: nikos Date: Thu, 21 Aug 2025 21:11:30 -0400 Subject: [PATCH 5/6] fix --- bindsnet/network/topology.py | 2 +- examples/dosidicus/network.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/bindsnet/network/topology.py b/bindsnet/network/topology.py index 262f4072..ef6df695 100644 --- a/bindsnet/network/topology.py +++ b/bindsnet/network/topology.py @@ -441,7 +441,7 @@ def compute(self, s: torch.Tensor) -> torch.Tensor: # Run through pipeline for f in self.pipeline: - if type(f).__name__ == 'Weight' and self.mask: + if type(f).__name__ == 'Weight' and self.mask is not None: f.value.masked_fill_(self.mask, 0) conn_spikes = f.compute(conn_spikes) diff --git a/examples/dosidicus/network.py b/examples/dosidicus/network.py index d8e20510..9fcf84e1 100644 --- a/examples/dosidicus/network.py +++ b/examples/dosidicus/network.py @@ -26,15 +26,13 @@ source=source_layer, target=target_layer, pipeline=[weight, bias], + mask=~torch.tril(torch.ones((5, 5)), diagonal=-1).bool(), device='cpu' ) network.add_connection(connection, source="input", target="output") print(connection.pipeline[0].value) network.run( inputs={"input": torch.bernoulli(torch.rand(250, 5)).byte()}, - time=250, - masks={ - ('input', 'output'): ~torch.tril(torch.ones((5, 5)), diagonal=-1).bool() - } + time=250 ) print(connection.pipeline[0].value) \ No newline at end of file From 202f16eb559b92f0d985ef10c365da3d51080714 Mon Sep 17 00:00:00 2001 From: nikos Date: Tue, 26 Aug 2025 20:03:03 -0400 Subject: [PATCH 6/6] fix --- bindsnet/network/topology.py | 4 ++-- examples/dosidicus/network.py | 33 ++++++++++++++++----------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/bindsnet/network/topology.py b/bindsnet/network/topology.py index ef6df695..731291d1 100644 --- a/bindsnet/network/topology.py +++ b/bindsnet/network/topology.py @@ -441,8 +441,6 @@ def compute(self, s: torch.Tensor) -> torch.Tensor: # Run through pipeline for f in self.pipeline: - if type(f).__name__ == 'Weight' and self.mask is not None: - f.value.masked_fill_(self.mask, 0) conn_spikes = f.compute(conn_spikes) # Sum signals for each of the output/terminal neurons @@ -492,6 +490,8 @@ def update(self, **kwargs) -> None: # Pipeline learning for f in self.pipeline: f.update(**kwargs) + if type(f).__name__ == 'Weight' and self.mask is not None: + f.value.masked_fill_(self.mask, 0) def normalize(self) -> None: # language=rst diff --git a/examples/dosidicus/network.py b/examples/dosidicus/network.py index 9fcf84e1..81e0e203 100644 --- a/examples/dosidicus/network.py +++ b/examples/dosidicus/network.py @@ -6,33 +6,32 @@ from bindsnet.network.topology_features import Weight, Bias from bindsnet.learning.MCC_learning import PostPre -network = Network(dt=1.0) -source_layer = LIFNodes(n=5, traces=True) -target_layer = LIFNodes(n=5, traces=True) - - -network.add_layer(source_layer, name="input") -network.add_layer(target_layer, name="output") +network = Network(dt=1.0) +neurons_number = 7 +layer = LIFNodes(n=neurons_number, traces=True) +network.add_layer(layer, name="input") +network.add_layer(layer, name="output") +mask = ~torch.tril(torch.ones((neurons_number, neurons_number)), diagonal=-1).bool() weight = Weight( name='weight_feature', - value=torch.rand(5, 5), + value=torch.rand(neurons_number, neurons_number) * mask, learning_rule=PostPre, nu=(1e-4, 1e-2) ) -bias = Bias(name='bias_feature', value=torch.rand(5, 5)) - +bias = Bias( + name='bias_feature', + value=torch.rand(neurons_number, neurons_number) +) connection = MulticompartmentConnection( - source=source_layer, - target=target_layer, + source=layer, + target=layer, pipeline=[weight, bias], - mask=~torch.tril(torch.ones((5, 5)), diagonal=-1).bool(), + mask=mask, device='cpu' ) network.add_connection(connection, source="input", target="output") -print(connection.pipeline[0].value) network.run( - inputs={"input": torch.bernoulli(torch.rand(250, 5)).byte()}, + inputs={"input": torch.bernoulli(torch.rand(250, neurons_number)).byte()}, time=250 -) -print(connection.pipeline[0].value) \ No newline at end of file +) \ No newline at end of file