AI e Machine Learning: come impararli visivamente

Ho creato questo tutorial come un articolo entry-level sull'intelligenza artificiale.

Ogni nuovo argomento deve essere presentato in una lingua che corrisponda al livello di abilità dello studente in quel momento. Quindi non aspettarti formule matematiche pazze ancora.

In particolare daremo uno sguardo al Machine Learning noto anche come Deep Learning.

La profondità di una rete neurale è determinata dal numero di livelli di input.

Gli algoritmi di Machine Learning valutano la probabilità di un determinato set di dati rispetto a un modello specifico.

Pensando in intervalli

I neuroni nel tuo cervello non sono sicuramente digitali, ma assomigliano alla logica binaria come stato acceso o spento. Ma nel software utilizziamo invece un intervallo di valori.

Il risultato di un ciclo di calcolo in un'operazione AI è una stima di precisione nell'intervallo compreso tra 0,0 e 1,0. In definitiva, viene prodotto un valore di output in base al modo in cui i dati di input corrispondono a un modello specifico con 1.0 corrispondente al 100% (raramente lo si raggiunge ma 0,95 - 0,97 è buono).

Questo modello viene di solito allenato prima di poter ottenere risultati significativi. Maggiori informazioni un po 'più avanti in questo tutorial. Ma prima, ecco ML nella sua forma più semplice.

Tutto inizia con le reti neurali - un'imitazione software della struttura fisica dei neuroni in un cervello.

Semplice struttura della rete neurale

L'apprendimento automatico nella sua forma più semplice: una rete neurale molto semplice.

In questo esempio minimalista viene mostrato 1 livello di input composto da 3 nodi di input.

Di solito viene fornito un set multiplo di input per layer. Ogni input viene raccolto da un tipo di sorgente. Come una matrice di pixel di un'immagine utilizzata per il riconoscimento facciale, ad esempio / o qualsiasi altro dato. Dipende dallo scopo di ciò che stai cercando di realizzare con il tuo algoritmo AI.

Entrambi i valori di input e output sono pt mobili. numeri tra 0,0 e 1,0.

Logisticamente, durante il funzionamento in rete i dati vengono alimentati da sinistra a destra. Tuttavia ... La retro-propagazione viene talvolta utilizzata per ottimizzare la rete neurale. Questo è quando viaggiamo in retromarcia. Ma per ora non dobbiamo preoccuparci di questo.

Somma

La somma di diversi nodi di input è proprio come sembra. È la somma totale dei pesi di ogni nodo del livello di input precedente. Dopo aver calcolato la somma, viene quindi passata alla funzione di attivazione per l'elaborazione.

Funzione di attivazione

La funzione di attivazione converte la somma dei valori di input in un valore di output.

Ma come funziona esattamente?

Dobbiamo dare un'occhiata a un altro aspetto dell'apprendimento automatico.

Ricordi quelle equazioni matematiche del liceo? Parabole: qualcuno?

Fonte immagine: https://pl.wikipedia.org/wiki/Plik:Catenary-pm.svg

Una funzione di attivazione è letteralmente solo un'equazione matematica. Quindi per quelli con un background matematico questo potrebbe essere un po 'più facile da capire. In caso contrario, continua a leggere i diagrammi visivi e il resto di questo tutorial in modo che inizi ad affondare!

Il motivo per cui non possiamo usare equazioni lineari semplici è dovuto ai loro limiti.

Non sono sufficienti per la creazione di utili reti neurali.

