Rete di casa | Implementazione di GoogleNet in Keras

Contenuti

introduzione

Il apprendimento profondo está ganando fuerza rápidamente a misura que surgen más y más artículos de investigación de todo el mundo. Decisamente, questi documenti contengono una grande quantità di informazioni, ma spesso possono essere difficili da analizzare. E per capirli, potresti dover rivedere quel documento più volte (E forse anche altri documenti dipendenti!).

Questo è davvero un compito arduo per i non accademici come noi..

dopo-finire-questo-300x225-6282215

Personalmente, Trovo il compito di rivedere un articolo di ricerca, interpretare il punto cruciale e implementare il codice come un'abilità importante che ogni appassionato e praticante di deep learning dovrebbe possedere. L'implementazione pratica delle idee di ricerca fa emergere il processo di pensiero dell'autore e aiuta anche a trasformare tali idee in applicazioni industriali del mondo reale..

Quindi, in questo articolo (e la seguente serie di articoli) il motivo per cui scrivo è duplice:

  1. Consenti ai lettori di tenere il passo con la ricerca all'avanguardia suddividendo gli articoli di deep learning in concetti comprensibili.
  2. Impara a trasformare le idee di ricerca in codice per me stesso e incoraggia le persone a farlo contemporaneamente.

Questo articolo presuppone che tu abbia una buona conoscenza delle basi del deep learning.. Nel caso non ne avessi bisogno, o hai solo bisogno di un aggiornamento, controlla prima gli articoli qui sotto, poi torna qui presto:

Sommario

  • Riepilogo documento “Immergiti nelle convoluzioni”
    • Obiettivo del lavoro
    • Dettagli architettonici proposti
    • Metodologia di allenamento
  • Implementazione di GoogLeNet in Keras

Riepilogo documento “Immergiti nelle convoluzioni”

Questo articolo si concentra sulla carta “Scava più a fondo con le convoluzioni” da dove nasce l'idea distintiva della homenet. La rete domestica una volta era considerata un'architettura (il modello) deep learning di nuova generazione per risolvere i problemi di riconoscimento e rilevamento delle immagini.

Prestazioni rivoluzionarie in primo piano nell'ImageNet Visual Recognition Challenge (Su 2014), che è una piattaforma rinomata per il benchmarking degli algoritmi di riconoscimento e rilevamento delle immagini. insieme a questo, sono state avviate molte ricerche sulla creazione di nuove architetture di deep learning con idee innovative e di impatto.

Esamineremo le principali idee e suggerimenti proposti nel documento sopra menzionato e cercheremo di comprendere le tecniche in esso contenute. Nelle parole dell'autore:

“In questo articolo, nos centraremos en una arquitectura de neuronale rosso profunda eficiente para la visión por computadora, il cui nome in codice è Inception, che deriva il suo nome da (…) il famoso meme di internet” dobbiamo approfondire “.

a88-1164825

Sembra intrigante, no? Bene, Continua a leggere allora!

Obiettivo del lavoro

Esiste un modo semplice ma potente per creare modelli di deep learning migliori. Puoi semplicemente fare un modello più grande, sia in termini di profondità, vale a dire, numero di strati, o il numero di neuroni in ogni strato. Ma come puoi immaginare, questo spesso può creare complicazioni:

  • Più grande è il modello, più incline alla regolazione eccessiva. Esto es particularmente notable cuando los datos de addestramento son pequeños.
  • Aumentar la cantidad de parametri significa que necesita aumentar sus recursos computacionales existentes

Una soluzione per questo, come suggerisce il documento, è passare ad architetture di rete poco connesse che sostituiranno le architetture di rete completamente connesse, specialmente all'interno degli strati convoluzionali. Questa idea può essere concettualizzata nelle immagini seguenti:

screenshot-da-2018-10-16-10-52-13-206x300-3658357

Architettura densamente connessa

screenshot-da-2018-10-16-10-52-30-300x165-1701673

Architettura scarsamente connessa

Questo articolo propone una nuova idea di creare architetture profonde. Questo approccio consente di mantenere “budget computazionale”, aumentando la profondità e la larghezza della rete. Sembra troppo bello per essere vero! Ecco come appare l'idea concettualizzata:

