using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace General_Neural_Network
{
class Program
{
static void Main(string[] args)
{
neurone neurone = new neurone();
Console.ReadKey();
}
}
class neurone
{
// System
int contatoreCiclo;
bool flagCiclo;
bool schermo = true; // se true stampa tutto i calcoli e dati del programma
// Struttura neurone
int[] strati = { 2, 2, 2 };
double[][] struttura_neurone;
double[][][] struttura_pesi;
double[][][] es_struttura_pesi;
// Dati neurone
double[] inputs = { 0.05, 0.1 };
double[] targets = { 0.2 , 0.8 };
double learnRate = 0.5;
double[] errore;
double errore_totale = 0;
double[] bias;
int numero_esempi = 4;
int contatore_esempi = 0;
public void nuovo_neurone()
{
}
public void traduttore_segnali()
{
// numeri , simboli , codice ascii
// gestione nuovo,modifica,elimina
}
public void set_neurone ()
{
// struttura_neurone
struttura_neurone = new double[strati.Length][];
for (int j = 0; j < struttura_neurone.Length; j++)
{
struttura_neurone[j] = new double[strati[j]];
}
// Assegnazione input
for (int a = 0; a < struttura_neurone[0].Length; a++)
{
struttura_neurone[0][a] = inputs[a];
}
// -----
// struttura_pesi
Random rand = new Random();
double[] test = new double[] { 0.15, 0.20, 0.25, 0.30, 0.40, 0.45, 0.50, 0.55 };
int contatore = 0;
int swap_1 = 0;
int swap_2 = 1;
struttura_pesi = new double[strati.Length-1][][];
for (int i = 0; i < struttura_pesi.Length; i++)
{
struttura_pesi[i] = new double[strati[swap_2]][];
for (int j = 0; j < struttura_pesi[i].Length; j++)
{
struttura_pesi[i][j] = new double[strati[swap_1]];
for (int k = 0; k < struttura_pesi[i][j].Length; k++)
{
struttura_pesi[i][j][k] = test[contatore];
contatore += 1;
}
}
swap_2 += 1;
swap_1 += 1;
}
// -----
// es_struttura_pesi
contatore = 0;
swap_1 = 0;
swap_2 = 1;
es_struttura_pesi = new double[2][][];
for (int i = 0; i < es_struttura_pesi.Length; i++)
{
es_struttura_pesi[i] = new double[strati[swap_2]][];
for (int j = 0; j < es_struttura_pesi[i].Length; j++)
{
es_struttura_pesi[i][j] = new double[strati[swap_1]];
for (int k = 0; k < es_struttura_pesi[i][j].Length; k++)
{
es_struttura_pesi[i][j][k] = 0;
contatore += 1;
}
}
swap_2 += 1;
swap_1 += 1;
}
// -----
double[] test2 = new double[] { 0.30 , 0.35, 0.60};
int contatore2 = 0;
// bias
bias = new double[strati.Length];
for (int j = 0; j < bias.Length; j++)
{
//bias[j] = rand.NextDouble();
bias[j] = test2[contatore2];
contatore2 += 1;
}
// -----
// errore
errore = new double[struttura_neurone[strati.Length-1].Length];
// -----
}
public void stampa()
{
if (schermo == true)
{
Console.WriteLine("####################### Struttura Rete Neurale #######################");
Console.WriteLine("Struttura_n_strati: " + strati.Length);
for (int a = 0; a < strati.Length; a++)
{
Console.WriteLine("Struttura_size_strato: " + "[" + a + "] = " + strati[a]);
}
Console.WriteLine("Struttura_bias_n: " + bias.Length);
for (int a = 0; a < bias.Length; a++)
{
Console.WriteLine("bias: " + "[" + a + "] = " + bias[a]);
}
for (int a = 0; a < targets.Length; a++)
{
Console.WriteLine("target output: " + "[" + a + "] = " + targets[a]);
}
for (int a = 0; a < errore.Length; a++)
{
Console.WriteLine("errore output: " + "[" + a + "] = " + errore[a]);
}
Console.WriteLine("errore totale: " + errore_totale);
Console.WriteLine("learnRate: " + learnRate);
for (int a = 0; a < struttura_neurone.Length; a++)
{
for (int j = 0; j < struttura_neurone[a].Length; j++)
{
Console.WriteLine("Neurone_valore: " + "[" + a + "]" + "[" + j + "] = " + struttura_neurone[a][j] + "");
}
}
for (int x = 0; x < struttura_pesi.Length; x++)
{
for (int j = 0; j < struttura_pesi[x].Length; j++)
{
for (int c = 0; c < struttura_pesi[x][j].Length; c++)
{
Console.WriteLine("Neurone_peso: " + "[" + x + "]" + "[" + j + "]" + "[" + c + "] = " + struttura_pesi[x][j][c] + "");
}
}
}
for (int x = 0; x < es_struttura_pesi.Length; x++)
{
for (int j = 0; j < es_struttura_pesi[x].Length; j++)
{
for (int c = 0; c < es_struttura_pesi[x][j].Length; c++)
{
Console.WriteLine("Neurone_esempio_peso: " + "[" + x + "]" + "[" + j + "]" + "[" + c + "] = " + es_struttura_pesi[x][j][c] + "");
}
}
}
Console.WriteLine("####################### Struttura Rete Neurale #######################");
} // fine if
}
public double funzione_costo(double previsione,double obiettivo)
{
double calcolo, a, b, c;
a = 1/2 * (previsione - targets[0]);
b = previsione * (1 - previsione) ;
c = 2;
calcolo = a*b*c;
return calcolo ;
}
public void comportamento_neurone()
{
// qunado un neurone non e collegato a nessuno altro neurone viene cancellato
// applicare limiti di memoria e tempo
// collegamento tra neuroni
// gestione nerueoni nuovo,modifica,elimina
}
public void back_propagation()
{
double nuovo_peso;
double e_totale_hx;
errore_totale = 0;
contatore_esempi = 0;
for (int strato = 1; strato < struttura_neurone.Length; strato++)
{
if (schermo == true)
{
Console.WriteLine("///////////////////////////////// BACK PROPAGATION //////////////////////////////////////");
Console.WriteLine("///////////////////////////////// STRATO " + strato + " /////////////////////////////////");
}
for (int neurone = 0; neurone < struttura_neurone[strato].Length; neurone++)
{
nuovo_peso = 0;
e_totale_hx = 0;
errore_totale = 0;
for (int pesi = 0; pesi < struttura_pesi[strato - 1][neurone].Length; pesi++)
{
double derivata_a, derivata_b, derivata_c;
if (strato < strati.Length-1) // calcolo per strato H
{
Console.WriteLine("H");
double a = 0, b = 0, calcolo_a = 0, calcolo_b = 0;
for (int hh = 0; hh < struttura_neurone[strati.Length - 1].Length; hh++)
{
a = -(targets[hh] - struttura_neurone[strati.Length - 1][hh]);
b = struttura_neurone[strati.Length - 1][hh] * (1 - struttura_neurone[strati.Length - 1][hh]);
calcolo_a = a * b;
Console.WriteLine(-(targets[hh] - struttura_neurone[strati.Length - 1][hh]) + " * " + struttura_neurone[strati.Length - 1][hh] * (1 - struttura_neurone[strati.Length - 1][hh]) + " = "+ calcolo_a);
calcolo_b = calcolo_a * struttura_pesi[strato][neurone][pesi];
Console.WriteLine(calcolo_a + " * " + struttura_pesi[strato][neurone][pesi] + " = " + calcolo_b);
errore[hh] = calcolo_b;
errore_totale += calcolo_b;
}
Console.WriteLine(errore_totale);
derivata_a = errore_totale;
derivata_b = struttura_neurone[strati.Length - 2][neurone] * (1 - struttura_neurone[strati.Length - 2][neurone]);
Console.WriteLine("aaa "+struttura_neurone[strati.Length-2][neurone] * (1 - struttura_neurone[strati.Length-2][neurone]));
derivata_c = struttura_neurone[strati.Length - 3][neurone];
e_totale_hx = derivata_a * derivata_b * derivata_c;
if (schermo == true)
{
Console.WriteLine("calcolo : -(target - output) = -(" + targets[neurone] + " - " + struttura_neurone[strati.Length - 1][neurone] + ") = " + derivata_a);
Console.WriteLine("calcolo : output*(1 - output) = " + struttura_neurone[strati.Length - 1][neurone] + " * (1 - " + struttura_neurone[strati.Length - 1][neurone] + ") = " + derivata_b);
Console.WriteLine("calcolo : input = " + derivata_c);
Console.WriteLine("calcolo : " + derivata_a + " * " + derivata_b + " * " + derivata_c + " = " + e_totale_hx);
}
}
if ( strato == strati.Length-1) // calcolo per strato O
{
Console.WriteLine("O");
derivata_a = -(targets[neurone] - struttura_neurone[strati.Length-1][neurone]);
derivata_b = struttura_neurone[strati.Length - 1][neurone] * (1 - struttura_neurone[strati.Length - 1][neurone]);
derivata_c = struttura_neurone[strati.Length - 2][neurone];
//errore[0] = Math.Pow((struttura_neurone[strato - 1][neurone] - targets[0]), 2);
e_totale_hx = derivata_a * derivata_b * derivata_c;
if (schermo == true)
{
Console.WriteLine("calcolo : -(target - output) = -(" + targets[neurone] + " - " + struttura_neurone[strati.Length - 1][neurone] + ") = " + derivata_a);
Console.WriteLine("calcolo : output*(1 - output) = " + struttura_neurone[strati.Length - 1][neurone] + " * (1 - " + struttura_neurone[strati.Length - 1][neurone] + ") = " + derivata_b);
Console.WriteLine("calcolo : input = " + derivata_c);
Console.WriteLine("calcolo : " + derivata_a + " * " + derivata_b + " * " + derivata_c + " = " + e_totale_hx);
}
}
nuovo_peso = struttura_pesi[strato-1][neurone][pesi] - learnRate * e_totale_hx;
errore_totale += errore[neurone];
if (schermo == true)
{
Console.WriteLine("calcolo : peso: " + struttura_pesi[strato-1][neurone][pesi] + " - LeanRate: " + learnRate + " * costo/peso: " + e_totale_hx + " = back_propagation: " + nuovo_peso);
}
struttura_pesi[strato-1][neurone][pesi] = nuovo_peso;
es_struttura_pesi[contatore_esempi][neurone][pesi] = nuovo_peso;
}//fine for pesi
if (schermo == true)
{
//Console.WriteLine("risultato aggiornato:" + "[" + strato + "][" + neurone + "] = " + tot + " + " + bias + " = " + totale);
Console.WriteLine("----------------------------------------------------------------------------");
}
}// fine for neurone
contatore_esempi = contatore_esempi + 1;
}// fine for strato
}
private void forward_propagation()
{
double calcolo;
double tot;
for (int strato = 1; strato < struttura_neurone.Length; strato++)
{
if (schermo == true)
{
Console.WriteLine("///////////////////////////////// FORWARD PROPAGATION ///////////////////////////////////");
Console.WriteLine("///////////////////////////////// STRATO " + strato + " /////////////////////////////////");
}
for (int neurone = 0; neurone < struttura_neurone[strato].Length; neurone++)
{
calcolo = 0;
tot = 0;
double[] dati = new double[struttura_pesi[strato - 1][neurone].Length];
for (int pesi = 0; pesi < struttura_pesi[strato-1][neurone].Length; pesi++)
{
calcolo = struttura_neurone[strato - 1][pesi] * struttura_pesi[strato - 1][neurone][pesi];
dati[pesi] = calcolo;
if (schermo == true)
{
Console.WriteLine("calcolo: input: " + struttura_neurone[strato - 1][pesi] + " * peso: " + struttura_pesi[strato - 1][neurone][pesi] + " = output: " + calcolo);
}
}
for (int x = 0; x < dati.Length; x++)
{
tot = dati[x] + tot;
}
double totale = tot + bias[strato] * 1;
if (schermo == true)
{
Console.WriteLine("risultato neurone:" + "[" + strato + "][" + neurone + "] = totale: " + tot + " + bias: " + bias[strato] + " * 1 = output: " + totale + " -> funzione = output: " + funzione_attivazione(totale));
Console.WriteLine("----------------------------------------------------------------------------");
}
struttura_neurone[strato][neurone] = funzione_attivazione(totale);
}
}
}
private double funzione_attivazione(double x)
{
double somma = 1.0 / (1.0 + Math.Exp(-x));
return somma;
}
public neurone ()
{
// CODICE
set_neurone();
// -----
while (false == flagCiclo)
{
if (schermo == true)
{
Console.WriteLine("||||||||||||||||||||||||||||||||| Epoch " + contatoreCiclo + " |||||||||||||||||||||||||||||||||");
}
// CODICE
// ALLENAMENTO
for (int a = 0; a<4000; a++)
{/*
struttura_neurone[0][0] = 0.02;
struttura_neurone[0][1] = 0.80;
targets[0] = 0.99; // uomo
targets[1] = 0.01; // cane
forward_propagation();
stampa();
back_propagation();
stampa();
*/
//Console.ReadKey();
}
// -----
Console.WriteLine("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< TEST >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
// TEST
for (int a = 0; a < 1; a++)
{
struttura_pesi[0][0][0] = 0.1593819297264715;
struttura_pesi[0][0][1] = 0.27927697746168275;
struttura_pesi[0][1][0] = 0.2383362398423115425;
struttura_pesi[0][1][1] = 0.7600338106205355;
struttura_pesi[1][0][0] = -0.621124261620155;
struttura_pesi[1][0][1] = -0.5711242616201575;
struttura_pesi[1][1][0] = -0.3999725513304025;
struttura_pesi[1][1][1] = -0.3499725513304025;
struttura_neurone[0][0] = 0.99;
struttura_neurone[0][1] = 0.99;
forward_propagation();
stampa();
}
// -----
Console.ReadKey();
// -----
// CICLO CONTATORE
if (contatoreCiclo == 100000)
{
flagCiclo = true;
}
contatoreCiclo ++;
// -----
}
}
} // fine classe Neurone
} // fine namespace