Le reti neurali sono progettate attorno a equazioni più complesse. Ad esempio la funzione Sigmoid (nota anche come logistica) è abbastanza comune. (Daremo un'occhiata ad alcuni di quelli diversi nella sezione seguente.)

Tutti assumono la forma di f (x) = ... e quindi riducono il valore x in un modo unico per quella funzione. Perché questo sia importante e perché abbiamo diverse funzioni AF diventerà più evidente un po 'più tardi.

Cosa succede quando otteniamo il nostro risultato?

AF passa il valore calcolato sul nodo successivo ed essenzialmente come input parziale in una delle funzioni di attivazione in un nodo nel set di input successivo.

Puoi pensarlo come prendere una serie di input multipli. E passando il valore calcolato sul nodo successivo. È il gateway del valore tra i set di input.

Diversi tipi di funzioni di attivazione

Proprio come ci sono diversi tipi di equazioni matematiche ... ci sono diversi tipi di funzioni di attivazione.

Il modo esatto in cui riducono i numeri per arrivare al valore di output finale è strettamente correlato alla formazione di una rete esistente per prima. Quindi non possiamo ancora approfondire l'argomento, perché nel complesso il sistema non si basa su qualcosa di semplice come calcolare e restituire un risultato numerico.

Ma quello che possiamo fare - per approfondire la nostra comprensione, finora - è dare un'occhiata alla rappresentazione visiva di ogni equazione matematica dietro diverse funzioni di attivazione!

Questo è un tutorial visivo. E per darti un'idea di base di ciò che dovrai affrontare qui è una tabella del classico set di equazioni matematiche su cui molte funzioni di attivazione classiche possono essere basate.

L'AF di base è rappresentato da f (x) = x o dalla funzione identità.

Alcune formule matematiche ben note di base.

Ce ne sono molti altri. Ma sono un po 'più complessi.

Essenzialmente queste funzioni vengono utilizzate per determinare il valore del nodo risultante.

In che modo una funzione di attivazione determina il suo valore?

Bene, ecco cos'è un AF. Prende un input sotto forma di un numero e produce un valore di ritorno tra 0,0–1,0 (a volte l'intervallo è +/- infinito). Le formule effettive sono descritte sopra. Puoi riscrivere queste equazioni come funzioni in Python, JavaScript o qualsiasi altro linguaggio di programmazione.

Se sei in matematica e hai molto tempo a disposizione, adorerai scrivere queste funzioni in codice! Ma spesso non è necessario. E questo perché A.I. già esistente le biblioteche se ne occupano per te. In questo modo puoi concentrarti sulla costruzione della tua rete neurale e sulla sua formazione per uno scopo specifico.

Ogni nodo porta un peso calcolato

Quindi queste funzioni di attivazione producono un valore.

La cosa più importante da notare in questo momento - ogni punto è un peso.

Questo peso misura la probabilità che un determinato modello corrisponda.

Ma sono possibili più livelli di set di input, come mostrato nel prossimo esempio.

Nodi in una rete neurale leggermente più avanzata collegati tra loro.

Ogni singolo nodo comunica con ogni singolo nodo nel livello di input successivo che costituisce questa strada di comunicazione interconnessa.

Il numero di elementi in ogni livello è arbitrario. Non deve essere lo stesso numero mostrato nel diagramma sopra. A seconda del problema che stai cercando di risolvere.

Ci vorrà un po 'di intuizione e creatività per determinare il numero di nodi di input che si desidera utilizzare in ogni livello. Ma anche risolvere lo stesso problema può essere realizzato da diverse strutture di rete neurale.

A causa della natura non lineare dei calcoli, questo processo è ambiguo.

Strati nascosti

Abbiamo appena discusso di come una rete neurale possa avere più livelli di input. Possono essere pensati come file verticali di nodi.

Tutti i livelli interni tra la prima riga di input e il nodo di output vengono spesso definiti layer nascosti. Questo ha senso perché è qui che viene eseguita la maggior parte del duro lavoro di elaborazione dell'IA. Fondamentalmente è la scatola misteriosa dell'IA.

Diversi tipi di modelli di rete neurale

A volte ML può sembrare un po 'come creare un modello di rete per abbinarlo.

Le reti neurali sono disponibili in diverse forme e forme.

Diversi tipi di strutture di reti neurali sono più adatti a risolvere particolari tipi di problemi associati alla loro struttura.

OK - Ma come scriviamo il codice?

Questa era molta teoria.

Ma come lo implementiamo effettivamente nel codice?

È possibile utilizzare una libreria come Tensorflow.js per iniziare.

Ma questo non farà nulla di buono perché c'è ancora tanto da coprire.

