evonet 0.1.0.dev26__tar.gz → 0.1.0.dev27__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/PKG-INFO +1 -1
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/connection.py +16 -4
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/core.py +8 -7
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/PKG-INFO +1 -1
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/pyproject.toml +2 -2
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_recurrent_dynamics.py +9 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/LICENSE +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/README.md +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/__init__.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/activation.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/core_mit_plot_simple.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/enums.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/io.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/layer.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/mutation.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/neuron.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/serialization.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/utils.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/visualize.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/SOURCES.txt +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/dependency_links.txt +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/requires.txt +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/top_level.txt +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/setup.cfg +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_activation.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_core.py +0 -0
- {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_nnet_io_and_forward.py +0 -0
|
@@ -38,18 +38,30 @@ class Connection:
|
|
|
38
38
|
conn_type: ConnectionType = ConnectionType.STANDARD,
|
|
39
39
|
) -> None:
|
|
40
40
|
|
|
41
|
+
if delay < 0:
|
|
42
|
+
raise ValueError("delay must be >= 0")
|
|
43
|
+
|
|
44
|
+
# Normalize: recurrent implies delay >= 1
|
|
45
|
+
if conn_type is ConnectionType.RECURRENT and delay == 0:
|
|
46
|
+
delay = 1
|
|
47
|
+
|
|
41
48
|
self.source = source
|
|
42
49
|
self.target = target
|
|
43
50
|
self.weight = weight
|
|
44
51
|
self.delay = delay
|
|
45
|
-
self.type
|
|
52
|
+
self.type = conn_type
|
|
46
53
|
|
|
47
54
|
self._history: Optional[Deque[float]] = None
|
|
48
|
-
if self.
|
|
55
|
+
if self.type is ConnectionType.RECURRENT:
|
|
49
56
|
self._history = deque(maxlen=self.delay)
|
|
50
57
|
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
def set_delay(self, delay: int) -> None:
|
|
59
|
+
if self.type is not ConnectionType.RECURRENT:
|
|
60
|
+
raise ValueError("set_delay is only valid for recurrent connections")
|
|
61
|
+
if delay <= 0:
|
|
62
|
+
delay = 1
|
|
63
|
+
self.delay = int(delay)
|
|
64
|
+
self._history = deque(maxlen=self.delay)
|
|
53
65
|
|
|
54
66
|
def push_source_output(self, value: float) -> None:
|
|
55
67
|
"""
|
|
@@ -351,6 +351,12 @@ class Nnet:
|
|
|
351
351
|
if weight is None:
|
|
352
352
|
weight = 0.0
|
|
353
353
|
|
|
354
|
+
# Normalize recurrent delays
|
|
355
|
+
if conn_type is ConnectionType.RECURRENT and delay <= 0:
|
|
356
|
+
delay = 1
|
|
357
|
+
if conn_type is not ConnectionType.RECURRENT and delay < 0:
|
|
358
|
+
delay = 0
|
|
359
|
+
|
|
354
360
|
conn = Connection(
|
|
355
361
|
source, target, weight=weight, conn_type=conn_type, delay=delay
|
|
356
362
|
)
|
|
@@ -402,12 +408,7 @@ class Nnet:
|
|
|
402
408
|
for n in layer.neurons:
|
|
403
409
|
for c in n.incoming:
|
|
404
410
|
if c.type is ConnectionType.RECURRENT:
|
|
405
|
-
|
|
406
|
-
# Use delayed history if configured
|
|
407
|
-
n.input += c.weight * c.delayed_source_output()
|
|
408
|
-
else:
|
|
409
|
-
# default: 1-step recurrence via last_output
|
|
410
|
-
n.input += c.weight * c.source.last_output
|
|
411
|
+
n.input += c.weight * c.delayed_source_output()
|
|
411
412
|
|
|
412
413
|
# Feed-forward by layers: activate first, then propagate non-recurrent edges
|
|
413
414
|
for layer in self.layers:
|
|
@@ -442,7 +443,7 @@ class Nnet:
|
|
|
442
443
|
|
|
443
444
|
# Update recurrent delay buffers once per time step.
|
|
444
445
|
for c in self.get_all_connections():
|
|
445
|
-
if c.type is ConnectionType.RECURRENT
|
|
446
|
+
if c.type is ConnectionType.RECURRENT:
|
|
446
447
|
c.push_source_output(c.source.output)
|
|
447
448
|
|
|
448
449
|
return [n.output for n in self.layers[-1].neurons]
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "evonet"
|
|
7
|
-
version = "0.1.0.
|
|
7
|
+
version = "0.1.0.dev27"
|
|
8
8
|
description = "Evolvable neural network core for integration with EvoLib"
|
|
9
9
|
authors = [
|
|
10
10
|
{ name = "EvoLib", email = "evolib@dismail.de" }
|
|
@@ -48,7 +48,7 @@ include = ["evonet*"]
|
|
|
48
48
|
# Tool-Konfigurationen
|
|
49
49
|
[tool.black]
|
|
50
50
|
line-length = 88
|
|
51
|
-
target-version = ["
|
|
51
|
+
target-version = ["py312"]
|
|
52
52
|
|
|
53
53
|
[tool.isort]
|
|
54
54
|
profile = "black"
|
|
@@ -181,3 +181,12 @@ def test_reset_full_clears_delay_history() -> None:
|
|
|
181
181
|
# After full reset, history is gone -> delay contribution must be 0.0
|
|
182
182
|
y = net.calc([0.0])[0]
|
|
183
183
|
assert y == pytest.approx(0.0)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def test_recurrent_delay_zero_normalizes_to_one() -> None:
|
|
187
|
+
net, n_in, n_hid, _ = _mk_linear_ih_h_o()
|
|
188
|
+
c = net.add_connection(
|
|
189
|
+
n_hid, n_hid, weight=1.0, conn_type=ConnectionType.RECURRENT, delay=0
|
|
190
|
+
)
|
|
191
|
+
assert c is not None
|
|
192
|
+
assert c.delay == 1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|