Initial population persistence
This commit is contained in:
parent
68b43ee476
commit
5553f8994f
@ -81,6 +81,8 @@ namespace NanoBrain {
|
|||||||
[HideInInspector]
|
[HideInInspector]
|
||||||
public List<Nucleus> nuclei = new();
|
public List<Nucleus> nuclei = new();
|
||||||
|
|
||||||
|
#region Timed Actions
|
||||||
|
|
||||||
public class TimedAction {
|
public class TimedAction {
|
||||||
public TimedAction(string neuronName, Action action, long timestamp) {
|
public TimedAction(string neuronName, Action action, long timestamp) {
|
||||||
this.neuronName = neuronName;
|
this.neuronName = neuronName;
|
||||||
@ -146,6 +148,8 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion Timed Actions
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
|
||||||
public Cluster() {
|
public Cluster() {
|
||||||
@ -368,6 +372,90 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Cluster Clone() {
|
||||||
|
Cluster clone = new() {
|
||||||
|
name = this.name,
|
||||||
|
prefab = this.prefab,
|
||||||
|
version = this.version,
|
||||||
|
parent = this.parent
|
||||||
|
};
|
||||||
|
if (clone.parent != null) {
|
||||||
|
// Do we need to clone the parent here too????
|
||||||
|
}
|
||||||
|
|
||||||
|
// first clone the nuclei without their connections
|
||||||
|
foreach (Nucleus nucleus in this.nuclei)
|
||||||
|
nucleus.ShallowCloneTo(clone);
|
||||||
|
|
||||||
|
Nucleus[] clonedNuclei = clone.nuclei.ToArray();
|
||||||
|
// Now clone the connections
|
||||||
|
for (int nucleusIx = 0; nucleusIx < this.nuclei.Count; nucleusIx++) {
|
||||||
|
Nucleus sourceNucleus = this.nuclei[nucleusIx];
|
||||||
|
if (sourceNucleus is not Neuron sourceNeuron)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Nucleus clonedNucleus = clonedNuclei[nucleusIx];
|
||||||
|
if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
foreach (Synapse sourceSynapse in sourceNeuron.synapses) {
|
||||||
|
Neuron synapseNeuron = sourceSynapse.neuron;
|
||||||
|
if (synapseNeuron.parent.prefab != null && synapseNeuron.parent.prefab != clone.prefab) {
|
||||||
|
// Neuron is in another cluster, find the cloned cluster first
|
||||||
|
Cluster sourceCluster = synapseNeuron.parent;
|
||||||
|
Cluster clonedCluster = clone.nuclei.Find(n => n.name == sourceCluster.name) as Cluster;
|
||||||
|
if (clonedCluster == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Now find the neuron in that cloned cluster
|
||||||
|
int neuronIx = GetNucleusIndex(sourceCluster.nuclei, sourceSynapse.neuron.name);
|
||||||
|
if (neuronIx < 0)
|
||||||
|
// Could not find the neuron in the prefab cluster
|
||||||
|
continue;
|
||||||
|
if (clonedCluster.nuclei[neuronIx] is not Neuron clonedSender)
|
||||||
|
// Could not find the neuron in the cloned cluster
|
||||||
|
continue;
|
||||||
|
|
||||||
|
clonedSender.AddReceiver(clonedNeuron, sourceSynapse.weight, sourceSynapse.trainable);
|
||||||
|
//Debug.Log($"Add synapse {clonedCluster.name}.{clonedSender.name} -> {clonedNeuron.name} [{clonedSender.receivers.Count}]");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int ix = GetNucleusIndex(clone.prefab.cluster.nuclei, sourceSynapse.neuron);
|
||||||
|
if (ix < 0)
|
||||||
|
continue;
|
||||||
|
if (clonedNuclei[ix] is not Neuron clonedSender)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Copy the receivers which will also create the synapse
|
||||||
|
clonedSender.AddReceiver(clonedNeuron, sourceSynapse.weight, sourceSynapse.trainable);
|
||||||
|
// Debug.Log($"Add synapse {clonedSender.name} -> {clonedNeuron.name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Nucleus clonedNucleus in clonedNuclei) {
|
||||||
|
if (clonedNucleus is not Cluster clonedCluster)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
List<Cluster> siblings = new() { clonedCluster };
|
||||||
|
for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) {
|
||||||
|
// Create another sibling
|
||||||
|
Cluster sibling = new(clonedCluster.prefab, this) {
|
||||||
|
name = $"{clonedCluster.baseName}: {instanceIx}",
|
||||||
|
parent = clone.parent,
|
||||||
|
instanceCount = clone.instanceCount,
|
||||||
|
};
|
||||||
|
siblings.Add(sibling);
|
||||||
|
CopyAllExternalReceivers(clonedCluster, sibling, this);
|
||||||
|
}
|
||||||
|
Cluster[] siblingClusters = siblings.ToArray();
|
||||||
|
foreach (Cluster sibling in siblings)
|
||||||
|
sibling.instances = siblingClusters;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clone;
|
||||||
|
}
|
||||||
|
|
||||||
/// \copydoc NanoBrain::Nucleus::ShallowCloneTo
|
/// \copydoc NanoBrain::Nucleus::ShallowCloneTo
|
||||||
public override Nucleus ShallowCloneTo(Cluster parent) {
|
public override Nucleus ShallowCloneTo(Cluster parent) {
|
||||||
// Clusters should not be cloned, but instantiated from the prefab....
|
// Clusters should not be cloned, but instantiated from the prefab....
|
||||||
@ -1011,10 +1099,10 @@ namespace NanoBrain {
|
|||||||
#region Serialization
|
#region Serialization
|
||||||
|
|
||||||
public void Export(string path) {
|
public void Export(string path) {
|
||||||
ClusterData data = new(this); //this.ToJSON();
|
ClusterData data = new(this);
|
||||||
string json = JsonUtility.ToJson(data, prettyPrint: true);
|
string json = JsonUtility.ToJson(data, prettyPrint: true);
|
||||||
|
|
||||||
// Debug.Log($"Exporting json to {path}");
|
Debug.Log($"Exporting {this.name} to {path}");
|
||||||
File.WriteAllText(path, json);
|
File.WriteAllText(path, json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,9 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace NanoBrain {
|
namespace NanoBrain {
|
||||||
public class Population {
|
public class Population {
|
||||||
|
|
||||||
|
# region Members
|
||||||
|
|
||||||
public class Member {
|
public class Member {
|
||||||
public Member(Cluster cluster) {
|
public Member(Cluster cluster) {
|
||||||
this.brain = cluster;
|
this.brain = cluster;
|
||||||
@ -21,12 +24,49 @@ namespace NanoBrain {
|
|||||||
return newMember;
|
return newMember;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#endregion Members
|
||||||
/// Generational update
|
|
||||||
/// </summary>
|
|
||||||
public virtual void Update() {
|
|
||||||
|
|
||||||
|
#region Saving
|
||||||
|
|
||||||
|
public enum SaveMethod {
|
||||||
|
Average,
|
||||||
|
Mean,
|
||||||
|
First,
|
||||||
|
All
|
||||||
}
|
}
|
||||||
|
public void Save(string path, SaveMethod saveMethod = SaveMethod.Average) {
|
||||||
|
Cluster cluster = null;
|
||||||
|
switch (saveMethod) {
|
||||||
|
case SaveMethod.First:
|
||||||
|
Member member = this.members[0];
|
||||||
|
if (member == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cluster = member.brain;
|
||||||
|
break;
|
||||||
|
case SaveMethod.Average:
|
||||||
|
cluster = CalculateAverageCluster();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cluster?.Export(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Cluster CalculateAverageCluster() {
|
||||||
|
if (members.Count <= 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Cluster result = members[0].brain.Clone();
|
||||||
|
for (int memberIx = 1; memberIx < members.Count; memberIx++) {
|
||||||
|
Member member = members[memberIx];
|
||||||
|
result.ProcessWeightsFrom(member.brain, Average);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Saving
|
||||||
|
|
||||||
|
#region New Generation
|
||||||
|
|
||||||
public void NewGeneration() {
|
public void NewGeneration() {
|
||||||
foreach (Member member in this.members) {
|
foreach (Member member in this.members) {
|
||||||
@ -118,6 +158,8 @@ namespace NanoBrain {
|
|||||||
return selectedMembers;
|
return selectedMembers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion New Generation
|
||||||
|
|
||||||
private void LogTrainableWeights(Cluster cluster) {
|
private void LogTrainableWeights(Cluster cluster) {
|
||||||
string s = "";
|
string s = "";
|
||||||
foreach (Nucleus nucleus in cluster.nuclei) {
|
foreach (Nucleus nucleus in cluster.nuclei) {
|
||||||
@ -131,5 +173,7 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
Debug.Log(s);
|
Debug.Log(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void Update() { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user