DOMANDA Dove posso trovare guide per reti neurali ?

InVeRsIoNe

Nuovo Utente
Salve ho un problema vorrei imparare machine Learning , reti neurali , intelligenza artificiale pero non so dove reperire il materiale ... ho provato in giro da molto ma ci sono solo copie i guide che si limitano a spiegare niente , cioe ti dicono cose pero non come costruirla .... ho provato su youtube su google , ma niente che mi abbia fatto capire come costruirla da zero solo teoria su teoria , ho capito e so come funziona un rete neurale in generale ma non so come costruirla in codice c#,c++ e come funziona l'addestramento o ecc quindi la mia domande c'e un buon articolo , libro , guida che fa davvero vedere come costruire in codice tutto ciò ?? sono interessato soprattutto alle reti neurali . davvero sono disperato il mio obbiettivo e costruire una piccola rete neurale . per capire il funzionamento da zero . grazie in anticipo <3 :giudice:
 

Andretti60

Utente Èlite
3,553
2,377
Hardware Utente
Domanda da un milione di dollari.
Purtroppo come hai notato internet e' inflazionato da reti neurali, trovi un sacco di schifezza, pare che tutti ne scrivano ma ben pochi le usano veramente. Ci sono un sacco di "prodotti" (ossia librerie) già pronte che permettono di configurare reti neurali e crearle dando in pasto i dati di apprendimento, la maggior parte degli articoli che trovi sono su queste.
Ma prima di tutto occorre capire quali sia il tuo background, le tue conoscenze e quello che vuoi veramente fare. Per esempio, sai programmare? Se si, quali linguaggi e a che livello? Cosa sai già di reti neurali? E, molto importante, puoi leggere in inglese, perché la maggior parte della documentazione e' in quella lingua (personalmente poiché ho studiato le reti neurali fin dal loro principio non ho mai studiato in italiano, allora non avevo scelta)
Ti dico subito: scrivere un programma che implementa una rete neurale non e' difficile. Ma scriverne uno che "funzioni" e' un altro paio di maniche, ho visto codice scritto da dottorandi fallire miseramente. Per partire da zero occorre una solida base matematica e di come funzioni l'aritmetica dei computer, altrimenti sono dolori.
 

InVeRsIoNe

Nuovo Utente
Si sono un programmatore conosco c++,c# livello medio , ho visto le librerie come tensoflow pero non sono interessato a quest ultime perché voglio scrivere il codice da zero che funzioni per l'inglese non ci sono problemi , delle reti neurali ho creato una neurone lineare , e ho fatto alcune prove di reti neurali multistrato pero senza riuscire ad addestrarla , in pratica conosco il funzionamento delle reti neurali quello che non capisco è come implementare la retro propagazione e l'addestramento ecc è questo che non so fare cioè la parte più difficile che comprende la matematica ho fatto vari test ti scrivo una test di una rete neurale che ho fatto che non funziona . se tu conosci qualche buon articolo mi daresti una grande mano .... su intenet c'e tanta spazzatura e gente che fa finta di sapere cose che non sa...
C#:
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
 
  • Mi piace
Reactions: Andretti60

Andretti60

Utente Èlite
3,553
2,377
Hardware Utente
Ah, hai già scritto molto.
Ma non è quella la maniera di scrivere una rete neurale, dimentica i vettori, devi adottare un sistema completamente OOP. Senza di quello cercare di implementare una back propagation è un incubo da mal di testa. Credimi.
Prima di tutto devi dichiare una classe tipo Neurone, con un un certo numero (variabile) di input e output. Questa classe dovrà derivare da una classe base di tipo INeurone, in modo da override la funzione di trasferimento, in questo modo puoi cambiarla a piacere senza dover toccare il resto del codice.
La classe Rete poi costruirà un albero di nodi (una "rete" in questo caso) di tipo INeurone, che puoi configurare mediante proprietà. Implementerà poi due metodi principali, Learn e Test.
Appena ho un minuto ti cerco un articolo "decente" che spiega i concetti fondamentali.
Ma per favore tieni questo in mente: è un esercizio difficile che non si risolve in pochi giorni, ci scrivono articoli e tesi a riguardo.
 

InVeRsIoNe

Nuovo Utente
si ho lo so ci sto provando da 1-2 anni senza successo :muro: aspetto l'articolo con ansia :D , seguirò il tuo consiglio sul OOP , sarebbe utile un articolo sul addestramento come la retro propagazione e deep learing grazie in anticipo :love:
 

pabloski

Utente Èlite
1,931
375
Hardware Utente
Salve ho un problema vorrei imparare machine Learning , reti neurali , intelligenza artificiale
Nota bene che stai parlando di cose diverse. Le reti neurali sono uno dei topic del machine learning, che è ben più vasto. L'intelligenza artificiale è il termine ombrello che contiene anche algoritmi genetici, evolutivi, ensemble e altre cose.

Ti posso solo consigliare di bagnarti i piedi col libro di Bishop "Pattern recognition and machine learning".

ho provato in giro da molto ma ci sono solo copie i guide che si limitano a spiegare niente
Sulle reti neurali esiste, per fortuna, qualcosa di buono http://neuralnetworksanddeeplearning.com/

Ma il must è il libro Deep Learning, di Goodfellow, Bengio e Courville. E i video di Andrew Ng su Youtube sono ottimi.

ho capito e so come funziona un rete neurale in generale ma non so come costruirla in codice c#,c++ e come funziona l'addestramento
Mi sa che le risorse che hai letto e guardato, ti hanno dato a mala pena una visione astratta di cos'è una rete neurale. Il libro Deep Learning ti può dare una visione dettagliata invece. Soprattutto la parte sull'addestramento è complicata. Innanzitutto ci sono vari algoritmi e non solo il gradient descent, come molti articoli affermano. Poi c'è il non trascurabile problema dell'esplosione dei gradienti, che richiede trucchetti ingegneristici non banali. Per questo la gente una Tensorflow e compagnia, piuttosto che crearsi una propria libreria da zero.

Comunque sia, dai un'occhiata pure qui https://victorzhou.com/blog/intro-to-neural-networks/

Ma se hai quest'intenzione, ti consiglio di nuovo Deep Learning, altrimenti non ne esci.
 
  • Mi piace
Reactions: Andretti60

Entra

oppure Accedi utilizzando