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