Apprendimento approfondito con Keras - Guida rapida
Deep Learning è diventata negli ultimi giorni una parola d'ordine nel campo dell'Intelligenza Artificiale (AI). Per molti anni abbiamo utilizzato l'apprendimento automatico (ML) per impartire intelligenza alle macchine. Negli ultimi giorni, il deep learning è diventato più popolare grazie alla sua supremazia nelle previsioni rispetto alle tecniche ML tradizionali.
Deep Learning significa essenzialmente addestrare una rete neurale artificiale (ANN) con un'enorme quantità di dati. Nell'apprendimento profondo, la rete impara da sola e quindi richiede dati enormi per l'apprendimento. Mentre l'apprendimento automatico tradizionale è essenzialmente un insieme di algoritmi che analizzano i dati e apprendono da essi. Hanno quindi utilizzato questo apprendimento per prendere decisioni intelligenti.
Ora, arrivando a Keras, è un'API per reti neurali di alto livello che viene eseguita su TensorFlow, una piattaforma di machine learning open source end-to-end. Usando Keras, definisci facilmente complesse architetture ANN per sperimentare sui tuoi big data. Keras supporta anche la GPU, che diventa essenziale per l'elaborazione di enormi quantità di dati e lo sviluppo di modelli di machine learning.
In questo tutorial imparerai l'uso di Keras nella costruzione di reti neurali profonde. Vedremo gli esempi pratici per l'insegnamento. Il problema in questione è riconoscere le cifre scritte a mano utilizzando una rete neurale addestrata con il deep learning.
Solo per renderti più entusiasta del deep learning, di seguito è riportato uno screenshot delle tendenze di Google sul deep learning qui -
Come puoi vedere dal diagramma, l'interesse per il deep learning è in costante crescita negli ultimi anni. Ci sono molte aree come la visione artificiale, l'elaborazione del linguaggio naturale, il riconoscimento vocale, la bioinformatica, la progettazione di farmaci e così via, in cui l'apprendimento profondo è stato applicato con successo. Questo tutorial ti consentirà di iniziare rapidamente il deep learning.
Quindi continua a leggere!
Come detto nell'introduzione, il deep learning è un processo di addestramento di una rete neurale artificiale con un'enorme quantità di dati. Una volta addestrata, la rete sarà in grado di fornirci le previsioni su dati invisibili. Prima di andare oltre nello spiegare cos'è l'apprendimento profondo, esaminiamo rapidamente alcuni termini utilizzati nell'addestramento di una rete neurale.
Reti neurali
L'idea di rete neurale artificiale è stata derivata dalle reti neurali nel nostro cervello. Una tipica rete neurale è costituita da tre livelli: input, output e nascosto, come mostrato nell'immagine sottostante.
Questo è anche chiamato a shallowrete neurale, poiché contiene solo uno strato nascosto. Aggiungere più livelli nascosti nell'architettura sopra per creare un'architettura più complessa.
Reti profonde
Il diagramma seguente mostra una rete profonda composta da quattro livelli nascosti, un livello di input e un livello di output.
Man mano che il numero di livelli nascosti viene aggiunto alla rete, la sua formazione diventa più complessa in termini di risorse richieste e il tempo necessario per addestrare completamente la rete.
Formazione in rete
Dopo aver definito l'architettura di rete, addestrarla per eseguire determinati tipi di previsioni. La formazione di una rete è un processo per trovare i pesi corretti per ogni collegamento nella rete. Durante l'addestramento, i dati fluiscono dai livelli di input a quelli di output attraverso vari livelli nascosti. Poiché i dati si muovono sempre in una direzione dall'input all'output, chiamiamo questa rete come Feed-forward Network e chiamiamo la propagazione dei dati come Forward Propagation.
Funzione di attivazione
Ad ogni livello, calcoliamo la somma ponderata degli input e la inseriamo in una funzione di attivazione. La funzione di attivazione porta la non linearità alla rete. È semplicemente una funzione matematica che discretizza l'output. Alcune delle funzioni di attivazione più comunemente utilizzate sono sigmoide, iperbolica, tangente (tanh), ReLU e Softmax.
Backpropagation
Backpropagation è un algoritmo per l'apprendimento supervisionato. In Backpropagation, gli errori si propagano all'indietro dall'output al livello di input. Data una funzione di errore, calcoliamo il gradiente della funzione di errore rispetto ai pesi assegnati ad ogni connessione. Il calcolo del gradiente procede a ritroso attraverso la rete. Il gradiente del primo strato di pesi viene calcolato per primo e il gradiente del primo strato di pesi viene calcolato per ultimo.
Ad ogni strato, i calcoli parziali del gradiente vengono riutilizzati nel calcolo del gradiente per lo strato precedente. Questo si chiama Gradient Descent.
In questo tutorial basato sul progetto definirai una rete neurale profonda feed-forward e la addestrerai con tecniche di backpropagation e di discesa del gradiente. Fortunatamente, Keras ci fornisce tutte le API di alto livello per la definizione dell'architettura di rete e l'addestramento utilizzando la discesa del gradiente. Successivamente, imparerai come farlo in Keras.
Sistema di riconoscimento delle cifre scritte a mano
In questo mini progetto, applicherai le tecniche descritte in precedenza. Creerai una rete neurale di apprendimento profondo che verrà addestrata per il riconoscimento delle cifre scritte a mano. In qualsiasi progetto di machine learning, la prima sfida è raccogliere i dati. Soprattutto, per le reti di apprendimento profondo, hai bisogno di dati enormi. Fortunatamente, per il problema che stiamo cercando di risolvere, qualcuno ha già creato un set di dati per l'addestramento. Questo si chiama mnist, che è disponibile come parte delle librerie di Keras. Il set di dati è costituito da diverse immagini di 28x28 pixel di cifre scritte a mano. Addestrerai il tuo modello sulla maggior parte di questo set di dati e il resto dei dati verrà utilizzato per convalidare il tuo modello addestrato.
descrizione del progetto
Il mnistil set di dati è composto da 70000 immagini di cifre scritte a mano. Alcune immagini di esempio sono riprodotte qui per riferimento
Ogni immagine ha una dimensione di 28 x 28 pixel per un totale di 768 pixel di vari livelli di scala di grigi. La maggior parte dei pixel tende verso l'ombra del nero mentre solo pochi di essi sono verso il bianco. Metteremo la distribuzione di questi pixel in un array o in un vettore. Ad esempio, la distribuzione dei pixel per un'immagine tipica delle cifre 4 e 5 è mostrata nella figura seguente.
Ogni immagine ha una dimensione di 28 x 28 pixel per un totale di 768 pixel di vari livelli di scala di grigi. La maggior parte dei pixel tende verso l'ombra del nero mentre solo pochi di essi sono verso il bianco. Metteremo la distribuzione di questi pixel in un array o in un vettore. Ad esempio, la distribuzione dei pixel per un'immagine tipica delle cifre 4 e 5 è mostrata nella figura seguente.
Chiaramente si vede che la distribuzione dei pixel (soprattutto quelli tendenti al bianco) è diversa, questo contraddistingue le cifre che rappresentano. Forniremo questa distribuzione di 784 pixel alla nostra rete come input. L'output della rete sarà composto da 10 categorie che rappresentano una cifra compresa tra 0 e 9.
La nostra rete sarà composta da 4 livelli: uno di input, uno di output e due nascosti. Ogni livello nascosto conterrà 512 nodi. Ogni livello è completamente connesso al livello successivo. Quando addestriamo la rete, calcoleremo i pesi per ciascuna connessione. Addestriamo la rete applicando la retropropagazione e la discesa del gradiente di cui abbiamo discusso in precedenza.
Con questo sfondo, iniziamo ora a creare il progetto.
Impostazione del progetto
Noi useremo Jupyter attraverso Anacondanavigatore per il nostro progetto. Poiché il nostro progetto utilizza TensorFlow e Keras, sarà necessario installarli nella configurazione di Anaconda. Per installare Tensorflow, esegui il seguente comando nella finestra della console:
>conda install -c anaconda tensorflow
Per installare Keras, usa il seguente comando:
>conda install -c anaconda keras
Ora sei pronto per avviare Jupyter.
Avvio di Jupyter
Quando avvii il navigatore Anaconda, vedrai la seguente schermata di apertura.
Clic ‘Jupyter’per avviarlo. Lo schermo mostrerà i progetti esistenti, se presenti, sul tuo disco.
Avvio di un nuovo progetto
Avvia un nuovo progetto Python 3 in Anaconda selezionando la seguente opzione di menu:
File | New Notebook | Python 3
Lo screenshot della selezione del menu viene mostrato come riferimento rapido -
Un nuovo progetto vuoto apparirà sullo schermo come mostrato di seguito -
Cambia il nome del progetto in DeepLearningDigitRecognition facendo clic e modificando il nome predefinito “UntitledXX”.
Per prima cosa importiamo le varie librerie richieste dal codice nel nostro progetto.
Gestione e stampa di array
Come tipico, usiamo numpy per la gestione degli array e matplotlibper tracciare. Queste librerie vengono importate nel nostro progetto utilizzando quanto segueimport dichiarazioni
import numpy as np
import matplotlib
import matplotlib.pyplot as plot
Soppressione degli avvisi
Poiché sia Tensorflow che Keras continuano a rivedere, se non sincronizzi le loro versioni appropriate nel progetto, in fase di esecuzione vedrai molti errori di avviso. Poiché distraggono la tua attenzione dall'apprendimento, sopprimeremo tutti gli avvertimenti in questo progetto. Questo viene fatto con le seguenti righe di codice:
# silent all warnings
import os
os.environ['TF_CPP_MIN_LOG_LEVEL']='3'
import warnings
warnings.filterwarnings('ignore')
from tensorflow.python.util import deprecation
deprecation._PRINT_DEPRECATION_WARNINGS = False
Keras
Usiamo le librerie di Keras per importare i set di dati. Useremo il filemnistset di dati per cifre scritte a mano. Importiamo il pacchetto richiesto utilizzando la seguente dichiarazione
from keras.datasets import mnist
Definiremo la nostra rete neurale di deep learning utilizzando i pacchetti Keras. Importiamo il fileSequential, Dense, Dropout e Activationpacchetti per definire l'architettura di rete. Noi usiamoload_modelpacchetto per salvare e recuperare il nostro modello. Usiamo anchenp_utilsper alcune utilità di cui abbiamo bisogno nel nostro progetto. Queste importazioni vengono eseguite con le seguenti istruzioni di programma:
from keras.models import Sequential, load_model
from keras.layers.core import Dense, Dropout, Activation
from keras.utils import np_utils
Quando esegui questo codice, vedrai un messaggio sulla console che dice che Keras utilizza TensorFlow nel back-end. Lo screenshot in questa fase è mostrato qui -
Ora, poiché abbiamo tutte le importazioni richieste dal nostro progetto, procederemo a definire l'architettura per la nostra rete di Deep Learning.
Il nostro modello di rete neurale consisterà in una pila lineare di livelli. Per definire un tale modello, chiamiamoSequential funzione -
model = Sequential()
Livello di input
Definiamo il livello di input, che è il primo livello nella nostra rete utilizzando la seguente istruzione di programma:
model.add(Dense(512, input_shape=(784,)))
Questo crea un livello con 512 nodi (neuroni) con 784 nodi di input. Questo è illustrato nella figura seguente:
Si noti che tutti i nodi di input sono completamente collegati al Layer 1, ovvero ogni nodo di input è connesso a tutti i 512 nodi del Layer 1.
Successivamente, dobbiamo aggiungere la funzione di attivazione per l'output del Livello 1. Useremo ReLU come nostra attivazione. La funzione di attivazione viene aggiunta utilizzando la seguente istruzione del programma:
model.add(Activation('relu'))
Successivamente, aggiungiamo Dropout del 20% utilizzando la dichiarazione seguente. Il dropout è una tecnica utilizzata per impedire l'overfitting del modello.
model.add(Dropout(0.2))
A questo punto, il nostro livello di input è completamente definito. Successivamente, aggiungeremo un livello nascosto.
Livello nascosto
Il nostro livello nascosto sarà composto da 512 nodi. L'input per il livello nascosto proviene dal nostro livello di input definito in precedenza. Tutti i nodi sono completamente connessi come nel caso precedente. L'output del livello nascosto andrà al livello successivo nella rete, che sarà il nostro livello finale e di output. Useremo la stessa attivazione ReLU del layer precedente e un dropout del 20%. Il codice per l'aggiunta di questo livello viene fornito qui:
model.add(Dense(512))
model.add(Activation('relu'))
model.add(Dropout(0.2))
La rete in questa fase può essere visualizzata come segue:
Successivamente, aggiungeremo il livello finale alla nostra rete, che è il livello di output. Nota che puoi aggiungere un numero qualsiasi di livelli nascosti usando il codice simile a quello che hai usato qui. L'aggiunta di più livelli renderebbe la rete complessa per la formazione; tuttavia, dando un netto vantaggio di risultati migliori in molti casi, anche se non tutti.
Livello di output
Il livello di output è costituito da soli 10 nodi poiché vogliamo classificare le immagini date in 10 cifre distinte. Aggiungiamo questo livello, usando la seguente dichiarazione:
model.add(Dense(10))
Dato che vogliamo classificare l'uscita in 10 unità distinte, utilizziamo l'attivazione softmax. In caso di ReLU, l'uscita è binaria. Aggiungiamo l'attivazione utilizzando la seguente dichiarazione:
model.add(Activation('softmax'))
A questo punto, la nostra rete può essere visualizzata come mostrato nel diagramma sottostante -
A questo punto, il nostro modello di rete è completamente definito nel software. Esegui la cella del codice e se non ci sono errori, riceverai un messaggio di conferma sullo schermo come mostrato nello screenshot qui sotto -
Successivamente, dobbiamo compilare il modello.
La compilazione viene eseguita utilizzando una singola chiamata di metodo chiamata compile.
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam')
Il compilemetodo richiede diversi parametri. Il parametro di perdita è specificato per avere tipo'categorical_crossentropy'. Il parametro delle metriche è impostato su'accuracy' e infine usiamo il adamottimizzatore per l'addestramento della rete. L'output in questa fase è mostrato di seguito:
Ora siamo pronti per inserire i dati nella nostra rete.
Caricamento dati
Come detto in precedenza, useremo il mnistset di dati fornito da Keras. Quando carichiamo i dati nel nostro sistema, li suddivideremo nei dati di addestramento e test. I dati vengono caricati chiamando ilload_data metodo come segue -
(X_train, y_train), (X_test, y_test) = mnist.load_data()
L'output in questa fase è simile al seguente:
Ora impareremo la struttura del set di dati caricato.
I dati che ci vengono forniti sono le immagini grafiche di dimensione 28 x 28 pixel, ciascuna contenente una singola cifra compresa tra 0 e 9. Visualizzeremo le prime dieci immagini sulla console. Il codice per farlo è fornito di seguito:
# printing first 10 images
for i in range(10):
plot.subplot(3,5,i+1)
plot.tight_layout()
plot.imshow(X_train[i], cmap='gray', interpolation='none')
plot.title("Digit: {}".format(y_train[i]))
plot.xticks([])
plot.yticks([])
In un ciclo iterativo di 10 conteggi, creiamo una sottotrama su ogni iterazione e mostriamo un'immagine da X_trainvettore in esso. Assegniamo un titolo a ciascuna immagine dalla corrispondentey_trainvettore. Nota che ily_train vettore contiene i valori effettivi per l'immagine corrispondente in X_trainvettore. Rimuoviamo i contrassegni degli assi xey chiamando i due metodixticks e ytickscon argomento nullo. Quando esegui il codice, vedrai il seguente output:
Successivamente, prepareremo i dati per inserirli nella nostra rete.
Prima di inviare i dati alla nostra rete, è necessario convertirli nel formato richiesto dalla rete. Questa operazione viene chiamata preparazione dei dati per la rete. Consiste generalmente nella conversione di un input multidimensionale in un vettore monodimensionale e nella normalizzazione dei punti dati.
Rimodellamento del vettore di input
Le immagini nel nostro set di dati sono costituite da 28 x 28 pixel. Questo deve essere convertito in un vettore unidimensionale di dimensione 28 * 28 = 784 per inserirlo nella nostra rete. Lo facciamo chiamando ilreshape metodo sul vettore.
X_train = X_train.reshape(60000, 784)
X_test = X_test.reshape(10000, 784)
Ora, il nostro vettore di addestramento sarà composto da 60000 punti dati, ciascuno costituito da un singolo vettore dimensione di dimensione 784. Allo stesso modo, il nostro vettore di prova sarà composto da 10000 punti dati di un vettore monodimensionale di dimensione 784.
Normalizzazione dei dati
I dati contenuti nel vettore di input hanno attualmente un valore discreto compreso tra 0 e 255 - i livelli della scala di grigi. La normalizzazione di questi valori di pixel tra 0 e 1 aiuta ad accelerare la formazione. Poiché utilizzeremo la discesa del gradiente stocastico, la normalizzazione dei dati aiuterà anche a ridurre la possibilità di rimanere bloccati negli ottimali locali.
Per normalizzare i dati, lo rappresentiamo come tipo float e lo dividiamo per 255 come mostrato nel seguente frammento di codice:
X_train = X_train.astype('float32')
X_test = X_test.astype('float32')
X_train /= 255
X_test /= 255
Vediamo ora come appaiono i dati normalizzati.
Esame dei dati normalizzati
Per visualizzare i dati normalizzati, chiameremo la funzione istogramma come mostrato qui -
plot.hist(X_train[0])
plot.title("Digit: {}".format(y_train[0]))
Qui, tracciamo l'istogramma del primo elemento del file X_trainvettore. Stampiamo anche la cifra rappresentata da questo punto dati. L'output dell'esecuzione del codice sopra è mostrato qui -
Noterai una fitta densità di punti con valore vicino allo zero. Questi sono i punti neri nell'immagine, che ovviamente sono la parte principale dell'immagine. Il resto dei punti della scala di grigi, che sono vicini al colore bianco, rappresentano la cifra. Puoi controllare la distribuzione dei pixel per un'altra cifra. Il codice seguente stampa l'istogramma di una cifra con indice 2 nel set di dati di addestramento.
plot.hist(X_train[2])
plot.title("Digit: {}".format(y_train[2])
L'output dell'esecuzione del codice sopra è mostrato di seguito:
Confrontando le due figure precedenti, noterai che la distribuzione dei pixel bianchi in due immagini differisce indicando una rappresentazione di una cifra diversa - "5" e "4" nelle due immagini precedenti.
Successivamente, esamineremo la distribuzione dei dati nel nostro set di dati di addestramento completo.
Esame della distribuzione dei dati
Prima di addestrare il nostro modello di apprendimento automatico sul nostro set di dati, dovremmo conoscere la distribuzione di cifre univoche nel nostro set di dati. Le nostre immagini rappresentano 10 cifre distinte che vanno da 0 a 9. Vorremmo conoscere il numero di cifre 0, 1, ecc. Nel nostro set di dati. Possiamo ottenere queste informazioni utilizzando ilunique metodo di Numpy.
Utilizzare il seguente comando per stampare il numero di valori univoci e il numero di occorrenze di ciascuno
print(np.unique(y_train, return_counts=True))
Quando esegui il comando sopra, vedrai il seguente output:
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=uint8), array([5923, 6742, 5958, 6131, 5842, 5421, 5918, 6265, 5851, 5949]))
Mostra che ci sono 10 valori distinti, da 0 a 9. Ci sono 5923 occorrenze della cifra 0, 6742 occorrenze della cifra 1 e così via. Lo screenshot dell'output è mostrato qui -
Come passaggio finale nella preparazione dei dati, dobbiamo codificare i nostri dati.
Codifica dei dati
Abbiamo dieci categorie nel nostro set di dati. Codificheremo quindi il nostro output in queste dieci categorie utilizzando la codifica one-hot. Usiamo il metodo to_categorial delle utilità Numpy per eseguire la codifica. Dopo che i dati di output sono stati codificati, ogni punto dati verrebbe convertito in un vettore monodimensionale di dimensione 10. Ad esempio, la cifra 5 sarà ora rappresentata come [0,0,0,0,0,1,0,0,0 , 0].
Codifica i dati utilizzando la seguente parte di codice:
n_classes = 10
Y_train = np_utils.to_categorical(y_train, n_classes)
Puoi controllare il risultato della codifica stampando i primi 5 elementi del vettore Y_train classificato.
Usa il codice seguente per stampare i primi 5 vettori:
for i in range(5):
print (Y_train[i])
Vedrai il seguente output:
[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
[1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
Il primo elemento rappresenta la cifra 5, il secondo rappresenta la cifra 0 e così via.
Infine, dovrai classificare anche i dati del test, cosa che viene eseguita utilizzando la seguente dichiarazione:
Y_test = np_utils.to_categorical(y_test, n_classes)
In questa fase, i tuoi dati sono completamente preparati per essere immessi nella rete.
Successivamente, viene la parte più importante e cioè l'addestramento del nostro modello di rete.
L'addestramento del modello viene eseguito in una singola chiamata al metodo chiamata fit che richiede pochi parametri, come mostrato nel codice seguente:
history = model.fit(X_train, Y_train,
batch_size=128, epochs=20,
verbose=2,
validation_data=(X_test, Y_test)))
I primi due parametri del metodo di adattamento specificano le funzionalità e l'output del set di dati di addestramento.
Il epochsè impostato su 20; assumiamo che l'addestramento converga in un massimo di 20 epoche - le iterazioni. Il modello addestrato viene convalidato sui dati del test come specificato nell'ultimo parametro.
L'output parziale dell'esecuzione del comando precedente è mostrato qui -
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
- 9s - loss: 0.2488 - acc: 0.9252 - val_loss: 0.1059 - val_acc: 0.9665
Epoch 2/20
- 9s - loss: 0.1004 - acc: 0.9688 - val_loss: 0.0850 - val_acc: 0.9715
Epoch 3/20
- 9s - loss: 0.0723 - acc: 0.9773 - val_loss: 0.0717 - val_acc: 0.9765
Epoch 4/20
- 9s - loss: 0.0532 - acc: 0.9826 - val_loss: 0.0665 - val_acc: 0.9795
Epoch 5/20
- 9s - loss: 0.0457 - acc: 0.9856 - val_loss: 0.0695 - val_acc: 0.9792
Lo screenshot dell'output è fornito di seguito come riferimento rapido:
Ora, poiché il modello viene addestrato sui nostri dati di addestramento, valuteremo le sue prestazioni.
Per valutare le prestazioni del modello, chiamiamo evaluate metodo come segue -
loss_and_metrics = model.evaluate(X_test, Y_test, verbose=2)
Per valutare le prestazioni del modello, chiamiamo evaluate metodo come segue -
loss_and_metrics = model.evaluate(X_test, Y_test, verbose=2)
Stamperemo la perdita e l'accuratezza utilizzando le seguenti due dichiarazioni:
print("Test Loss", loss_and_metrics[0])
print("Test Accuracy", loss_and_metrics[1])
Quando esegui le istruzioni precedenti, vedrai il seguente output:
Test Loss 0.08041584826191042
Test Accuracy 0.9837
Questo mostra una precisione del test del 98%, che dovrebbe essere accettabile per noi. Cosa significa per noi che nel 2% dei casi le cifre scritte a mano non sarebbero classificate correttamente. Tracciamo anche metriche di accuratezza e perdita per vedere come si comporta il modello sui dati di test.
Metriche di accuratezza della stampa
Usiamo il registrato historydurante la nostra formazione per ottenere un grafico delle metriche di precisione. Il codice seguente traccerà la precisione su ogni epoca. Raccogliamo l'accuratezza dei dati di addestramento ("acc") e l'accuratezza dei dati di convalida ("val_acc") per la stampa.
plot.subplot(2,1,1)
plot.plot(history.history['acc'])
plot.plot(history.history['val_acc'])
plot.title('model accuracy')
plot.ylabel('accuracy')
plot.xlabel('epoch')
plot.legend(['train', 'test'], loc='lower right')
Il grafico dell'output è mostrato di seguito:
Come puoi vedere nel diagramma, la precisione aumenta rapidamente nelle prime due epoche, indicando che la rete sta imparando velocemente. Successivamente, la curva si appiattisce indicando che non sono necessarie troppe epoche per addestrare ulteriormente il modello. In genere, se la precisione dei dati di addestramento ("acc") continua a migliorare mentre la precisione dei dati di convalida ("val_acc") peggiora, si verifica un overfitting. Indica che il modello sta iniziando a memorizzare i dati.
Tracciamo anche le metriche di perdita per verificare le prestazioni del nostro modello.
Tracciamento delle metriche di perdita
Ancora una volta, tracciamo il grafico della perdita sia sui dati di addestramento ("perdita") e di prova ("val_loss"). Questo viene fatto utilizzando il codice seguente:
plot.subplot(2,1,2)
plot.plot(history.history['loss'])
plot.plot(history.history['val_loss'])
plot.title('model loss')
plot.ylabel('loss')
plot.xlabel('epoch')
plot.legend(['train', 'test'], loc='upper right')
L'output di questo codice è mostrato di seguito:
Come puoi vedere nel diagramma, la perdita sul set di allenamento diminuisce rapidamente per le prime due epoche. Per il set di test, la perdita non diminuisce alla stessa velocità del set di allenamento, ma rimane pressoché invariata per più epoche. Ciò significa che il nostro modello sta generalizzando bene ai dati invisibili.
Ora useremo il nostro modello addestrato per prevedere le cifre nei nostri dati di test.
Prevedere le cifre in un dato invisibile è molto semplice. Devi semplicemente chiamare ilpredict_classes metodo del model passandolo a un vettore costituito dai tuoi punti dati sconosciuti.
predictions = model.predict_classes(X_test)
La chiamata al metodo restituisce le previsioni in un vettore che può essere testato per 0 e 1 rispetto ai valori effettivi. Questo viene fatto utilizzando le seguenti due istruzioni:
correct_predictions = np.nonzero(predictions == y_test)[0]
incorrect_predictions = np.nonzero(predictions != y_test)[0]
Infine, stamperemo il conteggio delle previsioni corrette e errate utilizzando le seguenti due istruzioni del programma:
print(len(correct_predictions)," classified correctly")
print(len(incorrect_predictions)," classified incorrectly")
Quando esegui il codice, otterrai il seguente output:
9837 classified correctly
163 classified incorrectly
Dopo aver addestrato in modo soddisfacente il modello, lo salveremo per un utilizzo futuro.
Salveremo il modello addestrato nella nostra unità locale nella cartella dei modelli nella nostra directory di lavoro corrente. Per salvare il modello, eseguire il codice seguente:
directory = "./models/"
name = 'handwrittendigitrecognition.h5'
path = os.path.join(save_dir, name)
model.save(path)
print('Saved trained model at %s ' % path)
L'output dopo aver eseguito il codice è mostrato di seguito:
Ora, poiché hai salvato un modello addestrato, puoi utilizzarlo in seguito per elaborare i tuoi dati sconosciuti.
Per prevedere i dati invisibili, è prima necessario caricare il modello addestrato nella memoria. Questo viene fatto usando il seguente comando:
model = load_model ('./models/handwrittendigitrecognition.h5')
Notare che stiamo semplicemente caricando il file .h5 in memoria. Questo imposta l'intera rete neurale in memoria insieme ai pesi assegnati a ciascun livello.
Ora, per fare le tue previsioni su dati invisibili, carica i dati, lascia che siano uno o più elementi, nella memoria. Pre-elaborare i dati per soddisfare i requisiti di input del nostro modello come hai fatto sui tuoi dati di addestramento e test sopra. Dopo la pre-elaborazione, alimentalo alla tua rete. Il modello produrrà la sua previsione.
Keras fornisce un'API di alto livello per la creazione di reti neurali profonde. In questo tutorial hai imparato a creare una rete neurale profonda che è stata addestrata per trovare le cifre nel testo scritto a mano. A tale scopo è stata creata una rete multistrato. Keras ti consente di definire una funzione di attivazione a tua scelta in ogni livello. Utilizzando la discesa del gradiente, la rete è stata addestrata sui dati di allenamento. L'accuratezza della rete addestrata nel prevedere i dati invisibili è stata testata sui dati del test. Hai imparato a tracciare la precisione e le metriche di errore. Dopo che la rete è stata completamente addestrata, hai salvato il modello di rete per un utilizzo futuro.