googlenet-1196311

Vediamo un po' più in dettaglio l'architettura proposta.

Dettagli architettonici proposti

Il documento propone un nuovo tipo di architettura: GoogLeNet o Inception v1. Es básicamente una convolucional neuronale rosso (CNN) che cosa c'è che non va 27 strati profondi.. Di seguito il riepilogo del modello:

screenshot-da-2018-10-16-11-24-42-74x300-3793794

Nota nell'immagine sopra che c'è un livello chiamato livello iniziale. Questa è in realtà l'idea principale alla base del focus del documento. Il livello iniziale è il concetto centrale di un'architettura liberamente connessa.

screenshot-da-2018-10-16-10-52-30-300x1651-300x165-3297392

Idea di un modulo di partenza

Lascia che ti spieghi un po' più in dettaglio di cosa tratta un livello di avvio. Tomando un extracto del artículo:

“(Livello iniziale) è una combinazione di tutti quegli strati (vale a dire, copertina convolutiva 1 × 1, copertina convolutiva 3 × 3, copertina convolutiva 5 × 5) con i loro banchi di filtri di uscita concatenati in un unico vettore di uscita che costituisce l'ingresso del seguente scenario.”

Insieme agli strati sopra menzionati, ci sono due plugin principali nel livello iniziale originale:

  • copertina convolutiva 1 × 1 prima di applicare un'altra mano, che viene utilizzato principalmente per la riduzione della dimensionalità
  • Un livello di raggruppamento massimo parallelo, che fornisce un'altra opzione al livello iniziale
screenshot-da-2018-10-17-11-14-10-3445962

Livello iniziale

Per comprendere l'importanza della struttura del livello iniziale, l'autore attinge al principio hebbiano dell'apprendimento umano. Questo dice che “neuroni che si attivano insieme, si connettono insieme”. L'autore suggerisce che Quando si crea un post layer in un modello di deep learning, attenzione dovrebbe essere prestata agli apprendimenti dal livello precedente.

supponiamo, ad esempio, che uno strato del nostro modello di apprendimento profondo ha imparato a concentrarsi sulle singole parti di un viso. Il livello successivo della rete si concentrerebbe probabilmente sulla faccia generale dell'immagine per identificare i diversi oggetti presenti lì. Ora, per fare questo, il livello deve avere le dimensioni del filtro appropriate per rilevare oggetti diversi.

cat_vs_dog_explain4-300x231-5284051

È qui che viene alla ribalta lo strato iniziale. Consente agli strati interni di selezionare e scegliere quale dimensione del filtro sarà rilevante per conoscere le informazioni richieste. Quindi, anche se la dimensione del viso nella foto è diversa (come si vede nelle immagini qui sotto), il mantello funziona di conseguenza per riconoscere il viso. Per la prima immagine, probabilmente avresti bisogno di una dimensione del filtro più alta, mentre ne prenderei una più bassa per la seconda immagine.

screenshot-da-2018-10-17-11-42-40-300x103-5993337

Architettura generale, con tutte le specifiche, sembra così:

screenshot-da-2018-10-16-11-56-41-300x163-9994576

Metodologia di allenamento

Si noti che questa architettura è nata in gran parte perché gli autori hanno partecipato a una sfida di rilevamento e riconoscimento delle immagini.. Perciò, ce ne sono in abbondanza “campane e fischi” che hanno spiegato nel documento. Questi includono:

  • L'hardware che hanno usato per addestrare i modelli.
  • La tecnica di aumento dei dati per creare il set di dati di addestramento.
  • Gli iperparametri della rete neurale, come la tecnica di ottimizzazione e il programma del tasso di apprendimento.
  • Formazione ausiliaria necessaria per addestrare il modello.
  • Tecniche di assemblaggio utilizzate per costruire la presentazione finale.

Tra questi, la formazione ausiliaria svolta dagli autori è piuttosto interessante e nuova per natura. Quindi per ora ci concentreremo su questo.. I dettagli del resto delle tecniche possono essere presi dall'articolo stesso, o nella realizzazione che vedremo di seguito.

