Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ see the [GitHub releases / tags](https://github.com/BindsNET/bindsnet/releases).
## [Unreleased]

### Fixed
- Forward mean-field `weight_decay` to the learning rule instead of treating it as
the update reduction; explicit `reduction` arguments are now accepted as well.
- `--seed` now makes GPU runs repeatable in `eth_mnist.py`, `batch_eth_mnist.py`,
`supervised_mnist.py`, `conv_mnist.py`, `conv1d_MNIST.py`, `conv3d_MNIST.py`,
`SOM_LM-SNNs.py` and `breakout/random_network_baseline.py`: they call
Expand Down
2 changes: 1 addition & 1 deletion bindsnet/network/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -2089,7 +2089,7 @@ def __init__(
tensor of same size as w
:param float norm: Total weight per target neuron normalization constant.
"""
super().__init__(source, target, nu, weight_decay, **kwargs)
super().__init__(source, target, nu=nu, weight_decay=weight_decay, **kwargs)

w = kwargs.get("w", None)
if w is None:
Expand Down
44 changes: 44 additions & 0 deletions test/network/test_meanfield_update_options.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest
import torch

from bindsnet.network import Network
from bindsnet.network.nodes import Input, LIFNodes
from bindsnet.network.topology import MeanFieldConnection


@pytest.mark.parametrize("weight_decay", [0.0, 0.1, 1.0])
@pytest.mark.parametrize("shared", [False, True])
def test_meanfield_weight_decay_during_network_run(weight_decay, shared):
network = Network()
source, target = Input(n=2), LIFNodes(n=3)
network.add_layer(source, "X")
network.add_layer(target, "Y")
initial = torch.tensor(0.5) if shared else torch.tensor([0.25, 0.5, 0.75])
connection = MeanFieldConnection(
source, target, w=initial.clone(), weight_decay=weight_decay
)
network.add_connection(connection, "X", "Y")
parameter = connection.w
# No STDP rule or normalization: the common learning-rule decay acts alone.
for step in range(1, 4):
network.run({"X": torch.zeros(1, 1, 2)}, time=1)
expected = initial * (1 - weight_decay) ** step
torch.testing.assert_close(connection.w, expected)
assert connection.w is parameter


@pytest.mark.parametrize(
"reduction,expected",
[(torch.sum, [5.0, 7.0, 9.0]), (torch.mean, [2.5, 3.5, 4.5])],
)
def test_meanfield_accepts_update_reduction(reduction, expected):
connection = MeanFieldConnection(
Input(n=2),
LIFNodes(n=3),
w=torch.tensor(0.5),
weight_decay=0.1,
reduction=reduction,
)
updates = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
actual = connection.update_rule.reduction(updates, dim=0)
torch.testing.assert_close(actual, torch.tensor(expected))
Loading