Archived
Private
Public Access
1
0
This repository has been archived on 2026-02-04. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
ProjectBackup/Unity/NeuralNetworkTest/Assets/Scripts/NeuralNetwork.cs
2022-11-12 13:10:03 +01:00

171 lines
5.2 KiB
C#

using System;
using System.Collections.Generic;
using Random = UnityEngine.Random;
public class NeuralNetwork : IComparable<NeuralNetwork> {
private int[] _layers; //layers of the neural network
private float[][] _neurons; //neurons of the neural network
public float[][][] _weights; //weights of the neural network
private float _score; //score of the neural network
/// <summary>
/// Creates a new neural network with the given layers
/// </summary>
/// <param name="layers">The layers with the count of the individual neurons</param>
public NeuralNetwork(in int[] layers) {
_layers = new int[layers.Length];
for (int i = 0; i < layers.Length; i++) {
_layers[i] = layers[i];
}
InitializeNeurons();
InitializeWeights();
}
/// <summary>
/// Copy a NeuralNetwork
/// </summary>
/// <param name="network">The NeuralNetwork you wanna copy</param>
public NeuralNetwork(in NeuralNetwork network) {
_layers = new int[network._layers.Length];
for (var i = 0; i < network._layers.Length; i++) {
_layers[i] = network._layers[i];
}
InitializeNeurons();
CopyWeights(network._weights);
}
/// <summary>
/// Calculate output based on ihe given input
/// </summary>
/// <param name="inputs">The values at the first layer</param>
/// <returns></returns>
public float[] FeedForward(in float[] inputs) {
for (int i = 0; i < inputs.Length; i++) {
_neurons[0][i] = inputs[i];
}
for (int i = 1; i < _layers.Length; i++) {
for (int j = 0; j < _neurons[i].Length; j++) {
float value = 0.25f;
for (int k = 0; k < _neurons[i - 1].Length; k++) {
value += _weights[i - 1][j][k] * _neurons[i - 1][k];
}
_neurons[i][j] = (float)Math.Tan(value);
}
}
return _neurons[_neurons.Length - 1];
}
/// <summary>
/// Randomize the weights of the neural network
/// </summary>
public void Mutate() {
for (int i = 0; i < _weights.Length; i++) {
for (int j = 0; j < _weights[i].Length; j++) {
for (int k = 0; k < _weights[i][j].Length; k++) {
float weight = _weights[i][j][k];
float random = Random.value * 100.0f;
switch (random) {
case 2.0f:
weight *= -1;
break;
case 4.0f:
weight = Random.Range(-0.5f, 0.5f);
break;
case 6.0f:
weight *= Random.Range(0.0f, 1.0f) + 1;
break;
case 8.0f:
weight *= Random.Range(0.0f, 1.0f);
break;
}
_weights[i][j][k] = weight;
}
}
}
}
public void AddScore(in float score) => _score += score;
public void SetScore(in float score) => _score = score;
public float GetScore() => _score;
private void InitializeNeurons() {
List<float[]> neurons = new List<float[]>();
for (int i = 0; i < _layers.Length; i++) {
neurons.Add(new float[_layers[i]]);
}
_neurons = neurons.ToArray();
}
private void InitializeWeights() {
List<float[][]> weights = new List<float[][]>();
for (int i = 1; i < _layers.Length; i++) {
List<float[]> layerWeights = new List<float[]>();
int neuronsInPreviousLayer = _layers[i - 1];
for (int j = 0; j < _neurons[i].Length; j++) {
float[] neuronWeights = new float[neuronsInPreviousLayer];
for (int k = 0; k < neuronsInPreviousLayer; k++) {
neuronWeights[k] = Random.value - 0.5f;
}
layerWeights.Add(neuronWeights);
}
weights.Add(layerWeights.ToArray());
}
_weights = weights.ToArray();
}
private void CopyWeights(in float[][][] weights) {
_weights = new float[weights.Length][][];
for (int i = 0; i < weights.Length; i++) {
_weights[i] = new float[weights[i].Length][];
for (int j = 0; j < weights[i].Length; j++) {
_weights[i][j] = new float[weights[i][j].Length];
for (int k = 0; k < weights[i][j].Length; k++) {
_weights[i][j][k] = weights[i][j][k];
}
}
}
}
public int CompareTo(NeuralNetwork other) {
if (other == null) {
return 1;
}
if (other._score > _score) {
return -1;
}
if (other._score < _score) {
return 1;
}
return 0;
}
}