Per evitare che la parte centrale della rete "sparisca", gli autori hanno introdotto due classificatori ausiliari (i quadrati viola nell'immagine). Fondamentalmente, applicato softmax alle uscite di due dei moduli starter e calcolato una perdita ausiliaria sulle stesse etichette. Il función de pérdida total es una suma ponderada de la pérdida auxiliar y la pérdida real. Il valore di peso utilizzato sulla carta era 0,3 per ogni perdita ausiliaria.

Implementazione di GoogLeNet in Keras

Ora che hai capito l'architettura di GoogLeNet e l'intuizione che c'è dietro, È ora di avviare Python e implementare le nostre conoscenze utilizzando Keras!! Useremo il set di dati CIFAR-10 per questo scopo.

cifar-9579521

CIFAR-10 è un popolare set di dati per la classificazione delle immagini. Esso consiste in 60.000 immagini di 10 Lezioni (ogni classe è rappresentata come una riga nell'immagine sopra). Il set di dati è suddiviso in 50.000 immagini di allenamento e 10.000 immagini di prova.

Tieni presente che devi avere le librerie necessarie installate per implementare il codice che vedremo in questa sezione. Questo include Keras e TensorFlow (come backend per Keras). Puoi controllare il guida ufficiale all'installazione nel caso tu non abbia già installato Keras sulla tua macchina.

Ora che ci siamo occupati dei prerequisiti, possiamo finalmente iniziare a codificare la teoria che abbiamo trattato nelle sezioni precedenti. La prima cosa che dobbiamo fare è importare tutte le librerie e i moduli necessari che useremo nel codice.

importare duro
a partire dal hard.layers.core importare Strato
importare keras.backend come K
importare flusso tensoriale come tf
a partire dal hard.dataset importare cifar10
a partire dal hard.models importare Modello
a partire dal hard.layers importare Conv2D, MaxPool2D,  
    Ritirarsi, Denso, Ingresso, concatenare,      
    GlobalMediaPooling2D, Media Pooling2D,
    Appiattire

importare cv2 
importare insensibile come per esempio 
a partire dal hard.dataset importare cifar10 
a partire dal duro importare backend come K 
a partire dal hard.utils importare np_utils

importare matematica 
a partire dal hard.optimizers importare SGD 
a partire dal forte.richiamate importare Apprendimento RateScheduler

Quindi caricheremo il set di dati e faremo alcuni passaggi di pre-elaborazione. Questo è un compito fondamentale prima che il modello di deep learning sia addestrato.

num_classi = 10

def load_cifar10_data(img_rows, img_cols):

    # Caricare i set di formazione e convalida cifar10
    (X_treno, Y_train), (X_valido, Y_valido) = cifar10.caricare dati()

    # Ridimensiona le immagini dell'allenamento
    X_treno = per esempio.Vettore([cv2.ridimensionare(img, (img_rows,img_cols)) per img in X_treno[:,:,:,:]])
    X_valido = per esempio.Vettore([cv2.ridimensionare(img, (img_rows,img_cols)) per img in X_valido[:,:,:,:]])

    # Trasforma i bersagli in un formato compatibile con Keras
    Y_train = np_utils.to_categorical(Y_train, num_classi)
    Y_valido = np_utils.to_categorical(Y_valido, num_classi)
    
    X_treno = X_treno.come tipo('float32')
    X_valido = X_valido.come tipo('float32')

    # pre-elaborare i dati
    X_treno = X_treno / 255.0
    X_valido = X_valido / 255.0

    Restituzione X_treno, Y_train, X_valido, Y_valido
X_treno, y_train, X_test, y_test = load_cifar10_data(224, 224)

Ora, definiremo la nostra architettura di deep learning. Definiremo rapidamente una funzione per farlo, Quello, quando ti vengono fornite le informazioni necessarie, restituisce l'intero livello iniziale.

def inception_module(X,
                     filtri_1x1,
                     filtri_3x3_riduci,
                     filtri_3x3,
                     filtri_5x5_riduci,
                     filtri_5x5,
                     filter_pool_proj,
                     nome=Nessuno):
    
    conv_1x1 = Conv2D(filtri_1x1, (1, 1), imbottitura='stesso', Attivazione='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(X)
    
    conv_3x3 = Conv2D(filtri_3x3_riduci, (1, 1), imbottitura='stesso', Attivazione='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(X)
    conv_3x3 = Conv2D(filtri_3x3, (3, 3), imbottitura='stesso', Attivazione='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(conv_3x3)

    conv_5x5 = Conv2D(filtri_5x5_riduci, (1, 1), imbottitura='stesso', Attivazione='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(X)
    conv_5x5 = Conv2D(filtri_5x5, (5, 5), imbottitura='stesso', Attivazione='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(conv_5x5)

    pool_proj = MaxPool2D((3, 3), passi avanti=(1, 1), imbottitura='stesso')(X)
    pool_proj = Conv2D(filter_pool_proj, (1, 1), imbottitura='stesso', Attivazione='relu', kernel_initializer=kernel_init, bias_initializer=bias_init)(pool_proj)

    produzione = concatenare([conv_1x1, conv_3x3, conv_5x5, pool_proj], asse=3, nome=nome)
    
    Restituzione produzione

Quindi creeremo l'architettura GoogLeNet, come indicato nel documento.

kernel_init = duro.inizializzatori.glorot_uniform()
bias_init = duro.inizializzatori.Costante(valore=0.2)
screenshot-da-2018-10-16-11-56-41-300x163-9994576
input_layer = Ingresso(forma=(224, 224, 3))

X = Conv2D(64, (7, 7), imbottitura='stesso', passi avanti=(2, 2), Attivazione='relu', nome='conv_1_7x7/2', kernel_initializer=kernel_init, bias_initializer=bias_init)(input_layer)
X = MaxPool2D((3, 3), imbottitura='stesso', passi avanti=(2, 2), nome='max_pool_1_3x3/2')(X)
X = Conv2D(64, (1, 1), imbottitura='stesso', passi avanti=(1, 1), Attivazione='relu', nome='conv_2a_3x3/1')(X)
X = Conv2D(192, (3, 3), imbottitura='stesso', passi avanti=(1, 1), Attivazione='relu', nome='conv_2b_3x3/1')(X)
X = MaxPool2D((3, 3), imbottitura='stesso', passi avanti=(2, 2), nome='max_pool_2_3x3/2')(X)

X = inception_module(X,
                     filtri_1x1=64,
                     filtri_3x3_riduci=96,
                     filtri_3x3=128,
                     filtri_5x5_riduci=16,
                     filtri_5x5=32,
                     filter_pool_proj=32,
                     nome='inizio_3a')

X = inception_module(X,
                     filtri_1x1=128,
                     filtri_3x3_riduci=128,
                     filtri_3x3=192,
                     filtri_5x5_riduci=32,
                     filtri_5x5=96,
                     filter_pool_proj=64,
                     nome='inizio_3b')

X = MaxPool2D((3, 3), imbottitura='stesso', passi avanti=(2, 2), nome='max_pool_3_3x3/2')(X)

X = inception_module(X,
                     filtri_1x1=192,
                     filtri_3x3_riduci=96,
                     filtri_3x3=208,
                     filtri_5x5_riduci=16,
                     filtri_5x5=48,
                     filter_pool_proj=64,
                     nome='inizio_4a')


x1 = Media Pooling2D((5, 5), passi avanti=3)(X)
x1 = Conv2D(128, (1, 1), imbottitura='stesso', Attivazione='relu')(x1)
x1 = Appiattire()(x1)
x1 = Denso(1024, Attivazione='relu')(x1)
x1 = Ritirarsi(0.7)(x1)
x1 = Denso(10, Attivazione='softmax', nome='output_ausiliario_1')(x1)

X = inception_module(X,
                     filtri_1x1=160,
                     filtri_3x3_riduci=112,
                     filtri_3x3=224,
                     filtri_5x5_riduci=24,
                     filtri_5x5=64,
                     filter_pool_proj=64,
                     nome='inizio_4b')

X = inception_module(X,
                     filtri_1x1=128,
                     filtri_3x3_riduci=128,
                     filtri_3x3=256,
                     filtri_5x5_riduci=24,
                     filtri_5x5=64,
                     filter_pool_proj=64,
                     nome='inizio_4c')

X = inception_module(X,
                     filtri_1x1=112,
                     filtri_3x3_riduci=144,
                     filtri_3x3=288,
                     filtri_5x5_riduci=32,
                     filtri_5x5=64,
                     filter_pool_proj=64,
                     nome='inizio_4d')


x2 = Media Pooling2D((5, 5), passi avanti=3)(X)
x2 = Conv2D(128, (1, 1), imbottitura='stesso', Attivazione='relu')(x2)
x2 = Appiattire()(x2)
x2 = Denso(1024, Attivazione='relu')(x2)
x2 = Ritirarsi(0.7)(x2)
x2 = Denso(10, Attivazione='softmax', nome='output_ausiliario_2')(x2)

X = inception_module(X,
                     filtri_1x1=256,
                     filtri_3x3_riduci=160,
                     filtri_3x3=320,
                     filtri_5x5_riduci=32,
                     filtri_5x5=128,
                     filter_pool_proj=128,
                     nome='inizio_4e')

X = MaxPool2D((3, 3), imbottitura='stesso', passi avanti=(2, 2), nome='max_pool_4_3x3/2')(X)

X = inception_module(X,
                     filtri_1x1=256,
                     filtri_3x3_riduci=160,
                     filtri_3x3=320,
                     filtri_5x5_riduci=32,
                     filtri_5x5=128,
                     filter_pool_proj=128,
                     nome='inizio_5a')

X = inception_module(X,
                     filtri_1x1=384,
                     filtri_3x3_riduci=192,
                     filtri_3x3=384,
                     filtri_5x5_riduci=48,
                     filtri_5x5=128,
                     filter_pool_proj=128,
                     nome='inizio_5b')

X = GlobalMediaPooling2D(nome='avg_pool_5_3x3/1')(X)

X = Ritirarsi(0.4)(X)

X = Denso(10, Attivazione='softmax', nome='produzione')(X)
modello = Modello(input_layer, [X, x1, x2], nome='inizio_v1')

Riassumiamo il nostro modello per verificare se il nostro lavoro finora è andato bene.

__________________________________________________________________________________________________
Strato (genere)                    Parametro forma di output #     Collegato a
================================================== ================================================
ingresso_1 (InputLayer)            (Nessuno, 224, 224, 3)  0                                            
__________________________________________________________________________________________________
conv_1_7x7/2 (Conv2D)           (Nessuno, 112, 112, 64) 9472        ingresso_1[0][0]                    
__________________________________________________________________________________________________
max_pool_1_3x3/2 (MaxPooling2D) (Nessuno, 56, 56, 64)   0           conv_1_7x7/2[0][0]               
__________________________________________________________________________________________________
norma1 (LRN2D)                   (Nessuno, 56, 56, 64)   0           max_pool_1_3x3/2[0][0]           
__________________________________________________________________________________________________
...
...
...
dropout_3 (Ritirarsi)             (Nessuno, 1024)         0           avg_pool_5_3x3/1[0][0]           
__________________________________________________________________________________________________
dropout_1 (Ritirarsi)             (Nessuno, 1024)         0           denso_1[0][0]                    
__________________________________________________________________________________________________
dropout_2 (Ritirarsi)             (Nessuno, 1024)         0           densa_2[0][0]                    
__________________________________________________________________________________________________
produzione (Denso)                  (Nessuno, 10)           10250       dropout_3[0][0]                  
__________________________________________________________________________________________________
auxilliary_output_1 (Denso)     (Nessuno, 10)           10250       dropout_1[0][0]                  
__________________________________________________________________________________________________
auxilliary_output_2 (Denso)     (Nessuno, 10)           10250       dropout_2[0][0]                  
================================================== ================================================
Parametri totali: 10,334,030
Parametri addestrabili: 10,334,030
Parametri non addestrabili: 0
__________________________________________________________________________________________________

Il modello sembra buono, come puoi misurare dall'output sopra?. Possiamo aggiungere alcuni ritocchi finali prima di addestrare il nostro modello. Definiremo quanto segue:

  • Función de pérdida para cada capa de salida
  • Peso assegnato a quel livello di output
  • Funzione di ottimizzazione, che viene modificato per includere una diminuzione di peso dopo ogni 8 epoche.
  • Metrica di valutazione
epoche = 25
valore_iniziale = 0.01

def decadimento(epoca, passi=100):
    valore_iniziale = 0.01
    gocciolare = 0.96
    epochs_drop = 8
    lrate = valore_iniziale * matematica.pow(gocciolare, matematica.pavimento((1+epoca)/epochs_drop))
    Restituzione lrate

sgd = SGD(lr=valore_iniziale, quantità di moto=0.9, nesterov=falso)

lr_sc = Apprendimento RateScheduler(decadimento, verboso=1)

modello.compilare(perdita=['categorical_crossentropy', 'categorical_crossentropy', 'categorical_crossentropy'], perdita_pesi=[1, 0.3, 0.3], ottimizzatore=sgd, metrica=['precisione'])

Il nostro modello è ora pronto! Provalo per vedere come funziona.

storia = modello.in forma(X_treno, [y_train, y_train, y_train], validation_data=(X_test, [y_test, y_test, y_test]), epoche=epoche, dimensione del lotto=256, richiamate=[lr_sc])

Di seguito è riportato il risultato che ho ottenuto durante l'addestramento del modello:

Allenati 50000 campioni, convalidare su 10000 campioni
Epoca 1/25

Epoca 00001: LearningRateScheduler che riduce il tasso di apprendimento a 0.01.
50000/50000 [==============================] - 188s 4ms/passo - perdita: 3.7140 - output_loss: 2.3280 - auxilliary_output_1_loss: 2.3101 - auxilliary_output_2_loss: 2.3099 - output_acc: 0.1030 - auxilliary_output_1_acc: 0.1029 - auxilliary_output_2_acc: 0.0992 - val_loss: 3.6898 - val_output_loss: 2.3085 - val_auxilliary_output_1_loss: 2.3018 - val_auxilliary_output_2_loss: 2.3025 - val_output_acc: 0.1000 - val_auxilliary_output_1_acc: 0.1017 - val_auxilliary_output_2_acc: 0.0984
Epoca 2/25

Epoca 00002: LearningRateScheduler che riduce il tasso di apprendimento a 0.01.
50000/50000 [==============================] - 181s 4ms/passo - perdita: 3.6635 - output_loss: 2.2894 - auxilliary_output_1_loss: 2.2817 - auxilliary_output_2_loss: 2.2987 - output_acc: 0.1161 - auxilliary_output_1_acc: 0.1321 - auxilliary_output_2_acc: 0.1151 - val_loss: 3.6559 - val_output_loss: 2.3095 - val_auxilliary_output_1_loss: 2.2315 - val_auxilliary_output_2_loss: 2.2565 - val_output_acc: 0.1466 - val_auxilliary_output_1_acc: 0.1478 - val_auxilliary_output_2_acc: 0.1417
Epoca 3/25

Epoca 00003: LearningRateScheduler che riduce il tasso di apprendimento a 0.01.
50000/50000 [==============================] - 180s 4ms/passo - perdita: 3.2981 - output_loss: 2.0660 - auxilliary_output_1_loss: 2.0414 - auxilliary_output_2_loss: 2.0653 - output_acc: 0.2212 - auxilliary_output_1_acc: 0.2363 - auxilliary_output_2_acc: 0.2256 - val_loss: 3.1812 - val_output_loss: 2.0064 - val_auxilliary_output_1_loss: 1.9372 - val_auxilliary_output_2_loss: 1.9787 - val_output_acc: 0.2578 - val_auxilliary_output_1_acc: 0.2909 - val_auxilliary_output_2_acc: 0.2767
Epoca 4/25

Epoca 00004: LearningRateScheduler che riduce il tasso di apprendimento a 0.01.
50000/50000 [==============================] - 181s 4ms/passo - perdita: 3.0797 - output_loss: 1.9258 - auxilliary_output_1_loss: 1.9214 - auxilliary_output_2_loss: 1.9248 - output_acc: 0.2803 - auxilliary_output_1_acc: 0.2914 - auxilliary_output_2_acc: 0.2872 - val_loss: 3.0099 - val_output_loss: 1.8852 - val_auxilliary_output_1_loss: 1.8900 - val_auxilliary_output_2_loss: 1.8589 - val_output_acc: 0.3080 - val_auxilliary_output_1_acc: 0.3122 - val_auxilliary_output_2_acc: 0.3296
Epoca 5/25

Epoca 00005: LearningRateScheduler che riduce il tasso di apprendimento a 0.01.
50000/50000 [==============================] - 181s 4ms/passo - perdita: 2.8427 - output_loss: 1.7733 - auxilliary_output_1_loss: 1.7933 - auxilliary_output_2_loss: 1.7711 - output_acc: 0.3454 - auxilliary_output_1_acc: 0.3485 - auxilliary_output_2_acc: 0.3509 - val_loss: 2.6623 - val_output_loss: 1.6788 - val_auxilliary_output_1_loss: 1.6531 - val_auxilliary_output_2_loss: 1.6250 - val_output_acc: 0.3922 - val_auxilliary_output_1_acc: 0.4094 - val_auxilliary_output_2_acc: 0.4103
Epoca 6/25
...
...
...
Epoca 00024: LearningRateScheduler che riduce il tasso di apprendimento a 0.008847359999999999.
50000/50000 [==============================] - 181s 4ms/passo - perdita: 0.7803 - output_loss: 0.3791 - auxilliary_output_1_loss: 0.7608 - auxilliary_output_2_loss: 0.5767 - output_acc: 0.8665 - auxilliary_output_1_acc: 0.7332 - auxilliary_output_2_acc: 0.7962 - val_loss: 1.0228 - val_output_loss: 0.6043 - val_auxilliary_output_1_loss: 0.7442 - val_auxilliary_output_2_loss: 0.6508 - val_output_acc: 0.7970 - val_auxilliary_output_1_acc: 0.7408 - val_auxilliary_output_2_acc: 0.7724
Epoca 25/25

Epoca 00025: LearningRateScheduler che riduce il tasso di apprendimento a 0.008847359999999999.
50000/50000 [==============================] - 181s 4ms/passo - perdita: 0.7411 - output_loss: 0.3543 - auxilliary_output_1_loss: 0.7349 - auxilliary_output_2_loss: 0.5545 - output_acc: 0.8755 - auxilliary_output_1_acc: 0.7408 - auxilliary_output_2_acc: 0.8060 - val_loss: 0.9524 - val_output_loss: 0.5383 - val_auxilliary_output_1_loss: 0.7346 - val_auxilliary_output_2_loss: 0.6458 - val_output_acc: 0.8191 - val_auxilliary_output_1_acc: 0.7435 - val_auxilliary_output_2_acc: 0.7791

Il nostro modello ha fornito una precisione impressionante del 80% + nel set di convalida, il che dimostra che vale davvero la pena provare questa architettura del modello.

Note finali

Questo è stato davvero un bell'articolo da scrivere e spero che tu lo abbia trovato ugualmente utile. Inception v1 è stato il punto focale di questo articolo, in cui ho spiegato il nocciolo di questo framework e dimostrato come implementarlo da zero in Keras.

Nei prossimi articoli, Mi concentrerò sui progressi nelle architetture Inception. Questi progressi sono stati dettagliati negli articoli successivi., vale a dire, Inizio v2, Inizio v3, eccetera. E se, sono intriganti come suggerisce il nome, Quindi restate sintonizzati!

Se hai qualche suggerimento / commento relativo all'articolo, postalo nella sezione commenti qui sotto.

Iscriviti alla nostra Newsletter

Non ti invieremo posta SPAM. Lo odiamo quanto te.