Selector is working
This commit is contained in:
parent
25cd5aefd0
commit
c290b62637
54
Cluster.cs
54
Cluster.cs
@ -258,27 +258,27 @@ public class Cluster : INucleus {
|
||||
|
||||
#region Update
|
||||
|
||||
public virtual void UpdateState() {
|
||||
UpdateState(new float3(0, 0, 0));
|
||||
}
|
||||
// public virtual void UpdateState() {
|
||||
// UpdateState(new float3(0, 0, 0));
|
||||
// }
|
||||
|
||||
public void UpdateState(float3 bias) {
|
||||
float3 sum = bias; // new(0, 0, 0);
|
||||
// public void UpdateState(float3 bias) {
|
||||
// float3 sum = bias; // new(0, 0, 0);
|
||||
|
||||
//Applying the weight factors
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
sum += synapse.weight * synapse.nucleus.outputValue;
|
||||
}
|
||||
// //Applying the weight factors
|
||||
// foreach (Synapse synapse in this.synapses) {
|
||||
// sum += synapse.weight * synapse.nucleus.outputValue;
|
||||
// }
|
||||
|
||||
//this.inputs[0].UpdateState(sum);
|
||||
this.inputs[0].UpdateStateIsolated(sum);
|
||||
foreach (IReceptor receptor in this.sortedNuclei) {
|
||||
if (receptor is INucleus nucleus && nucleus != this.inputs[0])
|
||||
nucleus.UpdateStateIsolated();
|
||||
}
|
||||
// //this.inputs[0].UpdateState(sum);
|
||||
// this.inputs[0].UpdateStateIsolated(sum);
|
||||
// foreach (IReceptor receptor in this.sortedNuclei) {
|
||||
// if (receptor is INucleus nucleus && nucleus != this.inputs[0])
|
||||
// nucleus.UpdateStateIsolated();
|
||||
// }
|
||||
|
||||
UpdateResult(this.output.outputValue);
|
||||
}
|
||||
// UpdateResult(this.output.outputValue);
|
||||
// }
|
||||
|
||||
public void UpdateStateIsolated() {
|
||||
float3 bias = new(0,0,0);
|
||||
@ -301,17 +301,17 @@ public class Cluster : INucleus {
|
||||
this.outputValue = this.output.outputValue;
|
||||
}
|
||||
|
||||
public virtual void UpdateResult(Vector3 result) {
|
||||
// float d = Vector3.Distance(result, this.outputValue);
|
||||
// if (d < 0.5f) {
|
||||
// //Debug.Log($"insignificant update: {d}");
|
||||
// return;
|
||||
// }
|
||||
// public virtual void UpdateResult(Vector3 result) {
|
||||
// // float d = Vector3.Distance(result, this.outputValue);
|
||||
// // if (d < 0.5f) {
|
||||
// // //Debug.Log($"insignificant update: {d}");
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
this.outputValue = result;
|
||||
foreach (INucleus receiver in this.receivers)
|
||||
receiver.UpdateState();
|
||||
}
|
||||
// this.outputValue = result;
|
||||
// foreach (INucleus receiver in this.receivers)
|
||||
// receiver.UpdateState();
|
||||
// }
|
||||
|
||||
public void UpdateNuclei() {
|
||||
this.stale++;
|
||||
|
||||
@ -473,6 +473,7 @@ public class ClusterInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
private int selectedInputType = 0;
|
||||
void DrawInspector(VisualElement inspectorContainer) {
|
||||
if (inspectorContainer == null)
|
||||
return;
|
||||
@ -491,7 +492,7 @@ public class ClusterInspector : Editor {
|
||||
if (this.currentNucleus == null)
|
||||
return;
|
||||
|
||||
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name);
|
||||
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.GetType().ToString(), this.currentNucleus.name);
|
||||
if (this.currentNucleus is Neuron neuroid) {
|
||||
if (this.currentNucleus is MemoryCell memory) {
|
||||
}
|
||||
@ -551,6 +552,14 @@ public class ClusterInspector : Editor {
|
||||
EditorGUILayout.Space();
|
||||
|
||||
ConnectNucleus(this.cluster, this.currentNucleus);
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Add Input"))
|
||||
AddInput(selectedInputType, this.currentNucleus);
|
||||
string[] options = { "Neuron", "MemoryCell", "Selector", "Cluster" };
|
||||
selectedInputType = EditorGUILayout.Popup(selectedInputType, options);
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (GUILayout.Button("Add Input Neuron"))
|
||||
AddInputNeuron(this.currentNucleus);
|
||||
if (GUILayout.Button("Add Input MemoryCell"))
|
||||
@ -587,6 +596,23 @@ public class ClusterInspector : Editor {
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddInput(int selectedInputType, INucleus nucleus) {
|
||||
switch (selectedInputType) {
|
||||
case 0: // Neuron
|
||||
AddInputNeuron(nucleus);
|
||||
break;
|
||||
case 1: // MemoryCell
|
||||
AddInputMemoryCell(nucleus);
|
||||
break;
|
||||
case 2: // Selector
|
||||
AddSelectorInput(nucleus);
|
||||
break;
|
||||
case 3: // Cluster
|
||||
AddCluster(nucleus);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void AddInputNeuron(INucleus nucleus) {
|
||||
Neuron newNeuroid = new(this.cluster, "New neuron");
|
||||
newNeuroid.AddReceiver(nucleus);
|
||||
@ -609,6 +635,13 @@ public class ClusterInspector : Editor {
|
||||
BuildLayers();
|
||||
}
|
||||
|
||||
protected void AddSelectorInput(INucleus nucleus) {
|
||||
Selector newSelector = new(this.cluster, "New Selector");
|
||||
newSelector.AddReceiver(nucleus);
|
||||
this.currentNucleus = newSelector;
|
||||
BuildLayers();
|
||||
}
|
||||
|
||||
protected virtual void AddInputMemoryCell(INucleus nucleus) {
|
||||
MemoryCell newMemory = new(this.cluster, "New memory cell");
|
||||
newMemory.AddReceiver(nucleus);
|
||||
|
||||
@ -7,6 +7,7 @@ public interface INucleus : IReceptor {
|
||||
|
||||
// Cluster
|
||||
public ClusterPrefab cluster { get; }
|
||||
public Cluster parent { get; }
|
||||
|
||||
// Senders
|
||||
public List<Synapse> synapses { get; }
|
||||
@ -18,8 +19,8 @@ public interface INucleus : IReceptor {
|
||||
|
||||
#region dynamic state
|
||||
|
||||
public void UpdateState();
|
||||
public void UpdateState(float3 inputValue);
|
||||
// public void UpdateState();
|
||||
// public void UpdateState(float3 inputValue);
|
||||
public void UpdateStateIsolated();
|
||||
public void UpdateStateIsolated(float3 inputValue);
|
||||
|
||||
|
||||
@ -29,23 +29,23 @@ public class MemoryCell : Neuron, INucleus {
|
||||
private float3 _memorizedValue;
|
||||
private float _memorizedTime;
|
||||
|
||||
public override void UpdateState(float3 bias) {
|
||||
// A memorycell does not have an activation function
|
||||
float3 result = bias;
|
||||
int n = 0;
|
||||
// public override void UpdateState(float3 bias) {
|
||||
// // A memorycell does not have an activation function
|
||||
// float3 result = bias;
|
||||
// int n = 0;
|
||||
|
||||
//Applying the weight factgors
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
result += synapse.weight * synapse.nucleus.outputValue;
|
||||
if (lengthsq(synapse.nucleus.outputValue) != 0)
|
||||
n++;
|
||||
}
|
||||
// //Applying the weight factgors
|
||||
// foreach (Synapse synapse in this.synapses) {
|
||||
// result += synapse.weight * synapse.nucleus.outputValue;
|
||||
// if (lengthsq(synapse.nucleus.outputValue) != 0)
|
||||
// n++;
|
||||
// }
|
||||
|
||||
if (this.average)
|
||||
result /= n;
|
||||
// if (this.average)
|
||||
// result /= n;
|
||||
|
||||
UpdateResult(result);
|
||||
}
|
||||
// UpdateResult(result);
|
||||
// }
|
||||
|
||||
public override void UpdateStateIsolated() {
|
||||
float3 bias = new(0, 0, 0);
|
||||
@ -73,22 +73,22 @@ public class MemoryCell : Neuron, INucleus {
|
||||
this._memorizedTime = Time.time;
|
||||
}
|
||||
|
||||
public override void UpdateResult(Vector3 result) {
|
||||
// output value is the previous value
|
||||
// if (this.deltaValue) {
|
||||
// float deltaTime = Time.time - this._memorizedTime;
|
||||
// this._outputValue = this._memorizedValue * deltaTime;
|
||||
// }
|
||||
//else
|
||||
this.outputValue = this._memorizedValue;
|
||||
// public override void UpdateResult(Vector3 result) {
|
||||
// // output value is the previous value
|
||||
// // if (this.deltaValue) {
|
||||
// // float deltaTime = Time.time - this._memorizedTime;
|
||||
// // this._outputValue = this._memorizedValue * deltaTime;
|
||||
// // }
|
||||
// //else
|
||||
// this.outputValue = this._memorizedValue;
|
||||
|
||||
// Store the result for the next time
|
||||
this._memorizedValue = result;
|
||||
this._memorizedTime = Time.time;
|
||||
// // Store the result for the next time
|
||||
// this._memorizedValue = result;
|
||||
// this._memorizedTime = Time.time;
|
||||
|
||||
foreach (INucleus receiver in this.receivers)
|
||||
receiver.UpdateState();
|
||||
}
|
||||
// foreach (INucleus receiver in this.receivers)
|
||||
// receiver.UpdateState();
|
||||
// }
|
||||
|
||||
#endregion State
|
||||
}
|
||||
|
||||
130
Neuron.cs
130
Neuron.cs
@ -191,35 +191,7 @@ public class Neuron : INucleus {
|
||||
};
|
||||
return clone;
|
||||
}
|
||||
public virtual IReceptor ShallowCloneTo(ClusterPrefab newParent) {
|
||||
Neuron clone = new(newParent, this.name) {
|
||||
array = this.array,
|
||||
curve = this.curve,
|
||||
curvePreset = this.curvePreset,
|
||||
curveMax = this.curveMax,
|
||||
average = this.average
|
||||
};
|
||||
return clone;
|
||||
}
|
||||
|
||||
public virtual IReceptor CloneTo(ClusterPrefab parent) {
|
||||
Neuron clone = new(parent, this.name) {
|
||||
array = this.array,
|
||||
curve = this.curve,
|
||||
curvePreset = this.curvePreset,
|
||||
curveMax = this.curveMax,
|
||||
average = this.average
|
||||
};
|
||||
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
|
||||
clonedSynapse.weight = synapse.weight;
|
||||
}
|
||||
foreach (INucleus receiver in this.receivers) {
|
||||
clone.AddReceiver(receiver);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
public virtual IReceptor Clone() {
|
||||
Neuron clone = new(this.cluster, this.name) {
|
||||
array = this.array,
|
||||
@ -281,48 +253,48 @@ public class Neuron : INucleus {
|
||||
return synapse;
|
||||
}
|
||||
|
||||
public virtual void UpdateState() {
|
||||
//UpdateState(new float3(0, 0, 0));
|
||||
this.parent?.UpdateState();
|
||||
}
|
||||
// public virtual void UpdateState() {
|
||||
// //UpdateState(new float3(0, 0, 0));
|
||||
// this.parent?.UpdateState();
|
||||
// }
|
||||
|
||||
public virtual void UpdateState(float3 inputValue) {
|
||||
float3 sum = inputValue;
|
||||
int n = 0;
|
||||
// public virtual void UpdateState(float3 inputValue) {
|
||||
// float3 sum = inputValue;
|
||||
// int n = 0;
|
||||
|
||||
//Applying the weight factgors
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
sum += synapse.weight * synapse.nucleus.outputValue;
|
||||
// //Applying the weight factgors
|
||||
// foreach (Synapse synapse in this.synapses) {
|
||||
// sum += synapse.weight * synapse.nucleus.outputValue;
|
||||
|
||||
// Perhaps synapses should be removed when the output value goes to 0....
|
||||
if (lengthsq(synapse.nucleus.outputValue) != 0)
|
||||
n++;
|
||||
}
|
||||
if (this.average && n > 0)
|
||||
sum /= n;
|
||||
// // Perhaps synapses should be removed when the output value goes to 0....
|
||||
// if (lengthsq(synapse.nucleus.outputValue) != 0)
|
||||
// n++;
|
||||
// }
|
||||
// if (this.average && n > 0)
|
||||
// sum /= n;
|
||||
|
||||
// Activation function
|
||||
Vector3 result;
|
||||
switch (this.curvePreset) {
|
||||
case CurvePresets.Linear:
|
||||
result = sum;
|
||||
break;
|
||||
case CurvePresets.Sqrt:
|
||||
result = normalize(sum) * System.MathF.Sqrt(length(sum));
|
||||
break;
|
||||
case CurvePresets.Power:
|
||||
result = normalize(sum) * System.MathF.Pow(length(sum), 2);
|
||||
break;
|
||||
case CurvePresets.Reciprocal:
|
||||
result = normalize(sum) * (1 / length(sum));
|
||||
break;
|
||||
default:
|
||||
float activatedValue = this.curve.Evaluate(length(sum));
|
||||
result = normalize(sum) * activatedValue;
|
||||
break;
|
||||
}
|
||||
UpdateResult(result);
|
||||
}
|
||||
// // Activation function
|
||||
// Vector3 result;
|
||||
// switch (this.curvePreset) {
|
||||
// case CurvePresets.Linear:
|
||||
// result = sum;
|
||||
// break;
|
||||
// case CurvePresets.Sqrt:
|
||||
// result = normalize(sum) * System.MathF.Sqrt(length(sum));
|
||||
// break;
|
||||
// case CurvePresets.Power:
|
||||
// result = normalize(sum) * System.MathF.Pow(length(sum), 2);
|
||||
// break;
|
||||
// case CurvePresets.Reciprocal:
|
||||
// result = normalize(sum) * (1 / length(sum));
|
||||
// break;
|
||||
// default:
|
||||
// float activatedValue = this.curve.Evaluate(length(sum));
|
||||
// result = normalize(sum) * activatedValue;
|
||||
// break;
|
||||
// }
|
||||
// UpdateResult(result);
|
||||
// }
|
||||
|
||||
public virtual void UpdateStateIsolated() {
|
||||
UpdateStateIsolated(new float3(0, 0, 0));
|
||||
@ -368,20 +340,20 @@ public class Neuron : INucleus {
|
||||
this.outputValue = result;
|
||||
}
|
||||
|
||||
public virtual void UpdateResult(Vector3 result) {
|
||||
// float d = Vector3.Distance(result, this.outputValue);
|
||||
// if (d < 0.5f) {
|
||||
// //Debug.Log($"insignificant update: {d}");
|
||||
// return;
|
||||
// }
|
||||
// public virtual void UpdateResult(Vector3 result) {
|
||||
// // float d = Vector3.Distance(result, this.outputValue);
|
||||
// // if (d < 0.5f) {
|
||||
// // //Debug.Log($"insignificant update: {d}");
|
||||
// // return;
|
||||
// // }
|
||||
|
||||
this.outputValue = result;
|
||||
if (lengthsq(outputValue) != 0) {
|
||||
Debug.Log($"{this.parent.name}.{this.name}: {this.outputValue}");
|
||||
}
|
||||
// this.outputValue = result;
|
||||
// if (lengthsq(outputValue) != 0) {
|
||||
// Debug.Log($"{this.parent.name}.{this.name}: {this.outputValue}");
|
||||
// }
|
||||
|
||||
foreach (INucleus receiver in this.receivers)
|
||||
receiver.UpdateState();
|
||||
// foreach (INucleus receiver in this.receivers)
|
||||
// receiver.UpdateState();
|
||||
|
||||
}
|
||||
// }
|
||||
}
|
||||
@ -179,7 +179,7 @@ public class Receptor : IReceptor {
|
||||
thingIds[selectedReceiverIx] = thingId;
|
||||
// if (thingName != null)
|
||||
// selectedReceiver.nucleus.name = selectedReceiver.nucleus.baseName + " " + thingName;
|
||||
selectedReceiver.UpdateState();
|
||||
selectedReceiver.parent.UpdateStateIsolated();
|
||||
}
|
||||
|
||||
public void UpdateNuclei() {
|
||||
|
||||
@ -9,8 +9,8 @@ public class SelectorBrain : NanoBrain {
|
||||
public Receptor receptor2;
|
||||
|
||||
protected void Awake() {
|
||||
receptor1 = Receptor.CreateReceptor(this.brain, "Input 1");
|
||||
receptor2 = Receptor.CreateReceptor(this.brain, "Input 2");
|
||||
receptor1 = Receptor.CreateReceptor(this.brain, "Selector");
|
||||
receptor2 = Receptor.CreateReceptor(this.brain, "Selector");
|
||||
}
|
||||
|
||||
protected void Update() {
|
||||
|
||||
16
Selector.cs
16
Selector.cs
@ -1,8 +1,22 @@
|
||||
using System;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
|
||||
[Serializable]
|
||||
public class Selector : Neuron {
|
||||
public Selector(Cluster parent, string name) : base(parent, name) { }
|
||||
public Selector(ClusterPrefab parent, string name) : base(parent, name) {}
|
||||
|
||||
public override IReceptor ShallowCloneTo(Cluster newParent) {
|
||||
Selector clone = new(newParent, this.name) {
|
||||
array = this.array,
|
||||
curve = this.curve,
|
||||
curvePreset = this.curvePreset,
|
||||
curveMax = this.curveMax,
|
||||
average = this.average
|
||||
};
|
||||
return clone;
|
||||
}
|
||||
|
||||
public override void UpdateStateIsolated(float3 bias) {
|
||||
float3 max = bias;
|
||||
@ -11,7 +25,7 @@ public class Selector : Neuron {
|
||||
//Applying the weight factors
|
||||
foreach (Synapse synapse in this.synapses) {
|
||||
float3 input = synapse.weight * synapse.nucleus.outputValue;
|
||||
|
||||
|
||||
float inputSqrlength = lengthsq(input);
|
||||
if (inputSqrlength > maxSqrLength) {
|
||||
max = input;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user