OK - Ma come produce risultati significativi?

Finora abbiamo discusso della struttura di una rete neurale.

Abbiamo parlato di funzioni di attivazione, input di dati e livelli nascosti.

Abbiamo anche parlato dei pesi trasmessi avanti e indietro per le connessioni simulate.

Affinché un algoritmo di Machine Learning non lineare produca risultati sensati, deve prima essere addestrato su una serie di dati preesistenti.

Inizi sempre con la scelta dei dati per addestrare il tuo algoritmo AI.

Dipende dal problema che stai cercando di risolvere.

Se vuoi riconoscere i numeri in un'immagine, inizi con le immagini delle cifre.

Riconoscere i numeri da una schermata

L'esempio AI classico è insegnare a una rete neurale a riconoscere numeri compresi tra 0 e 9. Allo stesso modo in cui è possibile addestrare un algoritmo macchina per riconoscere le lettere A-Z o anche parti di un volto umano: un occhio o una bocca su un la fotografia rappresenta anche un particolare tipo di forma o modello comune a tutti gli esseri umani ma che potrebbe apparire leggermente diverso.

Ricorda che qui stiamo trattando solo schemi.

Quando l'algoritmo riconosce un modello, non corrisponde mai al 100%. Ma più ci avviciniamo a 1,0 (100%), più è probabile che la forma che stiamo cercando rappresenti ciò che è stato addestrato a riconoscere.

Se usassimo un carattere standard, non dovremmo nemmeno fare alcun lavoro di intelligenza artificiale. Potremmo semplicemente scansionare ogni cifra per un modello di pixel esatto. Ma il punto chiave dell'IA è riconoscere un modello nell'oscurità.

Innanzitutto, dobbiamo disporre di un tipo di supporto che verrà utilizzato come un dato di allenamento. Ogni cifra può essere rappresentata da un'immagine:

Le stesse cifre scritte più volte producono pattern leggermente diversi. Immagine tratta dalla demo AI di JavaScript che si trova su http://myselph.de/neuralNet.html

Puoi riconoscere facilmente ogni cifra a vista. Ma un algoritmo AI deve essere addestrato per riconoscere modelli simili perché mentre sono simili non sono ancora identici al 100%.

Per raggiungere questo obiettivo, possiamo scomporre il modello principale in blocchi più piccoli e implementare qualcosa chiamato estrazione delle caratteristiche.

Estrazione di funzionalità

Per identificare una cifra l'algoritmo implementa un sistema di estrazione di caratteristiche che suddivide i modelli comuni in controparti rilevanti per la costruzione della cifra / simbolo / lettera / ecc. Completi

L'essenza di un modello rimane la stessa. Ad esempio, 0 è principalmente un cerchio: puoi scomporlo in motivi più piccoli con un arco su ciascuno dei lati:

Se possiamo solo addestrare il nostro algoritmo a riconoscere questi 4 schemi unici e verificarne la presenza all'interno dell'area localizzata di un'immagine, possiamo calcolare la certezza con cui si può dire che potrebbe essere uno zero.

È lo stesso per le altre cifre. La cifra 1 ad esempio è una singola barra verticale. O forse con una linea più piccola con un leggero angolo in alto.

Il numero 2 è mezzo cerchio in alto, una linea diagonale e una linea orizzontale.

Il numero 3 può essere suddiviso in due schemi semi-arco.

Il numero 4 può essere pensato come 3 linee: verticale, orizzontale e diagonale.

…e così via.

E se fosse una cifra scritta a mano? Ha ancora le stesse proprietà di quella cifra: gli stessi bordi, gli stessi anelli.

Cosa succede se la cifra appare su un limite di velocità per uscire dalla strada da un angolo indiretto su una fotografia? Proprio come la nostra visione, l'IA dovrebbe essere in grado di adattarsi a qualche tipo di termine di errore.

È un cinque, tre o otto?

Prova questa demo AI JavaScript che ti consente di disegnare qualcosa sullo schermo e chiedi all'algoritmo pre-addestrato di dirti cosa hai appena disegnato.

