Sam 3b64ef62e1
Some checks failed
Build Simulation and Test / Run All Tests (push) Failing after 2m35s
Refactor neural network implementation into separate neural.py file
2025-06-18 17:21:11 -05:00

94 lines
3.5 KiB
Python

from world.base.neural import FlexibleNeuralNetwork
from config.constants import MAX_VELOCITY, MAX_ROTATIONAL_VELOCITY
from world.behavioral import BehavioralModel
class CellBrain(BehavioralModel):
"""
Enhanced CellBrain using a flexible neural network with input normalization.
"""
def __init__(self, neural_network=None, input_ranges=None):
super().__init__()
# Define input and output keys
self.input_keys = ['distance', 'angle', 'current_speed', 'current_angular_velocity']
self.output_keys = ['linear_acceleration', 'angular_acceleration']
# Initialize inputs and outputs
self.inputs = {key: 0.0 for key in self.input_keys}
self.outputs = {key: 0.0 for key in self.output_keys}
# Set input ranges for normalization
default_ranges = {
'distance': (0, 50),
'angle': (-180, 180),
'current_speed': (-MAX_VELOCITY, MAX_VELOCITY),
'current_angular_velocity': (-MAX_ROTATIONAL_VELOCITY, MAX_ROTATIONAL_VELOCITY)
}
self.input_ranges = input_ranges if input_ranges is not None else default_ranges
# Use provided network or create new one
if neural_network is None:
self.neural_network = FlexibleNeuralNetwork(
input_size=len(self.input_keys),
output_size=len(self.output_keys)
)
else:
self.neural_network = neural_network
def _normalize_input(self, key, value):
min_val, max_val = self.input_ranges.get(key, (0.0, 1.0))
# Avoid division by zero
if max_val == min_val:
return 0.0
# Normalize to [-1, 1]
return 2 * (value - min_val) / (max_val - min_val) - 1
def tick(self, input_data) -> dict:
"""
Process inputs through neural network and produce outputs.
:param input_data: Dictionary containing input values
:return: Dictionary with output values
"""
# Update internal input state
for key in self.input_keys:
self.inputs[key] = input_data.get(key, 0.0)
# Normalize inputs
input_array = [self._normalize_input(key, self.inputs[key]) for key in self.input_keys]
# Process through neural network
output_array = self.neural_network.forward(input_array)
# Map outputs back to dictionary
self.outputs = {
key: output_array[i] if i < len(output_array) else 0.0
for i, key in enumerate(self.output_keys)
}
return self.outputs.copy()
def mutate(self, mutation_rate=0.1):
"""
Create a mutated copy of this CellBrain.
:param mutation_rate: Rate of mutation for the neural network
:return: New CellBrain with mutated neural network
"""
mutated_network = self.neural_network.mutate(mutation_rate)
return CellBrain(neural_network=mutated_network, input_ranges=self.input_ranges.copy())
def get_network_info(self):
"""Get information about the underlying neural network."""
return self.neural_network.get_structure_info()
def __repr__(self):
inputs = {key: round(value, 5) for key, value in self.inputs.items()}
outputs = {key: round(value, 5) for key, value in self.outputs.items()}
network_info = self.get_network_info()
return (f"CellBrain(inputs={inputs}, outputs={outputs}, "
f"network_layers={network_info['layer_sizes']}, "
f"connections={network_info['total_connections']})")