Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- namespace NewNet
- {
- class FNeuron
- {
- public bool[] friends;
- public double[] w;
- public double cur_sum;
- public double storage;
- static Random rnd = new Random();
- public FNeuron(int netSize)
- {
- this.w = new double[netSize];
- this.friends = new bool[netSize];
- this.cur_sum = 0;
- }
- public void AddLink(int j)
- {
- w[j] = (double)rnd.Next(0, 100) / 1000;
- friends[j] = true;
- }
- }
- class NeuralNet
- {
- FNeuron[] net;
- double[] delta;
- int I, N, K;
- int netSize;
- double speed, eps;
- double feedforward_prob = 0.75;
- double feedback_prob = 0.4;
- double selfconn_prob = 0.3;
- double new_link_prob = 0.0005;
- Random rnd = new Random();
- public NeuralNet(int I, int N, int K, double speed, double eps)
- {
- this.I = I;
- this.N = N;
- this.K = K;
- this.netSize = I + N + K;
- this.net = new FNeuron[netSize];
- this.speed = speed;
- this.eps = eps;
- for (int i = 0; i < netSize; i++)
- net[i] = new FNeuron(netSize);
- this.delta = new double[net.Length];
- GenerateNet();
- }
- private void GenerateNet()
- {
- for (int i = 0; i < I + N; i++)
- for (int j = I; j < net.Length; j++)
- {
- double p = (double)rnd.Next(0, 1000) / 1000;
- if (p <= feedforward_prob && i < j)
- net[i].AddLink(j);
- }
- for (int i = I + N + K - 1; i >= 0; i--)
- for (int j = 0; j < net.Length; j++)
- {
- double p = (double)rnd.Next(0, 1000) / 1000;
- if (p <= feedback_prob && i > j)
- net[i].AddLink(j);
- }
- for (int i = I, j = I; i < I + N; i++, j++)
- {
- double p = (double)rnd.Next(0, 1000) / 1000;
- if (p <= selfconn_prob && i == j)
- net[i].AddLink(j);
- }
- }
- private static double Sigmoid(double x)
- {
- return
- 1 / (1 + Math.Pow(Math.E, -x));
- }
- public double[] Compute(double[] vector)
- {
- for (int i = 0; i < net.Length; i++)
- net[i].cur_sum = 0;
- for (int i = 0; i < vector.Length; i++)
- net[i].cur_sum = vector[i];
- for (int i = I; i < net.Length; i++)
- {
- double val = 0; double tmp = 0;
- for (int j = 0; j < net.Length; j++)
- {
- if (net[j].friends[i] && (j < i))
- val += net[j].w[i] * net[j].cur_sum;
- else if (net[j].friends[i] && (j >= i))
- tmp += net[j].w[i] * net[j].cur_sum;
- }
- net[i].cur_sum = Sigmoid(val) + net[i].storage;
- net[i].storage = tmp;
- }
- double[] result = new double[K];
- for (int i = 0; i < K; i++)
- result[i] = net[I + N + i].cur_sum;
- return result;
- }
- private void BackPropagation(double[] vector, double[] optim)
- {
- Compute(vector);
- for (int i = I + N; i < net.Length; i++)
- {
- double yi = net[i].cur_sum;
- double val = 0;
- for (int j = 0; j < net.Length; j++)
- if (net[i].friends[j])
- val += delta[j] * net[i].w[j];
- delta[i] = ((optim[i - I - N] - yi) + val) * yi * (1 - yi);
- for (int j = 0; j < net.Length; j++)
- if (net[j].friends[i])
- net[j].w[i] += speed * delta[i] * net[j].cur_sum;
- }
- for (int i = I + N - 1; i >= I; i--)
- {
- double val = 0;
- for (int j = 0; j < net.Length; j++)
- if (net[i].friends[j])
- val += delta[j] * net[i].w[j];
- double yi = net[i].cur_sum;
- delta[i] = val * yi * (1 - yi);
- for (int j = 0; j < net.Length; j++)
- if (net[j].friends[i])
- net[j].w[i] += speed * delta[i] * net[j].cur_sum;
- }
- }
- private bool IsLearned(List<double[]> y, List<double[]> opt)
- {
- double sum = 0; int n = y[0].Length;
- for (int q = 0; q < y.Count; q++)
- for (int i = 0; i < n; i++)
- sum += (opt[q][i] - y[q][i]) * (opt[q][i] - y[q][i]);
- if (sum >= eps) return false;
- return true;
- }
- public int Training(List<double[]> vectors, List<double[]> opt, int maxIter, bool exit_on_epochs)
- {
- for (int i = 0; i < delta.Length; i++)
- delta[i] = 0;
- List<double[]> y = new List<double[]>();
- for (int i = 0; i < vectors.Count; i++)
- y.Add(Compute(vectors[i]));
- int cur_epoch = 0;
- while (!IsLearned(y, opt))
- {
- cur_epoch++;
- if ((cur_epoch >= maxIter) && exit_on_epochs)
- return cur_epoch;
- for (int i = 0; i < vectors.Count; i++)
- BackPropagation(vectors[i], opt[i]);
- for (int i = 0; i < vectors.Count; i++)
- y[i] = Compute(vectors[i]);
- Console.WriteLine(cur_epoch);
- }
- New_Link(); return cur_epoch;
- }
- public void New_Link()
- {
- double p = (double) rnd.Next(0, 10000) / 100000;
- if (p <= new_link_prob)
- {
- for (int i = 0; i < net.Length; i++)
- for (int j = 0; j < net.Length; j++)
- if (!net[i].friends[j])
- {
- net[i].AddLink(j);
- return;
- }
- }
- }
- public void PrintLinks()
- {
- for (int i = 0; i < netSize; i++)
- {
- for (int j = 0; j < netSize; j++)
- {
- if (net[i].friends[j]) Console.Write("{0} ", 1);
- else Console.Write("{0} ", 0);
- }
- Console.WriteLine();
- }
- }
- }
- class Program
- {
- static void Print(double[] d)
- {
- for (int i = 0; i < d.Length; i++)
- Console.WriteLine(d[i]);
- }
- static void Main(string[] args)
- {
- NeuralNet net = new NeuralNet(2, 10, 1, 0.3, 0.01);
- List<double[]> vec = new List<double[]>();
- List<double[]> res = new List<double[]>();
- for (int i = 0; i < 10; i++)
- for (int j = 0; j < 10; j++)
- {
- vec.Add(new double[] { i, j });
- if (i == j) res.Add(new double[] { 1 });
- else res.Add(new double[] { 0 });
- }
- int a = net.Training(vec, res, 20000, false);
- for (int i = 0; i < 15; i++)
- for (int j = 0; j < 15; j++)
- {
- Console.Write(i + " " + j + " ");
- Print(net.Compute(new double[] { i, j }));
- }
- Console.WriteLine(a);
- net.PrintLinks();
- }
- }
- }
Add Comment
Please, Sign In to add comment