Multiple array variable

Hello! I am trying to make my own Artificial Neural Network like this guy did here: [Youtube Video][1]
It is in Finnish, so no need to watch.

So, his “brain” code was almost 1000 lines long, and it was pretty hard to add more layers and neurons. So I wanted to make more expandable one.

This is a part of original one

// Inputs / Inputit
	private float I1, I2, I3;

// Outputs / Outputit
	private float Sum_01, Sum_02;

	// Mutation rate / Mutaation määrä
	public int mutationRate = 5;

	//weights ----------------------------------------------------------------------------
		
	//Input1
	float W_I1_L1N1;
	float W_I1_L1N2;
	float W_I1_L1N3;
	float W_I1_L1N4;
	float W_I1_L1N5;

And this is mine in works.

// Inputs / Inputit
	float[] I = new float[3];

	// Outputs / Outputit
	float[] Sum_ = new float[2];

	// Layer amount / Layereiden määrä
	[SerializeField]
	private int LayerAmount = 2;

	// Neuron count for each layer / Neuroni määrä jokaiselle layerille
	[SerializeField]
	private int NeuronAmountForEachLayer = 5;

	// Mutation rate / Mutaation määrä
	[SerializeField]
	private int mutationRate = 5;

Now the problem is things like these

void Start(){

		// Start generation and mutation / Alkugenerointi ja mutaatio

		//Mutaatio Input1
		if (Random.Range (0, mutationRate) == 1 || simulationStart == true) {
			W_I1_L1N1 = Random.Range (-1.0f, 1.0f);
		}

	}

And I’d like to use it like this (if it even works as intended)

void Start(){

		// Start generation and mutation / Alkugenerointi ja mutaatio

		//Mutaatio Input1
		if (Random.Range (0, mutationRate) == 1 || simulationStart == true) {
			foreach (float i in I) {
				foreach(int l in LayerAmount){
					foreach(int n in NeuronAmountForEachLayer){
						W_I*_L[l]N[n] = Random.Range (-1.0f, 1.0f);*
  •  			}*
    
  •  		}*
    
  •  	}*
    
  •  }*
    
  • }*
    ( W_I1_L1N1 means Weight of Input 1 to Layer 1’s Neuron 1 )
    I basically want to use better way of setting these, than doing it for every single one.
    It’s hard to explain ANN.
    [1]: - YouTube

This approach for a neuronal network is not very flexible. I just wrote a simple NeuronalNetwork framework which is fully scalable. You can create a neuronal network with as many hidden layers you like in any configuration with a single line of code. The only thing that’s fixed is that each node of one layer is connected to each node of the next layer.

NeuronalNetwork network = new NeuronalNetwork(inputCount, outputCount, hiddenLayer1, hiddenLayer2, ...);

Some examples:

// 2 inputs, 1 outputs, 3 neurons in the first hidden layer, 5 in the second hidden layer and 2 in the third. 
network = new NeuronalNetwork(2, 1, 3, 5, 2);

// 4 inputs, 2 outputs, 5 neurons in the hidden layer
network = new NeuronalNetwork(4, 2, 5);

You can set the inputs with SetInput and read the outputs with GetOutput. Alternatively you can access the input and output layers directly. You have to call “Calculate()” after you set the inputs in order to calculate the output values.

You can easily clone a NeuronalNetwork with the copy constructor:

NeuronalNetwork clone = new NeuronalNetwork( source );

This will duplicate the whole network and copy the weights and settings over. You can call the Mutate method in order to randomly mutate the network. I implemented this the same way as in the source code you’ve linked.

Note: When Mutate is called with a MutationRate of “-1” it will randomize all stats. This is automatically called for new networks.

At the moment it doesn’t have any kind of backpropagation or weight adjustments since the original code only depends on random evolution.

edit

I just implemented two ways of serializing a “NeuronalNetwork”:

  • XML
  • Binary

To serialize a network as an XML string you would do this:

XML

NeuronalNetwork network;

var doc = new System.Xml.XmlDocument(); // new XML document
var nets = doc.AppendChild(doc.CreateElement("Networks")); // add root node
network.Serialize(nets); // serialize the network into the root node
// the following is just converting the XML document into a string
var sb = new System.Text.StringBuilder();
using (var writer = new System.IO.StringWriter(sb))
    doc.Save(writer);
string XMLtext = sb.ToString();

To deserialize you would do:

var doc = new System.Xml.XmlDocument();
doc.LoadXml(text);
var nets = doc["Networks"]; // root node
var node = nets.ChildNodes.Item(0); // get the actual network node
NeuronalNetwork network = new NeuronalNetwork(node);

To serialize it as a byte array you would do:

Binary

NeuronalNetwork network;

byte[] data;
using (var stream = new System.IO.MemoryStream())
using (var writer = new System.IO.BinaryWriter(stream))
{
    network.Serialize(writer);
    data = stream.ToArray();
}

To deserialize:

NeuronalNetwork network;
byte[] data;

using (var stream = new System.IO.MemoryStream(data))
using (var reader = new System.IO.BinaryReader(stream))
{
    network = new NeuronalNetwork(reader);
}

Of course instead of a MemoryStream you could directly use a file stream if you want to read / write to a file.

Likewise the XmlDocument has a Load and Save method which also works with IO streams.

Not sure if this is what you’re looking for:

// Create the jagged array
float[][] input = new float[LayerAmount][];
for (int i = 0; i < LayerAmount; i++)
{
    input *= new float[NeuronAmountForEachLayer];*

}

// Randomize the values
for (int i = 0; i < LayerAmount; i++)
{
for (int j = 0; j < NeuronAmountForEachLayer; j++)
{
input*[j] = Random.Range(-1f, 1f);*
}
}
_*They’re called jagged arrays: Microsoft Learn: Build skills that open doors in your career