evonet 0.1.0.dev23__tar.gz → 0.1.0.dev25__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.
Files changed (28) hide show
  1. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/PKG-INFO +41 -16
  2. evonet-0.1.0.dev25/README.md +72 -0
  3. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/core.py +52 -8
  4. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/mutation.py +4 -0
  5. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/neuron.py +35 -0
  6. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet.egg-info/PKG-INFO +41 -16
  7. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/pyproject.toml +1 -1
  8. evonet-0.1.0.dev23/README.md +0 -47
  9. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/LICENSE +0 -0
  10. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/__init__.py +0 -0
  11. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/activation.py +0 -0
  12. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/connection.py +0 -0
  13. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/core_mit_plot_simple.py +0 -0
  14. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/enums.py +0 -0
  15. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/io.py +0 -0
  16. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/layer.py +0 -0
  17. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/serialization.py +0 -0
  18. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/utils.py +0 -0
  19. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet/visualize.py +0 -0
  20. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet.egg-info/SOURCES.txt +0 -0
  21. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet.egg-info/dependency_links.txt +0 -0
  22. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet.egg-info/requires.txt +0 -0
  23. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/evonet.egg-info/top_level.txt +0 -0
  24. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/setup.cfg +0 -0
  25. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/tests/test_activation.py +0 -0
  26. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/tests/test_core.py +0 -0
  27. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/tests/test_nnet_io_and_forward.py +0 -0
  28. {evonet-0.1.0.dev23 → evonet-0.1.0.dev25}/tests/test_recurrent_dynamics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evonet
3
- Version: 0.1.0.dev23
3
+ Version: 0.1.0.dev25
4
4
  Summary: Evolvable neural network core for integration with EvoLib
5
5
  Author-email: EvoLib <evolib@dismail.de>
6
6
  License: MIT License
@@ -50,30 +50,54 @@ Requires-Dist: myst-parser; extra == "docs"
50
50
  Dynamic: license-file
51
51
 
52
52
  # EvoNet
53
+
53
54
  [![Code Quality & Tests](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml/badge.svg)](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml)
