last changes

This commit is contained in:
2026-02-21 10:58:05 +01:00
parent 841bc7c805
commit 0902732f60
136 changed files with 10387 additions and 2015 deletions

View File

@@ -2,6 +2,9 @@ import asyncio
class Actor:
"""
actor base class.
"""
def __init__(self, name: str):
self.name = name
self.inbox = asyncio.Queue()

View File

@@ -7,6 +7,33 @@ log = logging.getLogger(__name__)
class Actuator(Actor):
"""
Actuator actor responsible for collecting outputs from upstream neurons
(fanin), assembling them into an action/output vector, interacting with
a scape (environment), and synchronizing the result back to the cortex.
Conceptually, an Actuator represents the *output layer* of a cortex/agent:
- It waits for `forward` messages from all expected fanin sources.
- Once all signals are received, they are concatenated in the order
defined by `fanin_ids` into a flat output vector.
- Depending on `aname`, the output is:
* used for debugging/testing ("pts"),
* sent directly as an action to a scape ("xor_SendOutput"),
* mapped to a car control action and sent to a CarRacing scape
("car_ApplyAction"),
* or ignored with a default fitness.
- After the interaction, the actuator reports the resulting fitness
and halt flag back to the cortex via a `"sync"` message.
Inbox message protocol:
- ("forward", from_id, vec):
`from_id` is the ID of the sending fanin neuron,
`vec` is its output vector.
- ("result", fitness, halt_flag):
Response from the scape after an action was applied.
- ("terminate",):
Terminates the actor.
"""
def __init__(self, aid, cx_pid, name, fanin_ids, expect_count, scape=None):
super().__init__(f"Actuator-{aid}")
self.aid = aid

View File

@@ -6,6 +6,41 @@ log = logging.getLogger(__name__)
class Cortex(Actor):
"""
Cortex actor coordinating a network of Sensors, Neurons, and Actuators.
The Cortex is responsible for driving the network forward in discrete
computation cycles, collecting fitness feedback from all actuators, and
reporting evaluation results to an Exoself (supervisor) actor.
High-level behavior:
- At the start of an episode, the cortex triggers a new cycle:
1) It tells all neurons to prepare recurrent state for the new cycle
via ("cycle_start",).
2) It optionally triggers neurons via ("tick",) (scheduler hook).
3) It tells all sensors to produce outputs via ("sync",).
- Actuators eventually send back ("sync", aid, fitness, halt_flag).
- Once all actuators have synchronized for the current cycle, the cortex
either:
* ends the evaluation if any actuator requested a halt (halt_flag > 0),
and reports ("evaluation_completed", total_fitness, cycles, elapsed)
to the exoself, or
* starts the next cycle.
Message protocol (inbox):
- ("register_actuators", aids):
Provide/replace the set of actuator IDs that must sync each cycle.
Used when actuators are created dynamically or not known at init.
- ("sync", aid, fitness, halt_flag):
Fitness feedback from an actuator for the current cycle.
The cortex accumulates fitness and checks halt conditions.
- ("reactivate",):
Restart a new evaluation episode (reset counters and kick sensors).
- ("terminate",):
Terminate the cortex and cascade termination to sensors/neurons/actuators.
- ("backup_from_neuron", nid, idps...):
Forward neuron backup data upstream to the exoself.
"""
def __init__(self, cid, exoself_pid, sensor_pids, neuron_pids, actuator_pids):
super().__init__(f"Cortex-{cid}")
self.cid = cid

View File

@@ -12,6 +12,24 @@ def tanh(x): return math.tanh(x)
class Neuron(Actor):
"""
Neuron actor implementing a weighted-sum neuron with an activation function
and optional recurrent inputs.
The Neuron receives input vectors from upstream neurons, accumulates them
according to its weight configuration, applies an activation function,
and forwards the resulting output to downstream actors.
It supports:
- feed-forward and recurrent connections
- bias handling
- asynchronous message-based execution
- weight backup, restoration, and stochastic perturbation (mutation)
- cycle-based updates for recurrent networks
This actor is designed to be used inside a cortex/agent actor network,
where synchronization and evolution are coordinated externally.
"""
def __init__(self, nid, cx_pid, af_name, input_idps, output_pids, bias: Optional[float] = None):
super().__init__(f"Neuron-{nid}")
self.nid = nid

View File

@@ -6,6 +6,42 @@ log = logging.getLogger(__name__)
class Sensor(Actor):
"""
Sensor actor that produces an input vector for the network and forwards it
to downstream actors (fanout).
A Sensor is an *input node* in the actor-based neural architecture. It does
not compute from other neurons; instead, it generates observations either
from:
- a local source (e.g., random numbers), or
- an external scape/environment actor.
When the cortex triggers a sensor with a ("sync",) message, the sensor:
1) calls `_sense()` to obtain a vector,
2) broadcasts that vector to all downstream targets in `fanout` via
("forward", sid, vec).
Supported sensor types (controlled by `sname`):
- "rng":
Produces `vl` random floats in [0, 1).
- "xor_GetInput" (requires `scape`):
Requests an input vector from the scape and expects a ("percept", vec)
reply on its own inbox.
- "car_GetFeatures" (requires `scape`):
Requests a feature vector from the scape and normalizes it:
* clamps values to [-1, 1],
* pads with zeros or truncates to exactly `vl` elements.
- default:
Returns a zero vector of length `vl`.
Inbox message protocol:
- ("sync",):
Trigger sensing and forwarding to fanout.
- ("percept", vec):
Scape reply to a previous ("sense", sid, self) request (handled inside `_sense()`).
- ("terminate",):
Stop the actor.
"""
def __init__(self, sid, cx_pid, name, vector_length, fanout_pids, scape=None):
super().__init__(f"Sensor-{sid}")
self.sid = sid