*
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Agent : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Vector2 ImageSpacePosition {
|
||||
get {
|
||||
var thisTransform = GetComponent<RectTransform>();
|
||||
return new Vector3(thisTransform.anchoredPosition.x, -thisTransform.anchoredPosition.y);
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2 ImageSpacePositionNormalized {
|
||||
get {
|
||||
var localPos = ImageSpacePosition;
|
||||
var parentTransform = transform.parent.GetComponent<RectTransform>();
|
||||
var parentSize = parentTransform.rect.size;
|
||||
return new Vector2(localPos.x / parentSize.x, localPos.y / parentSize.y);
|
||||
}
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
if (transform.hasChanged) {
|
||||
|
||||
Debug.Log(ImageSpacePositionNormalized);
|
||||
transform.hasChanged = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7702dc5fe2d825345aa9e1fad9aa9f0b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,174 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class Perceptron : MonoBehaviour
|
||||
{
|
||||
public List<Layer> Layers;
|
||||
public List<Synapses> _synapses;
|
||||
|
||||
[System.Serializable]
|
||||
public class Layer {
|
||||
public int Size;
|
||||
public bool AddOffsetNeuron;
|
||||
public int TotalSize {
|
||||
get {
|
||||
return AddOffsetNeuron ? (Size + 1) : Size;
|
||||
}
|
||||
}
|
||||
public void Init() {
|
||||
Values = new float[TotalSize];
|
||||
Errors = new float[TotalSize];
|
||||
|
||||
|
||||
if (AddOffsetNeuron) {
|
||||
Values[Values.Length - 1] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
public float[] Values;
|
||||
public float[] Errors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class Synapses {
|
||||
public float[,] Values;
|
||||
public int InSize;
|
||||
public int OutSize;
|
||||
|
||||
public Synapses(int inSize, int outSize) {
|
||||
InSize = inSize;
|
||||
OutSize = outSize;
|
||||
Values = new float[inSize, outSize];
|
||||
SetRandom();
|
||||
// SetOne();
|
||||
Debug.Log($"Make synapses: {inSize}x{outSize}");
|
||||
}
|
||||
|
||||
public void SetOne() {
|
||||
|
||||
for (int i = 0; i < InSize; ++i) {
|
||||
for (int j = 0; j < OutSize; ++j) {
|
||||
Values[i, j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetRandom() {
|
||||
|
||||
for(int i = 0; i < InSize; ++i) {
|
||||
for (int j = 0; j < OutSize; ++j) {
|
||||
Values[i, j] = UnityEngine.Random.value * 2.0f - 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const float FxCapDerivative = 0.01f;
|
||||
//float Fx(float x) {
|
||||
// if(x > 1.0f) {
|
||||
// return 1.0f + FxCapDerivative * (x - 1.0f);
|
||||
// }else if(x < 0.0f) {
|
||||
// return FxCapDerivative * x;
|
||||
// }
|
||||
// return x;
|
||||
//}
|
||||
//
|
||||
//float FxDerivative(float x) {
|
||||
// if (x > 1.0f) {
|
||||
// return FxCapDerivative;
|
||||
// } else if (x < 0.0f) {
|
||||
// return FxCapDerivative;
|
||||
// }
|
||||
// return 1.0f;
|
||||
//}
|
||||
|
||||
float Fx(float x) {
|
||||
return 1.0f / (1.0f + Mathf.Exp(-x));
|
||||
}
|
||||
|
||||
float FxDerivative(float x) {
|
||||
return x * (1.0f - x);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void PropagateErrors() {
|
||||
for (int inLayerId = Layers.Count - 2; inLayerId >= 0; --inLayerId) {
|
||||
int outLayerId = inLayerId + 1;
|
||||
|
||||
var inLayer = Layers[inLayerId];
|
||||
var outLayer = Layers[outLayerId];
|
||||
var weights = _synapses[inLayerId];
|
||||
|
||||
for(int i = 0; i < inLayer.Size; ++i) {
|
||||
float err = 0.0f;
|
||||
for (int o = 0; o < outLayer.Size; ++o) {
|
||||
err += outLayer.Errors[o] * weights.Values[i, o];
|
||||
}
|
||||
inLayer.Errors[i] = err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RecalculateWeights(float learnRate) {
|
||||
for (int inLayerId = 0; inLayerId < Layers.Count - 1; ++inLayerId) {
|
||||
int outLayerId = inLayerId + 1;
|
||||
|
||||
var inLayer = Layers[inLayerId];
|
||||
var outLayer = Layers[outLayerId];
|
||||
var weights = _synapses[inLayerId];
|
||||
for (int i = 0; i < inLayer.TotalSize; ++i) {
|
||||
|
||||
for (int o = 0; o < outLayer.Size; ++o) {
|
||||
|
||||
weights.Values[i, o] += (learnRate * outLayer.Errors[o]) * FxDerivative(outLayer.Values[o]) * inLayer.Values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CalculateOutputs() {
|
||||
for (int inLayerId = 0; inLayerId < Layers.Count - 1; ++inLayerId) {
|
||||
int outLayerId = inLayerId + 1;
|
||||
|
||||
var inLayer = Layers[inLayerId];
|
||||
var outLayer = Layers[outLayerId];
|
||||
var weights = _synapses[inLayerId];
|
||||
for (int o = 0; o < outLayer.Size; ++o) {
|
||||
|
||||
float sum = 0;
|
||||
for (int i = 0; i < inLayer.TotalSize; ++i) {
|
||||
sum += weights.Values[i, o] * inLayer.Values[i];
|
||||
}
|
||||
outLayer.Values[o] = Fx(sum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Learn(float learnRate) {
|
||||
PropagateErrors();
|
||||
RecalculateWeights(learnRate);
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
foreach(var layer in Layers) {
|
||||
layer.Init();
|
||||
}
|
||||
|
||||
_synapses = new List<Synapses>();
|
||||
for (int i = 0; i < Layers.Count - 1; ++i) {
|
||||
_synapses.Add(new Synapses(Layers[i].TotalSize, Layers[i + 1].Size));
|
||||
}
|
||||
}
|
||||
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fad4601af2d840146a88aefa97c2947a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,145 @@
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e6015504cae23b14398f2ee5705f952a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ea315d0fd7389c41b19996891e99ae3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9fc0d4010bbf28b4594072e72b8655ab
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,80 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 8
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_Name: TextureView
|
||||
m_Shader: {fileID: 4800000, guid: b86c37b293849804e88fd1a08722b27e, type: 3}
|
||||
m_ValidKeywords: []
|
||||
m_InvalidKeywords: []
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Ints: []
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _Metallic: 0
|
||||
- _Mode: 0
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
m_BuildTextureStacks: []
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4a532ce263722b948ac9761044f13463
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,58 @@
|
||||
Shader "Unlit/TextureView"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
Tags { "RenderType"="Opaque" }
|
||||
LOD 100
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
// make fog work
|
||||
#pragma multi_compile_fog
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
UNITY_FOG_COORDS(1)
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
UNITY_TRANSFER_FOG(o,o.vertex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
// sample the texture
|
||||
fixed4 col = tex2D(_MainTex, i.uv);
|
||||
// apply fog
|
||||
UNITY_APPLY_FOG(i.fogCoord, col);
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b86c37b293849804e88fd1a08722b27e
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user