54
55
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
55
56
  [![Project Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/EvoLib/evo-net)
56
57
 
57
- **EvoNet** is a modular and evolvable neural network core designed for integration with [EvoLib](https://github.com/EvoLib/evo-lib).
58
- It supports dynamic topologies, recurrent connections, per-neuron activation, and structural evolution – with a strong emphasis on **clarity**, **transparency**, and **didactic value**.
58
+ **EvoNet** is a modular and evolvable neural network core designed for integration
59
+ with [EvoLib](https://github.com/EvoLib/evo-lib).
60
+ It supports dynamic topologies, recurrent connections, per-neuron activation, and
61
+ structural evolution, with a strong emphasis on clarity and explicit behaviour.
62
+
63
+ ---
64
+
65
+ ## Scope
66
+
67
+ EvoNet is not a state-of-the-art or general-purpose deep learning framework.
68
+
69
+ It does not aim to compete with libraries such as PyTorch, TensorFlow, or JAX in terms
70
+ of performance, scalability, or training algorithms. Backpropagation, GPU acceleration,
71
+ and highly optimised tensor operations are outside the scope of this project.
72
+
73
+ Instead, EvoNet is designed for evolutionary algorithms, structural mutation, and
74
+ exploratory research, with a focus on transparent and explicit implementations rather
75
+ than performance optimisation or feature completeness.
76
+
77
+ EvoNet should be understood as a conceptual and experimental model, not as a
78
+ production-grade neural-network engine.
59
79
 
60
80
  ---
61
81
 
62
82
  ## Features
63
83
 
64
- - **Layer-based but flexible** – allows skip connections, cycles, and recurrent paths
84
+ - **Explicit, layer-based topology** with support for skip connections, cycles,
85
+ and recurrent paths
65
86
  - **Typed neuron roles and connection types** (`NeuronRole`, `ConnectionType`)
66
- - **Topology-aware mutation system** – add/remove neurons and connections, mutate weights, change activations
67
- - **Per-neuron activation functions** – configurable, extensible, evolvable
68
- - **1-step recurrent state logic** – avoids multi-pass stabilization
69
- - **Topology can grow at runtime** – with `add_neuron`, `add_connection`, `split_connection`
70
- - **Debug-friendly architecture** – explicit IDs, labels, roles, directional graphs
71
- - **Designed for evolutionary learning** – mutation, crossover, speciation ready
72
- - **Lightweight & extensible** – pure Python, NumPy-based, no hard dependencies
87
+ - **Topology-aware mutation operations**:
88
+ add/remove neurons and connections, mutate weights, change activations
89
+ - **Per-neuron activation functions**, configurable and evolvable
90
+ - **Explicit 1-step recurrent state model**, without iterative stabilisation passes
91
+ - **Runtime topology growth**, e.g. via `add_neuron` and `add_connection`
92
+ - **Debug-friendly architecture** with explicit neuron IDs, labels, roles,
93
+ and directional graphs
94
+ - **Designed for evolutionary integration**, not gradient-based training
95
+ - **Lightweight and extensible**: pure Python, NumPy-based, no hard dependencies
73
96
 
74
97
  ---
75
98
 
76
- > ⚠️ **This project is in early development (alpha)**. Interfaces and structure may change.
99
+ > ⚠️ **Project status: Alpha**
100
+ > Interfaces, APIs, and internal structure may change as the project evolves.
77
101
 
78
102
  ---
79
103
 
@@ -83,14 +107,15 @@ It supports dynamic topologies, recurrent connections, per-neuron activation, an
83
107
  from evonet.core import Nnet
84
108
 
85
109
  net = Nnet()
86
- net.add_layer() # Input
87
- net.add_layer() # Output
110
+ net.add_layer() # Input layer
111
+ net.add_layer() # Output layer
88
112
 
89
- net.add_neuron(layer_idx=0, activation="linear", lable="in")
90
- net.add_neuron(layer_idx=1, activation="linear", bias=0.5, lable="out", connect_layer=True)
113
+ net.add_neuron(layer_idx=0, activation="linear", label="in")
114
+ net.add_neuron(layer_idx=1, activation="linear", bias=0.5, label="out")
91
115
 
92
116
  print(net.calc([1.0]))
93
117
  ```
118
+ ---
94
119
 
95
120
  ## License
96
121
 
@@ -0,0 +1,72 @@
1
+ # EvoNet
2
+
3
+ [![Code Quality & Tests](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml/badge.svg)](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml)
4
+ [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
5
+ [![Project Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/EvoLib/evo-net)
6
+
7
+ **EvoNet** is a modular and evolvable neural network core designed for integration
8
+ with [EvoLib](https://github.com/EvoLib/evo-lib).
9
+ It supports dynamic topologies, recurrent connections, per-neuron activation, and
10
+ structural evolution, with a strong emphasis on clarity and explicit behaviour.
11
+
12
+ ---
13
+
14
+ ## Scope
15
+
16
+ EvoNet is not a state-of-the-art or general-purpose deep learning framework.
17
+
18
+ It does not aim to compete with libraries such as PyTorch, TensorFlow, or JAX in terms
19
+ of performance, scalability, or training algorithms. Backpropagation, GPU acceleration,
20
+ and highly optimised tensor operations are outside the scope of this project.
21
+
22
+ Instead, EvoNet is designed for evolutionary algorithms, structural mutation, and
23
+ exploratory research, with a focus on transparent and explicit implementations rather
24
+ than performance optimisation or feature completeness.
25
+
26
+ EvoNet should be understood as a conceptual and experimental model, not as a
27
+ production-grade neural-network engine.
28
+
29
+ ---
30
+
31
+ ## Features
32
+
33
+ - **Explicit, layer-based topology** with support for skip connections, cycles,
34
+ and recurrent paths
35
+ - **Typed neuron roles and connection types** (`NeuronRole`, `ConnectionType`)
36
+ - **Topology-aware mutation operations**:
37
+ add/remove neurons and connections, mutate weights, change activations
38
+ - **Per-neuron activation functions**, configurable and evolvable
39
+ - **Explicit 1-step recurrent state model**, without iterative stabilisation passes
40
+ - **Runtime topology growth**, e.g. via `add_neuron` and `add_connection`
41
+ - **Debug-friendly architecture** with explicit neuron IDs, labels, roles,
42
+ and directional graphs
43
+ - **Designed for evolutionary integration**, not gradient-based training
44
+ - **Lightweight and extensible**: pure Python, NumPy-based, no hard dependencies
45
+
46
+ ---
47
+
48
+ > ⚠️ **Project status: Alpha**
49
+ > Interfaces, APIs, and internal structure may change as the project evolves.
50
+
51
+ ---
52
+
53
+ ## Quick Example
54
+
55
+ ```python
56
+ from evonet.core import Nnet
57
+
58
+ net = Nnet()
59
+ net.add_layer() # Input layer
60
+ net.add_layer() # Output layer
61
+
62
+ net.add_neuron(layer_idx=0, activation="linear", label="in")
63
+ net.add_neuron(layer_idx=1, activation="linear", bias=0.5, label="out")
64
+
65
+ print(net.calc([1.0]))
66
+ ```
67
+ ---
68
+
69
+ ## License
70
+
71
+ MIT License - see [MIT License](https://github.com/EvoLib/evo-net/tree/main/LICENSE).
72
+
@@ -117,11 +117,14 @@ class Nnet:
117
117
  label: str = "",
118
118
  role: NeuronRole = NeuronRole.HIDDEN,
119
119
  count: int = 1,
120
+ dynamics_name: str = "standard",
121
+ dynamics_params: dict[str, float] | None = None,
120
122
  connection_init: Literal["random", "zero", "near_zero", "none"] = "zero",
121
123
  recurrent: Optional[set[RecurrentKind]] = None,
122
124
  connection_scope: Literal["adjacent", "crosslayer"] = "adjacent",
123
125
  connection_density: float = 1.0,
124
126
  max_connections: int = 2**63 - 1,
127
+ require_io_connections: bool = True,
125
128
  ) -> list[Neuron]:
126
129
  """
127
130
  Add one or more neurons to the network.
@@ -147,6 +150,9 @@ class Nnet:
147
150
  that should actually be created. Must be in [0, 1].
148
151
  max_connections:
149
152
  Hard limit for the number of created connections per neuron.
153
+ require_io_connections:
154
+ If True, ensure that each newly added neuron has at least
155
+ one incoming and one outgoing connection (if structurally possible).
150
156
 
151
157
  Returns:
152
158
  list[Neuron]: The created neuron objects.
@@ -172,6 +178,10 @@ class Nnet:
172
178
  neuron = Neuron(activation=activation, bias=bias)
173
179
  neuron.role = role
174
180
  neuron.label = label
181
+
182
+ neuron.dynamics_name = dynamics_name
183
+ neuron.dynamics_params = dict(dynamics_params) if dynamics_params else {}
184
+
175
185
  target_layer.neurons.append(neuron)
176
186
  new_neurons.append(neuron)
177
187
 
@@ -260,21 +270,55 @@ class Nnet:
260
270
  if not all_candidates:
261
271
  continue
262
272
 
263
- total = len(all_candidates)
273
+ forced: list[tuple[Neuron, Neuron, ConnectionType]] = []
274
+
275
+ # --------------------------------------------------------------
276
+ # IO enforcement
277
+ # --------------------------------------------------------------
278
+
279
+ if require_io_connections and max_connections > 0:
280
+ incoming_candidates = [
281
+ (src, dst, ctype) for src, dst, ctype in all_candidates if dst is n
282
+ ]
283
+
284
+ outgoing_candidates = [
285
+ (src, dst, ctype) for src, dst, ctype in all_candidates if src is n
286
+ ]
287
+
288
+ # Enforce incoming if possible
289
+ if incoming_candidates:
290
+ forced.append(random.choice(incoming_candidates))
291
+
292
+ # Enforce outgoing if possible and budget allows
293
+ if outgoing_candidates and len(forced) < max_connections:
294
+ forced.append(random.choice(outgoing_candidates))
264
295
 
265
- # Global connection budget based on density
296
+ # --------------------------------------------------------------
297
+ # Remaining
298
+ # --------------------------------------------------------------
299
+
300
+ total = len(all_candidates)
266
301
  k = int(np.ceil(total * connection_density))
267
- k = min(k, max_connections)
302
+ k = min(k, max_connections - len(forced))
268
303
  k = max(k, 0)
269
304
 
305
+ remaining_candidates = [c for c in all_candidates if c not in forced]
306
+
307
+ # Create forced connections
308
+ for src, dst, ctype in forced:
309
+ self.add_connection(src, dst, weight=weight, conn_type=ctype)
310
+
311
+ k = min(k, len(remaining_candidates))
312
+
270
313
  if k == 0:
271
314
  continue
272
315
 
273
- # Randomly select k connections across all types
274
- selected = random.sample(all_candidates, k)
316
+ sampled = random.sample(remaining_candidates, k)
275
317
 
276
- # Create the selected connections
277
- for src, dst, ctype in selected:
318
+ # --------------------------------------------------------------
319
+ # Create connections
320
+ # --------------------------------------------------------------
321
+ for src, dst, ctype in forced + sampled:
278
322
  self.add_connection(src, dst, weight=weight, conn_type=ctype)
279
323
 
280
324
  return new_neurons
@@ -374,7 +418,7 @@ class Nnet:
374
418
  for n in layer.neurons:
375
419
  if n.activation_name != "softmax":
376
420
  total = n.input + n.bias
377
- n.output = n.activation(total)
421
+ n.output = n.compute_output(total)
378
422
 
379
423
  # Propagate to targets (exclude recurrent edges)
380
424
  for n in layer.neurons:
@@ -273,6 +273,8 @@ def add_random_neuron(
273
273
  connection_scope: Literal["adjacent", "crosslayer"] = "adjacent",
274
274
  connection_density: float = 1.0,
275
275
  max_connections: int = 2**63 - 1,
276
+ dynamics_name: str = "standard",
277
+ dynamics_params: dict[str, float] = {},
276
278
  ) -> Neuron | None:
277
279
  """
278
280
  Insert a new hidden neuron into a random layer.
@@ -313,6 +315,8 @@ def add_random_neuron(
313
315
  connection_scope=connection_scope,
314
316
  connection_density=connection_density,
315
317
  max_connections=max_connections,
318
+ dynamics_name=dynamics_name,
319
+ dynamics_params=dynamics_params,
316
320
  )[0]
317
321
 
318
322
  return new_neuron
@@ -55,6 +55,41 @@ class Neuron:
55
55
  self.last_output: float = 0.0
56
56
  self.label = label
57
57
 
58
+ # Neuron dynamics (stateful behaviour over time)
59
+ self.dynamics_name: str = "standard"
60
+ self.dynamics_params: dict[str, float] = {}
61
+
62
+ def compute_output(self, total_input: float) -> float:
63
+ """
64
+ Compute the neuron's output given the total input.
65
+
66
+ This method defines the neuron's local output dynamics and serves as the single
67
+ extension point for experimental neuron behaviour (e.g. leaky integration,
68
+ gating, oscillators).
69
+
70
+ By default, this applies the activation function directly.
71
+ """
72
+
73
+ # Default / standard dynamics
74
+ if self.dynamics_name == "standard":
75
+ return self.activation(total_input)
76
+
77
+ # Leaky integrator dynamics
78
+ if self.dynamics_name == "leaky":
79
+ alpha = self.dynamics_params.get("alpha", 1.0)
80
+
81
+ # Safety: keep alpha in [0, 1]
82
+ if alpha < 0.0:
83
+ alpha = 0.0
84
+ elif alpha > 1.0:
85
+ alpha = 1.0
86
+
87
+ raw = self.activation(total_input)
88
+ return (1.0 - alpha) * self.last_output + alpha * raw
89
+
90
+ # Fallback: unknown dynamics --> behave like standard
91
+ return self.activation(total_input)
92
+
58
93
  def reset(self, full: bool = False) -> None:
59
94
  """
60
95
  Clear current neuron state for a new forward pass.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evonet
3
- Version: 0.1.0.dev23
3
+ Version: 0.1.0.dev25
4
4
  Summary: Evolvable neural network core for integration with EvoLib
5
5
  Author-email: EvoLib <evolib@dismail.de>
6
6
  License: MIT License
@@ -50,30 +50,54 @@ Requires-Dist: myst-parser; extra == "docs"
50
50
  Dynamic: license-file
51
51
 
52
52
  # EvoNet
53
+
53
54
  [![Code Quality & Tests](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml/badge.svg)](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml)
54
55
  [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
55
56
  [![Project Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/EvoLib/evo-net)
56
57
 
57
- **EvoNet** is a modular and evolvable neural network core designed for integration with [EvoLib](https://github.com/EvoLib/evo-lib).
58
- It supports dynamic topologies, recurrent connections, per-neuron activation, and structural evolution – with a strong emphasis on **clarity**, **transparency**, and **didactic value**.
58
+ **EvoNet** is a modular and evolvable neural network core designed for integration
59
+ with [EvoLib](https://github.com/EvoLib/evo-lib).
60
+ It supports dynamic topologies, recurrent connections, per-neuron activation, and
61
+ structural evolution, with a strong emphasis on clarity and explicit behaviour.
62
+
63
+ ---
64
+
65
+ ## Scope
66
+
67
+ EvoNet is not a state-of-the-art or general-purpose deep learning framework.
68
+
69
+ It does not aim to compete with libraries such as PyTorch, TensorFlow, or JAX in terms
70
+ of performance, scalability, or training algorithms. Backpropagation, GPU acceleration,
71
+ and highly optimised tensor operations are outside the scope of this project.
72
+
73
+ Instead, EvoNet is designed for evolutionary algorithms, structural mutation, and
74
+ exploratory research, with a focus on transparent and explicit implementations rather
75
+ than performance optimisation or feature completeness.
76
+
77
+ EvoNet should be understood as a conceptual and experimental model, not as a
78
+ production-grade neural-network engine.
59
79
 
60
80
  ---
61
81
 
62
82
  ## Features
63
83
 
64
- - **Layer-based but flexible** – allows skip connections, cycles, and recurrent paths
84
+ - **Explicit, layer-based topology** with support for skip connections, cycles,
85
+ and recurrent paths
65
86
  - **Typed neuron roles and connection types** (`NeuronRole`, `ConnectionType`)
66
- - **Topology-aware mutation system** – add/remove neurons and connections, mutate weights, change activations
67
- - **Per-neuron activation functions** – configurable, extensible, evolvable
68
- - **1-step recurrent state logic** – avoids multi-pass stabilization
69
- - **Topology can grow at runtime** – with `add_neuron`, `add_connection`, `split_connection`
70
- - **Debug-friendly architecture** – explicit IDs, labels, roles, directional graphs
71
- - **Designed for evolutionary learning** – mutation, crossover, speciation ready
72
- - **Lightweight & extensible** – pure Python, NumPy-based, no hard dependencies
87
+ - **Topology-aware mutation operations**:
88
+ add/remove neurons and connections, mutate weights, change activations
89
+ - **Per-neuron activation functions**, configurable and evolvable
90
+ - **Explicit 1-step recurrent state model**, without iterative stabilisation passes
91
+ - **Runtime topology growth**, e.g. via `add_neuron` and `add_connection`
92
+ - **Debug-friendly architecture** with explicit neuron IDs, labels, roles,
93
+ and directional graphs
94
+ - **Designed for evolutionary integration**, not gradient-based training
95
+ - **Lightweight and extensible**: pure Python, NumPy-based, no hard dependencies
73
96
 
74
97
  ---
75
98
 
76
- > ⚠️ **This project is in early development (alpha)**. Interfaces and structure may change.
99
+ > ⚠️ **Project status: Alpha**
100
+ > Interfaces, APIs, and internal structure may change as the project evolves.
77
101
 
78
102
  ---
79
103
 
@@ -83,14 +107,15 @@ It supports dynamic topologies, recurrent connections, per-neuron activation, an
83
107
  from evonet.core import Nnet
84
108
 
85
109
  net = Nnet()
86
- net.add_layer() # Input
87
- net.add_layer() # Output
110
+ net.add_layer() # Input layer
111
+ net.add_layer() # Output layer
88
112
 
89
- net.add_neuron(layer_idx=0, activation="linear", lable="in")
90
- net.add_neuron(layer_idx=1, activation="linear", bias=0.5, lable="out", connect_layer=True)
113
+ net.add_neuron(layer_idx=0, activation="linear", label="in")
114
+ net.add_neuron(layer_idx=1, activation="linear", bias=0.5, label="out")
91
115
 
92
116
  print(net.calc([1.0]))
93
117
  ```
118
+ ---
94
119
 
95
120
  ## License
96
121
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "evonet"
7
- version = "0.1.0.dev23"
7
+ version = "0.1.0.dev25"
8
8
  description = "Evolvable neural network core for integration with EvoLib"
9
9
  authors = [
10
10
  { name = "EvoLib", email = "evolib@dismail.de" }
@@ -1,47 +0,0 @@
1
- # EvoNet
2
- [![Code Quality & Tests](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml/badge.svg)](https://github.com/EvoLib/evo-net/actions/workflows/ci.yml)
3
- [![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
4
- [![Project Status: Alpha](https://img.shields.io/badge/status-alpha-orange.svg)](https://github.com/EvoLib/evo-net)
5
-
6
- **EvoNet** is a modular and evolvable neural network core designed for integration with [EvoLib](https://github.com/EvoLib/evo-lib).
7
- It supports dynamic topologies, recurrent connections, per-neuron activation, and structural evolution – with a strong emphasis on **clarity**, **transparency**, and **didactic value**.
8
-
9
- ---
10
-
11
- ## Features
12
-
13
- - **Layer-based but flexible** – allows skip connections, cycles, and recurrent paths
14
- - **Typed neuron roles and connection types** (`NeuronRole`, `ConnectionType`)
15
- - **Topology-aware mutation system** – add/remove neurons and connections, mutate weights, change activations
16
- - **Per-neuron activation functions** – configurable, extensible, evolvable
17
- - **1-step recurrent state logic** – avoids multi-pass stabilization
18
- - **Topology can grow at runtime** – with `add_neuron`, `add_connection`, `split_connection`
19
- - **Debug-friendly architecture** – explicit IDs, labels, roles, directional graphs
20
- - **Designed for evolutionary learning** – mutation, crossover, speciation ready
21
- - **Lightweight & extensible** – pure Python, NumPy-based, no hard dependencies
22
-
23
- ---
24
-
25
- > ⚠️ **This project is in early development (alpha)**. Interfaces and structure may change.
26
-
27
- ---
28
-
29
- ## Quick Example
30
-
31
- ```python
32
- from evonet.core import Nnet
33
-
34
- net = Nnet()
35
- net.add_layer() # Input
36
- net.add_layer() # Output
37
-
38
- net.add_neuron(layer_idx=0, activation="linear", lable="in")
39
- net.add_neuron(layer_idx=1, activation="linear", bias=0.5, lable="out", connect_layer=True)
40
-
41
- print(net.calc([1.0]))
42
- ```
43
-
44
- ## License
45
-
46
- MIT License - see [MIT License](https://github.com/EvoLib/evo-net/tree/main/LICENSE).
47
-
File without changes
File without changes
File without changes