This commit is contained in:
Pascal Serrarens 2026-05-26 09:02:20 +02:00
parent f8a6f579ea
commit 133804a154
3 changed files with 3 additions and 202 deletions

View File

@ -85,8 +85,6 @@ namespace NanoBrain {
this.parent = parent; this.parent = parent;
this.parent?.nuclei.Add(this); this.parent?.nuclei.Add(this);
ClonePrefab(); ClonePrefab();
// _ = this.inputs;
//this.sortedNuclei = TopologicalSort(this.nuclei);
} }
/// <summary> /// <summary>
@ -102,8 +100,6 @@ namespace NanoBrain {
this.parent = parent.cluster; this.parent = parent.cluster;
ClonePrefab(); ClonePrefab();
// _ = this.inputs;
//this.sortedNuclei = TopologicalSort(this.nuclei);
} }
/// <summary> /// <summary>
@ -169,15 +165,11 @@ namespace NanoBrain {
} }
} }
//if (Application.isPlaying) {
// Only create cluster siblings at runtime
foreach (Nucleus clonedNucleus in clonedNuclei) { foreach (Nucleus clonedNucleus in clonedNuclei) {
if (clonedNucleus is not Cluster clonedCluster) if (clonedNucleus is not Cluster clonedCluster)
continue; continue;
List<Cluster> siblings = new() { List<Cluster> siblings = new() { clonedCluster };
clonedCluster
};
for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) { for (int instanceIx = 1; instanceIx < clonedCluster.instanceCount; instanceIx++) {
// Create another sibling // Create another sibling
Cluster sibling = new(clonedCluster.prefab, this) { Cluster sibling = new(clonedCluster.prefab, this) {
@ -186,7 +178,7 @@ namespace NanoBrain {
instanceCount = this.instanceCount, instanceCount = this.instanceCount,
}; };
siblings.Add(sibling); siblings.Add(sibling);
CopyAllExternalReceivers(clonedCluster, sibling, clonedCluster.prefab, this); CopyAllExternalReceivers(clonedCluster, sibling, this);
} }
Cluster[] siblingClusters = siblings.ToArray(); Cluster[] siblingClusters = siblings.ToArray();
foreach (Cluster sibling in siblings) foreach (Cluster sibling in siblings)
@ -198,7 +190,6 @@ namespace NanoBrain {
if (clonedNucleus is not Cluster) if (clonedNucleus is not Cluster)
clonedNucleus.UpdateStateIsolated(); clonedNucleus.UpdateStateIsolated();
} }
//}
} }
/// \copydoc NanoBrain::Nucleus::ShallowCloneTo /// \copydoc NanoBrain::Nucleus::ShallowCloneTo
@ -209,13 +200,11 @@ namespace NanoBrain {
parent = this.parent, parent = this.parent,
instanceCount = this.instanceCount, instanceCount = this.instanceCount,
}; };
// Somehow siblingClusters should be cloned too. Believe I do this in ClonePrefab right now.
return clone; return clone;
} }
private static void CopyAllExternalReceivers(Cluster sourceCluster, Cluster sibling, ClusterPrefab prefabParent, Cluster clonedParent) { private static void CopyAllExternalReceivers(Cluster sourceCluster, Cluster sibling, Cluster clonedParent) {
for (int nucleusIx = 0; nucleusIx < sourceCluster.nuclei.Count; nucleusIx++) { for (int nucleusIx = 0; nucleusIx < sourceCluster.nuclei.Count; nucleusIx++) {
Nucleus sourceNucleus = sourceCluster.nuclei[nucleusIx]; Nucleus sourceNucleus = sourceCluster.nuclei[nucleusIx];
if (sourceNucleus is not Neuron sourceNeuron) if (sourceNucleus is not Neuron sourceNeuron)
@ -517,43 +506,6 @@ namespace NanoBrain {
return false; return false;
} }
/// <summary>
/// Get a nucleus in this cluster
/// </summary>
/// <param name="nucleusName">The name of the nucleus to find</param>
/// <returns>The found nucleus or null when it is not found</returns>
// public Nucleus GetNucleus(string nucleusName) {
// int dotPosition = nucleusName.IndexOf('.');
// if (dotPosition >= 0) {
// string clusterName = nucleusName[..dotPosition];
// string clusterName0 = clusterName + ": 0";
// foreach (Nucleus nucleus in this.nuclei) {
// if (nucleus is Cluster cluster) {
// if (cluster.name == clusterName || cluster.name == clusterName0) {
// // cluster.CheckInstances();
// string subNucleusName = nucleusName[(dotPosition + 1)..];
// return cluster.GetNucleus(subNucleusName);
// }
// }
// }
// return null;
// }
// else {
// string nucleusName0 = nucleusName + ": 0";
// foreach (Nucleus nucleus in this.nuclei) {
// if (nucleus is Cluster cluster) {
// if (nucleus.name == nucleusName || nucleus.name == nucleusName0) {
// // cluster.CheckInstances();
// return nucleus;
// }
// }
// else if (nucleus.name == nucleusName)
// return nucleus;
// }
// return null;
// }
// }
/// <summary> /// <summary>
/// Get a neuron in this cluster /// Get a neuron in this cluster
/// </summary> /// </summary>

View File

@ -144,146 +144,6 @@ namespace NanoBrain {
//this.curve = GenerateCurve(); //this.curve = GenerateCurve();
} }
} }
/// <summary>
/// The curve representing the activation function
/// </summary>
// [HideInInspector]
// public AnimationCurve curve;
/// <summary>
/// The maximum value of the curve
/// </summary>
// [HideInInspector]
// public float curveMax = 1.0f;
/// <summary>
/// Generate the curve for the current activation function
/// </summary>
/// <returns>The curve </returns>
// public AnimationCurve GenerateCurve() {
// switch (this.activator) {
// case ActivationType.Linear:
// this.curveMax = 1;
// return Presets.Linear(1);
// case ActivationType.Power:
// this.curveMax = 1;
// return Presets.Power(2.0f, 1);
// case ActivationType.Sqrt:
// this.curveMax = 1;
// return Presets.Power(0.5f, 1);
// case ActivationType.Reciprocal:
// this.curveMax = 1 / 0.01f * 1;
// return Presets.Reciprocal(1);
// case ActivationType.Tanh:
// this.curveMax = 1;
// return Presets.Tanh(1);
// case ActivationType.Binary:
// this.curveMax = 1;
// return Presets.Binary();
// case ActivationType.Normalized:
// this.curveMax = 1;
// return Presets.Binary();
// default:
// this.curveMax = 1;
// return this.curve;
// }
// }
/// <summary>
/// The curve presets for the activation functions
/// </summary>
public static class Presets {
/// <summary>
/// The number of samples in the curve
/// </summary>
private const int samples = 32;
/// <summary>
/// Generate a curve for the linear activation function
/// </summary>
/// <param name="weight">The maximum value for the function</param>
/// <returns>The curve preset</returns>
public static AnimationCurve Linear(float weight) {
return AnimationCurve.Linear(0f, 0f, 1000f, weight * 1000);
}
/// <summary>
/// Generate a curve for the power activation function
/// </summary>
/// <param name="exponent">The exponent of the power function</param>
/// <param name="weight">The maximum value for the function</param>
/// <returns>The curve preset</returns>
public static AnimationCurve Power(float exponent, float weight) {
// build keyframes
Keyframe[] keys = new Keyframe[samples];
for (int i = 0; i < samples; i++) {
float t = i / (float)(samples - 1);
float v = Mathf.Pow(t, exponent) * weight;
keys[i] = new Keyframe(t, v);
}
AnimationCurve curve = new(keys);
// set tangent modes for each key to Auto (smooth). Use Linear if you prefer straight segments.
for (int i = 0; i < curve.length; i++) {
AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Auto);
AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Auto);
}
return curve;
}
/// <summary>
/// Generate a curve for the reciprocal activation function
/// </summary>
/// <param name="weight">The maximum value for the function</param>
/// <returns>The curve preset</returns>
public static AnimationCurve Reciprocal(float weight) {
int samples = 128;
float xMin = 0.001f;
float xMax = 1;
var keys = new Keyframe[samples];
for (int i = 0; i < samples; i++) {
float t = i / (float)(samples - 1);
float x = Mathf.Lerp(xMin, xMax, t);
float y = 1f / x * weight;
keys[i] = new Keyframe(x, y);
}
var curve = new AnimationCurve(keys);
for (int i = 0; i < curve.length; i++) {
AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
}
return curve;
}
/// <summary>
/// Generate a curve for the tanh activation function
/// </summary>
/// <param name="weight">The maximum value for the function</param>
/// <returns>The curve preset</returns>
public static AnimationCurve Tanh(float weight) {
//int samples = 128;
float xMin = 0.001f;
float xMax = 1;
var keys = new Keyframe[samples];
for (int i = 0; i < samples; i++) {
float t = i / (float)(samples - 1);
float x = Mathf.Lerp(xMin, xMax, t);
float y = MathF.Tanh(x * weight);
keys[i] = new Keyframe(x, y);
}
var curve = new AnimationCurve(keys);
for (int i = 0; i < curve.length; i++) {
AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
}
return curve;
}
/// <summary>
/// Generate a curve for the binary activation function
/// </summary>
/// <returns>The curve preset</returns>
public static AnimationCurve Binary() {
return AnimationCurve.Linear(0, 0, 1, 1);
}
}
#endregion Serialization #endregion Serialization
@ -401,9 +261,7 @@ namespace NanoBrain {
clone.bias = this.bias; clone.bias = this.bias;
clone.persistOutput = this.persistOutput; clone.persistOutput = this.persistOutput;
clone.combinator = this.combinator; clone.combinator = this.combinator;
// clone.curve = this.curve;
clone.activator = this.activator; clone.activator = this.activator;
// clone.curveMax = this.curveMax;
clone.breakOnUpdate = this.breakOnUpdate; clone.breakOnUpdate = this.breakOnUpdate;
} }

View File

@ -17,15 +17,6 @@ namespace NanoBrain.Unity {
//[HideInInspector] //[HideInInspector]
public int version; public int version;
/// <summary>
/// Retrieve a nucleus in this cluster
/// </summary>
/// <param name="nucleusName">The name of the nucleus</param>
/// <returns>The Nucleus with the given name or null if no such Nucleus could be found</returns>
// public Nucleus GetNucleus(string nucleusName) {
// return cluster.GetNucleus(nucleusName);
// }
/// <summary> /// <summary>
/// Call this function to ensure that there is at least one nucleus /// Call this function to ensure that there is at least one nucleus
/// </summary> /// </summary>