Le reti neurali danno la possibilità di risolvere problemi non-lineari complicati. Possono essere usate in varie aree come la classificazione dei segnali e il pattern recognition. Una rete neurale è un modello ispirato al cervello umano che consiste di molteplici neuroni connessi fra di loro. Il network è formato da un livello di neuroni di input (dove l’informazione entra), un livello di neuroni output (da dove si possono osservare i risultati) e un numero di livelli nascosti al centro:

network-neurale

Negli ultimi anni sono stati sviluppati molti framework in Javascript con lo scopo di aiutare nella creazione, training e utilizzo delle reti neurali per scopi differenti. In questo post oggi mostriamo come configurare una rete neurale e usarla per classificare le immagini.
Un esempio comune per chi per la prima volta si addentra in questo mondo è quello della classificazione di numeri scritti a mano. Per raggiungere buoni risultati una rete neurale dev’essere opportunamente istruita. Motivo per cui abbiam bisogno di ciò che in gergo viene chiamato “training set”. Per il nostro esempio utilizzeremo i numeri MNIST, un insieme famoso di migliaia di immagini binarie 28px per 28px di numeri da 0 a 9:

mnist

Il database MNIST contiene 60.000 esempi utili al training e 10.000 esempi per l’esecuzione dei test. Piuttosto che scaricare il database e convertire i dati binari in immagini possiamo usare la libreria MNIST su npm, che crea automaticamente gli insiemi di training e test.

const mnist = require('mnist'); 
 
const set = mnist.set(700, 20);
 
const trainingSet = set.training;
const testSet = set.test;

Il codice sopra crea un training set di 700 immagini e un test-set da 20 elementi. Quando si crea il set manualmente, è importante assicurarsi che non ci siano elementi duplicati nel set. Ovviamente la libreria MNIST è già rodata in tal senso.

Dopo aver creato i dati per il training e il test, possiamo configurare la rete. Useremo la libreria Synaptic.js, che da la possibilità di creare una rete neurale e configurare vari parametri. Prima di tutto, dobbiamo determinare quanti neuroni d’input e d’output vogliamo.

Siccome la dimensione di ogni immagine è 28x28px, il numero di pixel che il network prenderà in input saranno 28 x 28 = 784. I numeri verranno assegnati ad una delle dieci classi (0-9) così che appunto i neuroni di output siano 10. Inoltre, il network dovrà avere almeno un livello nascosto, che nel nostro set d’esempio consterà di 100 neuroni.

Il codice che segue codifica il network descritto sopra:

const synaptic = require('synaptic');
 
const Layer = synaptic.Layer;
const Network = synaptic.Network;
const Trainer = synaptic.Trainer;
 
const inputLayer = new Layer(784);
const hiddenLayer = new Layer(100);
const outputLayer = new Layer(10);
 
inputLayer.project(hiddenLayer);
hiddenLayer.project(outputLayer);
 
const myNetwork = new Network({
    input: inputLayer,
    hidden: [hiddenLayer],
    output: outputLayer
});

Per effettuare il training possiamo usare direttamente il Trainer di synaptic.js. La funzione train() prende come parametri i dati di training e un oggetto di configurazione.

const trainer = new Trainer(myNetwork);
trainer.train(trainingSet, {
    rate: .2,
    iterations: 20,
    error: .1,
    shuffle: true,
    log: 1,
    cost: Trainer.cost.CROSS_ENTROPY
});

Come opzione, si può settare un “rate”, che è il tasso d’apprendimento. Il numero di iterazioni, “iterations” e altro ancora. Ogni opzione è ben descritta sulla documentazione di synaptic.js.

In generale, nel nostro esempio abbiamo fissato le iterazioni a 20, per assicurarci di non dover aspettare ore prima che il training finisca. Da sottolineare che per un training ottimale si consiglia un numero maggiore di iterazioni. Se si vuol vedere lo stato d’avanzamento del training, si può usare l’opzione “log”.

Dopo che il training è giunto al termine, il set di test può essere usato per verificare quanto sia efficace la classificazione della nostra rete neurale. Per questo task si utilizza la funzione activate(), che prende l’elemento da classificare come parametro.

console.log(myNetwork.activate(testSet[0].input));
console.log(testSet[0].output);

Noteremo che i risultati raggiunti da questa rete neurale, in questo specifico esempio non saranno perfetti. Solo il 50% degli elementi nel test-set verranno classificati correttamente. Questo per via di un training-set piccolo e di un numero di iterazioni troppo basso. Aumentando il numero di elementi e il numero d’iterazioni chiaramente la fase di training richiederà molto più tempo per essere completata.

Se volete sperimentare e dare un’occhiata ad altre librerie per la creazione di reti neurali, qui trovate altri progetti javascript open-source simili:

ConvNetJS
Mind.js
Brain.js
DN2A