Fix Stimulus reset
This commit is contained in:
parent
760168a6f7
commit
8b456e2b7c
@ -70,8 +70,9 @@ namespace NanoBrain {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// In a multi-cluster each instance can be used for a thing.
|
/// In a multi-cluster each instance can be used for a thing.
|
||||||
/// Cluster instance may also not (yet) be mapped to a thing.
|
/// Cluster instance may also not (yet) be mapped to a thing.
|
||||||
[NonSerialized]
|
// [NonSerialized]
|
||||||
public Dictionary<int, Cluster> thingClusters = new();
|
// public Dictionary<int, Cluster> thingClusters = new();
|
||||||
|
public int thingId;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// All nuclei in this cluster
|
/// All nuclei in this cluster
|
||||||
@ -105,11 +106,13 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ix >= 0) {
|
if (ix >= 0) {
|
||||||
|
Debug.Log($"update {neuronName} {timestamp}");
|
||||||
actions[ix].action = action;
|
actions[ix].action = action;
|
||||||
actions[ix].timestamp = timestamp;
|
actions[ix].timestamp = timestamp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Log($"new {neuronName} {timestamp}");
|
||||||
// No existing item; compute insertion point (sorted by timestamp ascending)
|
// No existing item; compute insertion point (sorted by timestamp ascending)
|
||||||
for (int i = 0; i < actions.Count; i++) {
|
for (int i = 0; i < actions.Count; i++) {
|
||||||
if (actions[i].timestamp > timestamp) {
|
if (actions[i].timestamp > timestamp) {
|
||||||
@ -121,8 +124,27 @@ namespace NanoBrain {
|
|||||||
TimedAction newAction = new(neuronName, action, timestamp);
|
TimedAction newAction = new(neuronName, action, timestamp);
|
||||||
actions.Insert(insertIx, newAction);
|
actions.Insert(insertIx, newAction);
|
||||||
}
|
}
|
||||||
|
public static void Check(List<TimedAction> actions) {
|
||||||
|
long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
|
if (actions.Count > 0) {
|
||||||
|
Debug.Log($"{actions.Count} actions, {actions[0].neuronName} {actions[0].timestamp} {now} {actions[0].timestamp - now}");
|
||||||
|
}
|
||||||
|
while (actions.Count > 0 && actions[0].timestamp <= now) {
|
||||||
|
Action action = actions[0].action;
|
||||||
|
actions.RemoveAt(0);
|
||||||
|
action();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public readonly List<TimedAction> actions = new();
|
public readonly List<TimedAction> actions = new();
|
||||||
|
public void CheckActions() {
|
||||||
|
TimedAction.Check(this.actions);
|
||||||
|
foreach (Nucleus nucleus in this.nuclei) {
|
||||||
|
if (nucleus is not Cluster cluster)
|
||||||
|
continue;
|
||||||
|
cluster.CheckActions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
|
||||||
@ -531,17 +553,18 @@ namespace NanoBrain {
|
|||||||
/// Remove a mapping from a thing to a cluster such that it becomes available for new things
|
/// Remove a mapping from a thing to a cluster such that it becomes available for new things
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="cluster">The multi-cluster instance which not no longer be mapped</param>
|
/// <param name="cluster">The multi-cluster instance which not no longer be mapped</param>
|
||||||
private void RemoveThingCluster(Cluster cluster) {
|
public void RemoveThingCluster(Cluster cluster) {
|
||||||
int keyToRemove = -1;
|
cluster.thingId = 0;
|
||||||
foreach (KeyValuePair<int, Cluster> kvp in this.thingClusters) {
|
// int keyToRemove = -1;
|
||||||
if (kvp.Value == cluster) {
|
// foreach (KeyValuePair<int, Cluster> kvp in this.thingClusters) {
|
||||||
keyToRemove = kvp.Key;
|
// if (kvp.Value == cluster) {
|
||||||
break;
|
// keyToRemove = kvp.Key;
|
||||||
}
|
// break;
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
if (keyToRemove >= 0)
|
// if (keyToRemove >= 0)
|
||||||
this.thingClusters.Remove(keyToRemove);
|
// this.thingClusters.Remove(keyToRemove);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Neuron> GetAllInstances(Neuron nucleus) {
|
public List<Neuron> GetAllInstances(Neuron nucleus) {
|
||||||
@ -776,13 +799,18 @@ namespace NanoBrain {
|
|||||||
/// <returns>The found neuron or null when it is not found</returns>
|
/// <returns>The found neuron or null when it is not found</returns>
|
||||||
/// The cluster instance mapped to the thing will be neuron.parent if a neuron is found.
|
/// The cluster instance mapped to the thing will be neuron.parent if a neuron is found.
|
||||||
public Neuron GetNeuron(int thingId, string neuronName, string thingName = null) {
|
public Neuron GetNeuron(int thingId, string neuronName, string thingName = null) {
|
||||||
|
// If this is not an ClusterArray, just take the neuron
|
||||||
if (this.instances == null || this.instances.Length <= 1)
|
if (this.instances == null || this.instances.Length <= 1)
|
||||||
return this.GetNeuron(neuronName);
|
return this.GetNeuron(neuronName);
|
||||||
|
|
||||||
// See if we are already using a cluster for thingId
|
// See if we are already using a cluster for thingId
|
||||||
thingClusters ??= new();
|
// thingClusters ??= new();
|
||||||
if (thingClusters.TryGetValue(thingId, out Cluster cluster))
|
// if (thingClusters.TryGetValue(thingId, out Cluster cluster))
|
||||||
return cluster.GetNeuron(neuronName);
|
// return cluster.GetNeuron(neuronName);
|
||||||
|
foreach (Cluster sibling in this.instances) {
|
||||||
|
if (sibling.thingId == thingId)
|
||||||
|
return sibling.GetNeuron(neuronName);
|
||||||
|
}
|
||||||
|
|
||||||
// Find the cluster with the lowest value neuron
|
// Find the cluster with the lowest value neuron
|
||||||
Neuron lowestNeuron = null;
|
Neuron lowestNeuron = null;
|
||||||
@ -794,7 +822,8 @@ namespace NanoBrain {
|
|||||||
Cluster selectedCluster = lowestNeuron.parent;
|
Cluster selectedCluster = lowestNeuron.parent;
|
||||||
RemoveThingCluster(selectedCluster);
|
RemoveThingCluster(selectedCluster);
|
||||||
selectedCluster.name = baseName + ": " + thingName;
|
selectedCluster.name = baseName + ": " + thingName;
|
||||||
thingClusters[thingId] = selectedCluster;
|
//thingClusters[thingId] = selectedCluster;
|
||||||
|
selectedCluster.thingId = thingId;
|
||||||
return lowestNeuron;
|
return lowestNeuron;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -185,13 +185,17 @@ namespace NanoBrain {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual float3 outputValue {
|
public virtual float3 outputValue {
|
||||||
get {
|
get {
|
||||||
long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
// long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
List<Cluster.TimedAction> actions = this.parent.actions;
|
// List<Cluster.TimedAction> actions = this.parent.actions;
|
||||||
while (actions.Count > 0 && actions[0].timestamp <= now) {
|
// if (actions.Count > 0) {
|
||||||
Action action = actions[0].action;
|
// Debug.Log($"{actions.Count} actions, {actions[0].neuronName} {actions[0].timestamp} {now} {actions[0].timestamp - now}");
|
||||||
actions.RemoveAt(0);
|
// }
|
||||||
action();
|
// while (actions.Count > 0 && actions[0].timestamp <= now) {
|
||||||
}
|
// Action action = actions[0].action;
|
||||||
|
// actions.RemoveAt(0);
|
||||||
|
// action();
|
||||||
|
// }
|
||||||
|
this.parent.CheckActions();
|
||||||
return _outputValue;
|
return _outputValue;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
@ -253,7 +257,7 @@ namespace NanoBrain {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// When true, the value will not be reset after timeToSleep.
|
/// When true, the value will not be reset after timeToSleep.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool persistOutput = false;
|
//public bool persistOutput = false;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// True when the neuron is not persisting and has not be updated for timeToSleep seconds
|
/// True when the neuron is not persisting and has not be updated for timeToSleep seconds
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -304,7 +308,7 @@ namespace NanoBrain {
|
|||||||
protected virtual void CloneFields(Neuron clone) {
|
protected virtual void CloneFields(Neuron clone) {
|
||||||
clone.bias = this.bias;
|
clone.bias = this.bias;
|
||||||
clone.trainableBias = this.trainableBias;
|
clone.trainableBias = this.trainableBias;
|
||||||
clone.persistOutput = this.persistOutput;
|
//clone.persistOutput = this.persistOutput;
|
||||||
clone.combinator = this.combinator;
|
clone.combinator = this.combinator;
|
||||||
clone.activator = this.activator;
|
clone.activator = this.activator;
|
||||||
clone.breakOnUpdate = this.breakOnUpdate;
|
clone.breakOnUpdate = this.breakOnUpdate;
|
||||||
@ -812,13 +816,15 @@ namespace NanoBrain {
|
|||||||
if (autoResetDelay > 0) {
|
if (autoResetDelay > 0) {
|
||||||
long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||||
long resetTime = now + (long)(autoResetDelay * 1000.0f);
|
long resetTime = now + (long)(autoResetDelay * 1000.0f);
|
||||||
Cluster.TimedAction.AddTo(this.parent.actions, this.name, this.resetStimulus, resetTime);
|
Cluster.TimedAction.AddTo(this.parent.actions, this.parent.name + "." +this.name, this.resetStimulus, resetTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ResetStimulus() {
|
private void ResetStimulus() {
|
||||||
// Debug.Log("reset stimulus");
|
Debug.Log($"reset stimulus {this.parent.name + "." +this.name}");
|
||||||
|
this.parent.name = this.parent.baseName;
|
||||||
this.bias = Vector3.zero;
|
this.bias = Vector3.zero;
|
||||||
|
this.parent.thingId = 0;
|
||||||
this.parent?.UpdateFromNucleus(this);
|
this.parent?.UpdateFromNucleus(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,6 +47,7 @@ namespace NanoBrain {
|
|||||||
Debug.Log($"Selected {i}: {member.performance}");
|
Debug.Log($"Selected {i}: {member.performance}");
|
||||||
member.initialized = true;
|
member.initialized = true;
|
||||||
selectedMembers.Add(member);
|
selectedMembers.Add(member);
|
||||||
|
LogTrainableWeights(member.brain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +87,9 @@ namespace NanoBrain {
|
|||||||
|
|
||||||
member.brain.CopyWeightsFrom(ants[parent1].brain);
|
member.brain.CopyWeightsFrom(ants[parent1].brain);
|
||||||
member.brain.ProcessWeightsFrom(ants[parent2].brain, Average);
|
member.brain.ProcessWeightsFrom(ants[parent2].brain, Average);
|
||||||
|
LogTrainableWeights(member.brain);
|
||||||
member.brain.GaussianAdditiveMutation(1e-1f);
|
member.brain.GaussianAdditiveMutation(1e-1f);
|
||||||
|
LogTrainableWeights(member.brain);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float Average(float a, float b) {
|
private static float Average(float a, float b) {
|
||||||
@ -114,5 +117,19 @@ namespace NanoBrain {
|
|||||||
}
|
}
|
||||||
return selectedMembers;
|
return selectedMembers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LogTrainableWeights(Cluster cluster) {
|
||||||
|
string s = "";
|
||||||
|
foreach (Nucleus nucleus in cluster.nuclei) {
|
||||||
|
if (nucleus is Neuron neuron) {
|
||||||
|
foreach (Synapse synapse in neuron.synapses) {
|
||||||
|
if (synapse.trainable) {
|
||||||
|
s += synapse.weight + " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Debug.Log(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user