L'algoritmo cercherà di darti la migliore corrispondenza anche se ciò che disegni non è in realtà un numero. Tuttavia puoi vedere l'intelletto artificiale al lavoro cercando di fornire l'approssimazione più vicina che riesca a raccogliere.

Che aspetto ha il set addestrato?

Ecco un frammento dei dati di allenamento dall'algoritmo. È solo un elenco di pesi memorizzati in un array molto lungo (migliaia di valori):

// Pesi della rete neurale (pesi unità-unità e distorsioni unità) // l'addestramento è stato svolto in Matlab con il set di dati MNIST.
// questi dati si riferiscono a un'unità 784-200-10, con non linearità logistica
// in nascosto e softmax nel livello di output. L'input è a
// [-1; 1] immagine di livello di grigio, sfondo == 1, 28x28 pixel linearizzati
// in ordine di colonna (ovvero colonna1 (:); colonna2 (:); ...) i-esima uscita
// essendo il massimo significa che la rete pensa che l'input codifichi
// (i-1) i pesi seguenti hanno mostrato un tasso di errore dell'1,92% sul test
// set di dati (9808/10000 cifre riconosciute correttamente).
let w12 = [[-0.00718674, 0.00941102, -0.0310175, -0.00121102, -0.00978546, -4.65943e-05, 0.0150367, 0.0101846, 0.0482145, 0.00291535, -0.00172736, 0.0234236025225225277025225277.025 , 0,00692898, 0,0215552, 0,0540464, 0,0393167, 0,0668207, 0,0232665, 0,031598, 0,0143047, 0,0156885, -0,0269579, -0,00777022, 0,0397823, -0,00825727, 0,0212889, -0,00755215, 0,038, 0,035
/ * ... Migliaia di pesi più seguono ... * /

Il codice sorgente completo non rientra in questo articolo. Ma i set di solito sono piuttosto lunghi anche per quelli che sembrano essere test banali.

Dipingere l'immagine immessa nella rete neurale

Questo bit di codice è stato preso dalla funzione riconoscere () scritta in JavaScript.

È stato preso dalla demo su http://myselph.de

Puoi controllare l'intero codice sorgente qui.

// per visualizzazione / debugging: dipinge l'input sulla rete neurale. if (document.getElementById ('preprocessing'). checked == true)
{
    ctx.clearRect (0, 0, canvas.width, canvas.height);
    ctx.drawImage (copyCtx.canvas, 0, 0);
    per (var y = 0; y <28; y ++) {
        per (var x = 0; x <28; x ++) {
           var block = ctx.getImageData (x * 10, y * 10, 10, 10);
           var newVal = 255 * (0,5 - nnInput [x * 28 + y] / 2);
           per (var i = 0; i <4 * 10 * 10; i + = 4) {
               block.data [i] = newVal;
               block.data [i + 1] = newVal;
               block.data [i + 2] = newVal;
               block.data [i + 3] = 255;
           }
       ctx.putImageData (blocco, x * 10, y * 10);
       }
   }
}

Questo pezzo parziale di codice "incolla" l'input dell'immagine (un disegno a mano libera) che in precedenza era stato diviso in blocchi di 10 x 10 che memorizzavano valori di scala di grigi medi per quell'area dell'immagine.

Lo controllerà quindi rispetto all'insieme addestrato e dopo aver scricchiolato le somme / e i confronti medi contro di esso restituirà la probabilità del risultato in termini di quanto il disegno del canvas HTML si avvicini a una determinata cifra.

Parole finali

L'intelligenza artificiale è un argomento vasto. Esistono diversi tipi di schemi di apprendimento automatico e tutorial che escono ogni giorno. Questo tutorial dovrebbe servire solo come introduzione per qualcuno che ha appena iniziato!

Seguimi su Twitter per omaggi di libri gratuiti

Prendi la tua copia del Dizionario visivo CSS incl. diagrammi di tutte le proprietà CSS.

Su Twitter Tidal Wave è l'account che regala i miei libri gratuitamente.

Seguimi su @ js_tut dove inserisco tutorial freemium JavaScript.