Files
NeuralNetworks.Unity/Assets/PointsClassificationTask.cs
T

146 lines
3.7 KiB
C#
Raw Normal View History

2025-05-13 02:53:08 +03:00
using System.Collections;
using System.Collections.Generic;
using UnityEditor.PackageManager;
using UnityEngine;
using UnityEngine.UI;
using static UnityEditor.PlayerSettings;
public class PointsClassificationTask : MonoBehaviour
{
public Perceptron Net;
private Agent[] _class0Agents;
private Agent[] _class1Agents;
public float LearnRate = 0.1f;
public int IterationsPerFrame = 50;
public Texture2D Texture;
struct Color {
public byte a;
public byte r;
public byte g;
public byte b;
public static Color Red {
get {
return new Color() { a = 0xff, r = 0xff, g = 0, b = 0 };
}
}
public static Color Green {
get {
return new Color() { a = 0xff, r = 0x0, g = 0xff, b = 0 };
}
}
}
Color[] colors = new Color[256 * 256];
// Start is called before the first frame update
void Start()
{
var img = GetComponent<Image>();
Texture = new Texture2D(256, 256, TextureFormat.ARGB32, false, true);
img.material.mainTexture = Texture;
for(int i = 0; i < colors.Length; ++i) {
colors[i] = Color.Red;
}
Texture.SetPixelData<Color>(colors, 0);
Texture.Apply();
// img.material = new Material()
int children = transform.childCount;
for(int i = 0; i < children; i++) {
var child = transform.GetChild(i);
if(child.name == "Class0") {
_class0Agents = child.GetComponentsInChildren<Agent>();
Debug.Log($"Add Class0 children: {_class0Agents.Length}");
}else if (child.name == "Class1") {
_class1Agents = child.GetComponentsInChildren<Agent>();
Debug.Log($"Add Class1 children: {_class1Agents.Length}");
}
}
}
// Update is called once per frame
void Update()
{
for(int i = 0; i < IterationsPerFrame; ++i) {
Learn();
}
RepaintTexture();
}
void Learn() {
LearnClass(true);
LearnClass(false);
}
void RepaintTexture() {
var inLayer = Net.Layers[0];
var outLayer = Net.Layers[Net.Layers.Count - 1];
for (int y = 0; y < 256; ++y) {
for (int x = 0; x < 256; ++x) {
inLayer.Values[0] = x / 255.0f;
inLayer.Values[1] = y / 255.0f;
Net.CalculateOutputs();
var c0 = Mathf.Clamp01(outLayer.Values[0]);
var c1 = Mathf.Clamp01(outLayer.Values[1]);
colors[(255-y) * 256 + x] = new Color() { a=0xff, r = (byte)(c1 * 255.0f), g = 0, b = (byte)(c0 * 255.0f) };
}
}
Texture.SetPixelData<Color>(colors, 0);
Texture.Apply();
}
public float Error;
void LearnClass(bool zero) {
var agents = zero ? _class0Agents : _class1Agents;
var inLayer = Net.Layers[0];
var outLayer = Net.Layers[Net.Layers.Count - 1];
float expected0 = zero ? 1 : 0;
float expected1 = zero ? 0 : 1;
for (int i = 0; i < agents.Length; i++) {
var pos = agents[i].ImageSpacePositionNormalized;
inLayer.Values[0] = pos.x;
inLayer.Values[1] = pos.y;
Net.CalculateOutputs();
var e0 = expected0 - outLayer.Values[0];
var e1 = expected1 - outLayer.Values[1];
Error = Mathf.Sqrt(e0 * e0 + e1 * e1);
//if(i == 0)
// Debug.Log($"Error: {Error}");
outLayer.Errors[0] = e0;
outLayer.Errors[1] = e1;
Net.Learn(LearnRate);
}
}
}