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/NeuralNetwork/Assets/Scripts/NeuralNetwork.cs
2023-07-31 21:20:56 +02:00

102 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using Random = UnityEngine.Random;
public sealed class NeuralNetwork : IComparable<NeuralNetwork> {
public float Fitness { get; set; }
private readonly int[] _layers;
private readonly float[][] _neurons;
private float[][][] _weights;
public NeuralNetwork(int[] layers) {
_layers = layers.ToArray();
_neurons = _layers.Select(layer => new float[layer]).ToArray();
InitWeights();
}
public NeuralNetwork(NeuralNetwork network) {
_layers = network._layers.ToArray();
_neurons = _layers.Select(layer => new float[layer]).ToArray();
InitWeights();
CopyWeights(network._weights);
}
private void CopyWeights(float[][][] weights) {
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++) {
_weights[i][j][k] = weights[i][j][k];
}
}
}
}
private void InitWeights() {
var weights = new List<float[][]>();
for (int i = 1; i < _layers.Length; i++) {
var layerWeights = new List<float[]>();
int previousNeurons = _layers[i - 1];
for (int j = 0; j < _neurons[i].Length; j++) {
var neuronWeights = new float[previousNeurons];
for (int k = 0; k < previousNeurons; k++) {
neuronWeights[k] = Random.Range(-0.5f, 0.5f);
}
layerWeights.Add(neuronWeights);
}
weights.Add(layerWeights.ToArray());
}
_weights = weights.ToArray();
}
public float[] FeedForward(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++) {
var 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] = MathF.Tanh(value);
}
}
return _neurons[^1];
}
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++) {
var weight = _weights[i][j][k];
var random = Random.Range(0.0f, 1000.0f);
if (random <= 2.0f) weight *= -1.0f;
else if (random <= 4.0f) weight = Random.Range(-0.5f, 0.5f);
else if (random <= 6.0f) weight *= Random.Range(0.0f, 1.0f) + 1.0f;
else if (random <= 8.0f) weight *= Random.Range(0.0f, 1.0f);
_weights[i][j][k] = weight;
}
}
}
}
public int CompareTo(NeuralNetwork other) {
if (ReferenceEquals(this, other)) return 0;
if (ReferenceEquals(null, other)) return 1;
return Fitness.CompareTo(other.Fitness);
}
}