initial.
This commit is contained in:
196
experiments/genotype_mapper.py
Normal file
196
experiments/genotype_mapper.py
Normal file
@@ -0,0 +1,196 @@
|
||||
import json
|
||||
import random
|
||||
import math
|
||||
from typing import List, Dict, Tuple
|
||||
|
||||
|
||||
# ---- Hilfsfunktionen ----
|
||||
def generate_id():
|
||||
"""Generiert eine eindeutige ID basierend auf Zufallszahlen."""
|
||||
return random.random()
|
||||
|
||||
|
||||
def create_neural_weights(vector_length: int):
|
||||
"""Erstellt eine Liste von Gewichten für eine Verbindung."""
|
||||
return [random.uniform(-0.5, 0.5) for _ in range(vector_length)]
|
||||
|
||||
|
||||
# ---- Klassen ----
|
||||
class Sensor:
|
||||
def __init__(self, name: str, vector_length: int):
|
||||
self.id = generate_id()
|
||||
self.name = name
|
||||
self.vector_length = vector_length
|
||||
self.cx_id = None # Wird später hinzugefügt
|
||||
self.fanout_ids = [] # Verbindungen zu Neuronen
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"vector_length": self.vector_length,
|
||||
"cx_id": self.cx_id,
|
||||
"fanout_ids": self.fanout_ids,
|
||||
}
|
||||
|
||||
|
||||
class Actuator:
|
||||
def __init__(self, name: str, vector_length: int):
|
||||
self.id = generate_id()
|
||||
self.name = name
|
||||
self.vector_length = vector_length
|
||||
self.cx_id = None # Wird später hinzugefügt
|
||||
self.fanin_ids = [] # Verbindungen von Neuronen
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"name": self.name,
|
||||
"vector_length": self.vector_length,
|
||||
"cx_id": self.cx_id,
|
||||
"fanin_ids": self.fanin_ids,
|
||||
}
|
||||
|
||||
|
||||
class Neuron:
|
||||
def __init__(self, layer_index: int, input_ids: List[Tuple[float, int]], output_ids: List[float], cx_id: float):
|
||||
self.id = generate_id()
|
||||
self.layer_index = layer_index
|
||||
self.cx_id = cx_id
|
||||
self.activation_function = "tanh"
|
||||
self.input_weights = [
|
||||
{"input_id": input_id, "weights": create_neural_weights(vector_length)}
|
||||
for input_id, vector_length in input_ids
|
||||
]
|
||||
self.output_ids = output_ids
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"layer_index": self.layer_index,
|
||||
"cx_id": self.cx_id,
|
||||
"activation_function": self.activation_function,
|
||||
"input_weights": self.input_weights,
|
||||
"output_ids": self.output_ids,
|
||||
}
|
||||
|
||||
|
||||
class Cortex:
|
||||
def __init__(self, sensor_ids: List[float], actuator_ids: List[float], neuron_ids: List[float]):
|
||||
self.id = generate_id()
|
||||
self.sensor_ids = sensor_ids
|
||||
self.actuator_ids = actuator_ids
|
||||
self.neuron_ids = neuron_ids
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
"id": self.id,
|
||||
"sensor_ids": self.sensor_ids,
|
||||
"actuator_ids": self.actuator_ids,
|
||||
"neuron_ids": self.neuron_ids,
|
||||
}
|
||||
|
||||
# ---- Hauptfunktionen ----
|
||||
|
||||
|
||||
def construct_genotype(sensor_name: str, actuator_name: str, hidden_layer_densities: List[int], file_name: str):
|
||||
"""
|
||||
Konstruktion eines Genotyps und Speicherung in einer JSON-Datei.
|
||||
"""
|
||||
# Sensor erstellen
|
||||
if sensor_name == "rng":
|
||||
sensor = Sensor(name="rng", vector_length=2)
|
||||
else:
|
||||
raise ValueError(f"System does not support a sensor by the name: {sensor_name}")
|
||||
|
||||
# Aktuator erstellen
|
||||
if actuator_name == "pts":
|
||||
actuator = Actuator(name="pts", vector_length=1)
|
||||
else:
|
||||
raise ValueError(f"System does not support an actuator by the name: {actuator_name}")
|
||||
|
||||
# Neuronenschichten erstellen
|
||||
output_layer_density = actuator.vector_length
|
||||
layer_densities = hidden_layer_densities + [output_layer_density]
|
||||
cortex_id = generate_id()
|
||||
|
||||
neurons = create_neuro_layers(
|
||||
cortex_id,
|
||||
sensor,
|
||||
actuator,
|
||||
layer_densities
|
||||
)
|
||||
|
||||
# Sensor und Aktuator mit Cortex-Informationen aktualisieren
|
||||
input_layer_neurons = neurons[0]
|
||||
output_layer_neurons = neurons[-1]
|
||||
|
||||
sensor.cx_id = cortex_id
|
||||
sensor.fanout_ids = [neuron.id for neuron in input_layer_neurons]
|
||||
|
||||
actuator.cx_id = cortex_id
|
||||
actuator.fanin_ids = [neuron.id for neuron in output_layer_neurons]
|
||||
|
||||
# Cortex erstellen
|
||||
neuron_ids = [neuron.id for layer in neurons for neuron in layer]
|
||||
cortex = Cortex(
|
||||
sensor_ids=[sensor.id],
|
||||
actuator_ids=[actuator.id],
|
||||
neuron_ids=neuron_ids
|
||||
)
|
||||
|
||||
# Genotyp erstellen
|
||||
genotype = {
|
||||
"cortex": cortex.to_dict(),
|
||||
"sensor": sensor.to_dict(),
|
||||
"actuator": actuator.to_dict(),
|
||||
"neurons": [neuron.to_dict() for layer in neurons for neuron in layer]
|
||||
}
|
||||
|
||||
# Genotyp in Datei speichern
|
||||
with open(file_name, "w") as file:
|
||||
json.dump(genotype, file, indent=4)
|
||||
print(f"Genotype saved to {file_name}")
|
||||
|
||||
|
||||
def create_neuro_layers(cortex_id: float, sensor: Sensor, actuator: Actuator, layer_densities: List[int]) -> List[
|
||||
List[Neuron]]:
|
||||
"""
|
||||
Erstellt alle Neuronen in allen Schichten des Netzwerks.
|
||||
"""
|
||||
neurons = []
|
||||
input_ids = [(sensor.id, sensor.vector_length)]
|
||||
|
||||
for layer_index, layer_density in enumerate(layer_densities):
|
||||
output_ids = []
|
||||
if layer_index < len(layer_densities) - 1:
|
||||
# IDs der nächsten Schicht generieren
|
||||
output_ids = [generate_id() for _ in range(layer_densities[layer_index + 1])]
|
||||
|
||||
# Neuronen für die aktuelle Schicht erstellen
|
||||
layer_neurons = [
|
||||
Neuron(layer_index=layer_index, input_ids=input_ids, output_ids=output_ids, cx_id=cortex_id)
|
||||
for _ in range(layer_density)
|
||||
]
|
||||
neurons.append(layer_neurons)
|
||||
|
||||
# Aktuelle Schicht wird die Eingabe für die nächste Schicht
|
||||
input_ids = [(neuron.id, 1) for neuron in layer_neurons]
|
||||
|
||||
# Letzte Schicht mit Verbindung zum Aktuator erstellen
|
||||
final_layer = neurons[-1]
|
||||
for neuron in final_layer:
|
||||
neuron.output_ids = [actuator.id]
|
||||
|
||||
return neurons
|
||||
|
||||
|
||||
# ---- Beispielverwendung ----
|
||||
if __name__ == "__main__":
|
||||
# Genotyp erstellen und speichern
|
||||
construct_genotype(
|
||||
sensor_name="rng",
|
||||
actuator_name="pts",
|
||||
hidden_layer_densities=[4,3], # Dichten der versteckten Schichten (z. B. 4 Neuronen in der ersten Schicht, 3 in der zweiten)
|
||||
file_name="genotype.json" # Name der Datei, in der der Genotyp gespeichert wird
|
||||
)
|
||||
Reference in New Issue
Block a user