Cosa devo fare quando la mia rete neurale non impara?


148

Sto allenando una rete neurale ma la perdita di allenamento non diminuisce. Come posso risolvere questo problema?

Non sto chiedendo di adattamento eccessivo o regolarizzazione. Sto chiedendo come risolvere il problema in cui le prestazioni della mia rete non migliorano sul set di formazione .


Questa domanda è intenzionalmente generale in modo che altre domande su come addestrare una rete neurale possano essere chiuse come duplicate di questa, con l'atteggiamento che "se dai a un uomo un pesce gli dai da mangiare per un giorno, ma se insegni a un uomo a pescare, puoi nutrirlo per il resto della sua vita. " Vedi questo thread Meta per una discussione: qual è il modo migliore per rispondere alle domande "la mia rete neurale non funziona, per favore correggi"?

Se la tua rete neurale non si generalizza bene, vedi: Cosa devo fare quando la mia rete neurale non si generalizza bene?


1
Ecco il caso in cui la NN non ha potuto progredire. youtu.be/iakFfOmanJU?t=144
Joshua,

4
Il blog di Ivanov " Ragioni per cui la tua rete neurale non funziona ", in particolare le sezioni II, III e IV, potrebbe essere utile.
user5228

Risposte:


187

Il test unitario è tuo amico

C'è un detto tra gli scrittori che "Tutta la scrittura è riscrittura", cioè la maggior parte della scrittura è la revisione. Per i programmatori (o almeno i data scientist) l'espressione potrebbe essere riformulata come "Tutto il codice è debug".

Ogni volta che scrivi un codice, devi verificare che funzioni come previsto. Il metodo migliore che abbia mai trovato per verificare la correttezza consiste nel suddividere il codice in piccoli segmenti e verificare che ciascun segmento funzioni. Questo può essere fatto confrontando l'output del segmento con quello che sai essere la risposta corretta. Questo si chiama unit test . Scrivere buoni test unitari è un elemento chiave per diventare un buon statistico / scienziato di dati / esperto di apprendimento automatico / professionista della rete neurale. Semplicemente non c'è sostituto.

Devi verificare che il tuo codice sia privo di bug prima di poter ottimizzare le prestazioni della rete! Altrimenti, potresti anche riorganizzare le sedie a sdraio sul Titanic RMS .

Esistono due caratteristiche delle reti neurali che rendono la verifica ancora più importante rispetto ad altri tipi di apprendimento automatico o modelli statistici.

  1. Le reti neurali non sono algoritmi "standardizzati" come lo sono la regressione logistica o forestale casuale. Anche per le reti semplici, feed-forward, l'onere spetta in gran parte all'utente prendere numerose decisioni su come la rete è configurata, connessa, inizializzata e ottimizzata. Ciò significa scrivere codice e scrivere codice significa debug.

  2. Anche quando un codice di rete neurale viene eseguito senza sollevare un'eccezione, la rete può ancora avere bug! Questi bug potrebbero persino essere il tipo insidioso per il quale la rete si allenerà, ma rimarranno bloccati in una soluzione non ottimale, oppure la rete risultante non avrà l'architettura desiderata. ( Questo è un esempio della differenza tra un errore sintattico e semantico .)

Questo post Medium , " Come testare il codice di apprendimento automatico delle unità ", di Chase Roberts, esamina in dettaglio i test di unità per i modelli di apprendimento automatico. Ho preso in prestito questo esempio di codice errato dall'articolo:

def make_convnet(input_image):
    net = slim.conv2d(input_image, 32, [11, 11], scope="conv1_11x11")
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv2_5x5")
    net = slim.max_pool2d(net, [4, 4], stride=4, scope='pool1')
    net = slim.conv2d(input_image, 64, [5, 5], scope="conv3_5x5")
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv4_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool2')
    net = slim.conv2d(input_image, 128, [3, 3], scope="conv5_3x3")
    net = slim.max_pool2d(net, [2, 2], scope='pool3')
    net = slim.conv2d(input_image, 32, [1, 1], scope="conv6_1x1")
    return net

Vedi l'errore? Molte delle diverse operazioni non vengono effettivamente utilizzate perché i risultati precedenti vengono sovrascritti con nuove variabili. L'uso di questo blocco di codice in una rete continuerà ad allenarsi e i pesi si aggiorneranno e la perdita potrebbe persino diminuire, ma il codice sicuramente non sta facendo ciò che era previsto. (L'autore è anche incoerente sull'uso di virgolette singole o doppie, ma è puramente stilistico.)

Gli errori di programmazione più comuni relativi alle reti neurali sono

  • Le variabili vengono create ma mai utilizzate (in genere a causa di errori di copia e incolla);
  • Le espressioni per gli aggiornamenti del gradiente non sono corrette;
  • Gli aggiornamenti del peso non vengono applicati;
  • Le funzioni di perdita non sono misurate sulla scala corretta (ad esempio, la perdita di entropia può essere espressa in termini di probabilità o logit)
  • La perdita non è appropriata per l'attività (ad esempio, utilizzando la perdita categorica incrociata entropia per un'attività di regressione).

Striscia prima di camminare; Cammina prima di correre

Reti neurali ampie e profonde e reti neurali con cablaggi esotici, sono la cosa calda in questo momento nell'apprendimento automatico. Ma queste reti non sono nate pienamente formate nell'esistenza; i loro progettisti li costruirono da unità più piccole. Innanzitutto, crea una piccola rete con un singolo livello nascosto e verifica che funzioni correttamente. Quindi aggiungere in modo incrementale ulteriore complessità del modello e verificare che anche ognuna di queste funzioni.

  • Troppo pochi neuroni in uno strato può limitare la rappresentazione che la rete apprende, causando sotto-montaggio. Troppi neuroni possono causare un eccesso di adattamento perché la rete "memorizzerà" i dati di allenamento.

    Anche se puoi dimostrare che, matematicamente, è necessario solo un piccolo numero di neuroni per modellare un problema, spesso accade che avere "pochi" neuroni rende più facile per l'ottimizzatore trovare una "buona" configurazione. (Ma non credo che nessuno comprenda appieno il motivo per cui questo è il caso.) Fornisco qui un esempio di questo nel contesto del problema XOR: le mie iterazioni non sono necessarie per addestrare NN per XOR con MSE <0,001 troppo alto? .

  • La scelta del numero di livelli nascosti consente alla rete di apprendere un'astrazione dai dati grezzi. Il deep learning è di gran moda in questi giorni e le reti con un gran numero di livelli hanno mostrato risultati impressionanti. Ma l'aggiunta di troppi layer nascosti può comportare rischi di overfitting o rendere molto difficile l'ottimizzazione della rete.

  • Scegliere un cablaggio di rete intelligente può fare molto del lavoro per te. La tua fonte di dati è adatta a architetture di rete specializzate? Le reti neurali convoluzionali possono ottenere risultati impressionanti su fonti di dati "strutturate", dati di immagini o audio. Le reti neurali ricorrenti possono fare bene su tipi di dati sequenziali, come il linguaggio naturale o i dati di serie temporali. Le connessioni residue possono migliorare le reti di feed-forward profonde.

L'allenamento della rete neurale è come il lock picking

Per ottenere risultati allo stato dell'arte, o anche semplicemente buoni, è necessario aver impostato tutte le parti configurate per funzionare bene insieme . Impostare una configurazione di rete neurale che apprende in realtà è un po 'come scegliere un lucchetto: tutti i pezzi devono essere allineati nel modo giusto. Così come non è sufficiente avere un solo bicchiere nel posto giusto, né è sufficiente che solo l'architettura, o solo l'ottimizzatore, siano impostati correttamente.

Ottimizzare le scelte di configurazione non è così semplice come dire che un tipo di scelta di configurazione (ad es. Velocità di apprendimento) è più o meno importante di un'altra (ad es. Numero di unità), poiché tutte queste scelte interagiscono con tutte le altre scelte, quindi uno la scelta può fare bene in combinazione con un'altra scelta fatta altrove .

Questo è un elenco non esaustivo delle opzioni di configurazione che non sono anche opzioni di regolarizzazione o opzioni di ottimizzazione numerica.

Tutti questi argomenti sono aree attive di ricerca.

L'ottimizzazione non convessa è difficile

La funzione oggettiva di una rete neurale è convessa solo quando non ci sono unità nascoste, tutte le attivazioni sono lineari e la matrice di progettazione è a pieno titolo, poiché questa configurazione è identicamente un normale problema di regressione.

In tutti gli altri casi, il problema dell'ottimizzazione non è convesso e l'ottimizzazione non convessa è difficile. Le sfide della formazione delle reti neurali sono ben note (vedi: Perché è difficile addestrare reti neurali profonde? ). Inoltre, le reti neurali hanno un numero molto grande di parametri, il che ci limita ai soli metodi del primo ordine (vedi: Perché il metodo di Newton non è ampiamente usato nell'apprendimento automatico? ). Questa è un'area di ricerca molto attiva.

  • Impostando una velocità di apprendimento troppo grande, l'ottimizzazione divergerà, poiché salterai da un lato del "canyon" all'altro. L'impostazione di un valore troppo basso ti impedirà di compiere progressi reali e probabilmente consentirà al rumore inerente a SGD di sopraffare le stime del gradiente.

  • Il ritaglio del gradiente ridimensiona la norma del gradiente se supera una certa soglia. Pensavo che si trattasse di un parametro imposta e dimentica, in genere a 1.0, ma ho scoperto che avrei potuto migliorare notevolmente un modello di linguaggio LSTM impostandolo su 0,25. Non so perché.

  • La pianificazione della frequenza di apprendimento può ridurre la frequenza di apprendimento nel corso della formazione. Nella mia esperienza, provare a usare la pianificazione è molto simile a regex : sostituisce un problema ("Come posso imparare a continuare dopo una certa epoca?") Con due problemi ("Come posso imparare a continuare dopo una certa epoca? ? "e" Come faccio a scegliere un buon programma? "). Altre persone insistono sul fatto che la programmazione è essenziale. Ti lascio decidere.

  • La scelta di una buona dimensione del minibatch può influenzare indirettamente il processo di apprendimento, dal momento che un mini-batch più grande tenderà ad avere una varianza minore ( ) rispetto a un mini-batch più piccolo. Volete che il mini-batch sia abbastanza grande da essere informativo sulla direzione del gradiente, ma abbastanza piccolo da consentire a SGD di regolarizzare la vostra rete.

  • Ci sono una serie di varianti sulla discesa gradiente stocastica che usano lo slancio, i tassi di apprendimento adattivo, gli aggiornamenti di Nesterov e così via per migliorare su SGD vaniglia. Progettare un ottimizzatore migliore è molto un'area di ricerca attiva. Qualche esempio:

  • Quando è uscito per la prima volta, l'ottimizzatore Adam ha suscitato molto interesse. Ma alcune ricerche recenti hanno scoperto che SGD con slancio può superare i metodi adattivi di gradiente per le reti neurali. " Il valore marginale dei metodi del gradiente adattivo nell'apprendimento automatico " di Ashia C. Wilson, Rebecca Roelofs, Mitchell Stern, Nathan Srebro, Benjamin Recht

  • D'altro canto, questo documento molto recente propone un nuovo ottimizzatore adattativo del tasso di apprendimento che presumibilmente colma il divario tra i metodi del tasso adattivo e la SGD. " Colmare il divario di generalizzazione dei metodi adattivi di gradiente nella formazione di reti neurali profonde " di Jinghui Chen, Quanquan Gu

    È stato osservato che i metodi di gradiente adattivo, che adottano informazioni storiche sul gradiente per regolare automaticamente il tasso di apprendimento, sono peggiori della discesa gradiente stocastica (SGD) con slancio nell'allenamento delle reti neurali profonde. Questo lascia un problema aperto per colmare il divario di generalizzazione dei metodi di gradiente adattivo. In questo lavoro, mostriamo che i metodi di gradiente adattivo come Adam, Amsgrad, sono talvolta "troppo adattati". Progettiamo un nuovo algoritmo, chiamato metodo di stima del momento parzialmente adattivo (Padam), che unifica Adam / Amsgrad con SGD per ottenere il meglio da entrambi i mondi. Esperimenti su benchmark standard mostrano che Padam è in grado di mantenere un rapido tasso di convergenza come Adam / Amsgrad mentre si generalizza e SGD nella formazione di reti neurali profonde.

Normalizzazione

La scala dei dati può fare una grande differenza sulla formazione.

regolarizzazione

La scelta e l'ottimizzazione della regolarizzazione della rete è una parte fondamentale della costruzione di un modello che si generalizza bene (vale a dire, un modello che non si adatta ai dati di addestramento). Tuttavia, nel momento in cui la tua rete sta lottando per ridurre la perdita dei dati di addestramento - quando la rete non sta imparando - la regolarizzazione può oscurare qual è il problema.

Quando la mia rete non impara, spengo tutta la regolarizzazione e verifico che la rete non regolarizzata funzioni correttamente. Quindi aggiungo nuovamente ogni pezzo di regolarizzazione e verifico che ciascuno di essi funzioni lungo il percorso.

Questa tattica può individuare dove una certa regolarizzazione potrebbe essere impostata male. Alcuni esempi sono

Tieni un diario degli esperimenti

Quando installo una rete neurale, non codifico in modo rigido nessuna impostazione di parametro. Invece, lo faccio in un file di configurazione (ad es. JSON) che viene letto e utilizzato per popolare i dettagli della configurazione di rete in fase di esecuzione. Conservo tutti questi file di configurazione. Se apporto qualche modifica ai parametri, creo un nuovo file di configurazione. Infine, aggiungo come commenti tutte le perdite per epoca per formazione e validazione.

K

Ad esempio, volevo conoscere i modelli di linguaggio LSTM, quindi ho deciso di creare un bot Twitter che scrive nuovi tweet in risposta ad altri utenti di Twitter. Ci ho lavorato nel tempo libero, tra la scuola di specializzazione e il mio lavoro. Ci sono voluti circa un anno e ho ripetuto circa 150 modelli diversi prima di arrivare a un modello che faceva quello che volevo: generare un nuovo testo in lingua inglese che (in un certo senso) ha senso. (Un punto critico, e parte del motivo per cui sono stati fatti così tanti tentativi, è che non era sufficiente ottenere semplicemente una perdita fuori campione, poiché i primi modelli a bassa perdita erano riusciti a memorizzare i dati di addestramento, quindi stava solo riproducendo alla lettera i blocchi di testo germano in risposta ai prompt - ci sono voluti alcuni ritocchi per rendere il modello più spontaneo e avere comunque una perdita ridotta).


11
Un sacco di buoni consigli lì. È interessante vedere quanti dei tuoi commenti sono simili ai commenti che ho fatto (o ho visto altri fare) in relazione alla stima del debug di parametri o previsioni per modelli complessi con schemi di campionamento MCMC. (Ad esempio, il codice potrebbe sembrare funzionare quando non è implementato correttamente.)
Glen_b

11
@Glen_b Non credo che le migliori pratiche di codifica ricevano un'enfasi sufficiente nella maggior parte dei curricula di statistiche / apprendimento automatico, motivo per cui ho sottolineato questo punto così pesantemente. Ho visto un numero di post su NN in cui OP ha lasciato un commento del tipo "oh ho trovato un bug ora funziona".
Sycorax,

7
Insegno un corso di programmazione per la scienza dei dati in Python e il primo giorno facciamo funzioni e test unitari come concetti primari. Combattere la buona battaglia.
Matthew Drury,

8
+1 per "Tutto il codice è debug". Sono sorpreso di quanti poster su SO sembrano pensare che la codifica sia un semplice esercizio che richiede poco sforzo; che si aspettano che il loro codice funzioni correttamente la prima volta che lo eseguono; e che sembrano non essere in grado di procedere quando non lo fa. La cosa divertente è che hanno ragione: la programmazione è semplice, ma la programmazione è difficile.
Bob Jarvis,

41

Le risposte pubblicate sono fantastiche e volevo aggiungere alcuni "Sanity Check" che mi hanno aiutato molto in passato.

1) Allena il tuo modello su un singolo punto dati. Se funziona, addestralo su due ingressi con uscite diverse.

Questo verifica alcune cose. Innanzitutto, ti mostra rapidamente che il tuo modello è in grado di apprendere controllando se il tuo modello è in grado di equipaggiare troppo i tuoi dati. Nel mio caso, faccio costantemente errori stupidi nel fare Dense(1,activation='softmax')vs Dense(1,activation='sigmoid')per le previsioni binarie, e il primo dà risultati spazzatura.

Se il tuo modello non è in grado di adattarsi ad alcuni punti dati, o è troppo piccolo (cosa improbabile nell'età di oggi) o qualcosa non va nella sua struttura o nell'algoritmo di apprendimento.

2) Prestare attenzione alla perdita iniziale.

L=-0.3ln(0.5)-0.7ln(0.5)0.7

-0.3ln(0.99)-0.7ln(0.01)=3.2

Puoi studiarlo ulteriormente facendo prevedere il tuo modello su alcune migliaia di esempi e quindi istogramma degli output. Ciò è particolarmente utile per verificare che i tuoi dati siano correttamente normalizzati. Ad esempio, se si prevede che l'output sia fortemente inclinato verso 0, potrebbe essere una buona idea trasformare gli output previsti (i dati di training) prendendo le radici quadrate dell'output previsto. Ciò eviterà problemi di gradiente per sigmoidi saturi, in uscita.

3) Generalizza gli output del tuo modello per il debug

Ad esempio, immagina di utilizzare un LSTM per fare previsioni dai dati delle serie temporali. Forse nel tuo esempio, ti preoccupi solo della previsione più recente, quindi il tuo LSTM genera un singolo valore e non una sequenza. Passa a LSTM per restituire le previsioni ad ogni passaggio (in keras, questo è return_sequences=True). Quindi puoi dare un'occhiata alle tue uscite a stato nascosto dopo ogni passaggio e assicurarti che siano effettivamente diverse. Un'applicazione di questo è assicurarsi che quando si mascherano le sequenze (ovvero riempiendole di dati per renderle uguali di lunghezza), LSTM ignori correttamente i dati mascherati. Senza generalizzare il tuo modello non troverai mai questo problema .

4) Guarda i singoli livelli

Tensorboard fornisce un modo utile per visualizzare gli output del layer . Questo può aiutare a garantire che gli ingressi / le uscite siano correttamente normalizzati in ogni strato. Può anche catturare attivazioni con errori. Puoi anche eseguire una query degli output dei livelli in keras su un batch di previsioni e quindi cercare layer che hanno attivazioni distorte in modo sospetto (tutti 0 o tutti diversi da zero).

5) Costruire prima un modello più semplice

Hai deciso che l'approccio migliore per risolvere il tuo problema è utilizzare una CNN combinata con un rilevatore di bounding box, che elabora ulteriormente le colture di immagini e quindi utilizza un LSTM per combinare tutto. Sono necessari 10 minuti solo per inizializzare il tuo modello GPU.

Invece, crea una serie di dati falsi (stessa forma) e suddividi il tuo modello in componenti. Quindi crea modelli fittizi al posto di ciascun componente (la tua "CNN" potrebbe essere solo una singola convoluzione a 20 falcate di 20 metri, l'LSTM con solo 2 unità nascoste). Questo ti aiuterà ad assicurarti che la struttura del tuo modello sia corretta e che non ci siano problemi estranei. Ho lottato per un po 'con un tale modello e quando ho provato una versione più semplice, ho scoperto che uno dei livelli non veniva mascherato correttamente a causa di un bug di keras. Puoi interrogare facilmente (e rapidamente ) i livelli del modello interno e vedere se hai configurato correttamente il tuo grafico.

6) Standardizzare le versioni di preelaborazione e pacchetto

Le reti neurali in particolare sono estremamente sensibili alle piccole modifiche nei dati. Ad esempio, due popolari pacchetti di caricamento delle immagini sono cv2e PIL. Proprio in virtù dell'apertura di un JPEG, entrambi questi pacchetti produrranno immagini leggermente diverse . Le differenze sono di solito molto piccole, ma a volte vedrai cali nelle prestazioni del modello a causa di questo tipo di cose. Inoltre rende il debug un incubo: hai ottenuto un punteggio di convalida durante l'allenamento e in seguito usi un caricatore diverso e ottieni una precisione diversa sullo stesso set di dati dannati.

Quindi, se stai scaricando il modello di qualcuno da Github, presta molta attenzione alla sua preelaborazione. Quali caricatori di immagini usano? Quali routine di preelaborazione delle immagini usano? Quando si ridimensiona un'immagine, quale interpolazione usano? Prima ridimensionano e poi normalizzano l'immagine? O viceversa? Qual è l'ordine dei canali per le immagini RGB?

Il modo più sicuro di standardizzare i pacchetti è utilizzare un requirements.txtfile che delinea tutti i pacchetti proprio come nella configurazione del sistema di allenamento, fino ai keras==2.1.5numeri di versione. In teoria, quindi, l'utilizzo di Docker insieme alla stessa GPU del sistema di allenamento dovrebbe produrre gli stessi risultati.


7
(+1) Controllare la perdita iniziale è un ottimo suggerimento. Mi dispiace di averlo lasciato fuori dalla mia risposta.
Sycorax,

7
Fare in modo che il tuo modello possa adattarsi eccessivamente è un'idea eccellente. Sono così abituato a pensare al sovraprezzo come a una debolezza che non ho mai pensato esplicitamente (fino a quando non lo hai menzionato) che la capacità di vestirsi eccessivamente sia in realtà una forza.
John Coleman,

15

Non addestrare una rete neurale per cominciare!

Tutte le risposte sono ottime, ma c'è un punto che dovrebbe essere menzionato: c'è qualcosa da imparare dai tuoi dati? (che potrebbe essere considerato come una sorta di test).

Se l'etichetta che stai tentando di prevedere è indipendente dalle tue caratteristiche, è probabile che la perdita di allenamento avrà difficoltà a ridursi.

Invece, inizia a calibrare una regressione lineare, una foresta casuale (o qualsiasi metodo che ti piace il cui numero di iperparametri è basso e il cui comportamento puoi capire).

Quindi, se ottieni prestazioni decenti su questi modelli (meglio delle ipotesi casuali), puoi iniziare a sintonizzare una rete neurale (e la risposta di @Sycorax risolverà la maggior parte dei problemi).


5
XK

11

Alla base, il flusso di lavoro di base per l'addestramento di un modello NN / DNN è più o meno sempre lo stesso:

  1. definire l'architettura NN (quanti layer, che tipo di layer, le connessioni tra layer, le funzioni di attivazione, ecc.)

  2. leggere i dati da alcune fonti (Internet, un database, una serie di file locali, ecc.), dare un'occhiata ad alcuni esempi (per assicurarsi che l'importazione sia andata bene) ed eseguire la pulizia dei dati se / quando necessario. Questo passaggio non è così banale come la gente di solito suppone che sia. Il motivo è che per i DNN, di solito ci occupiamo di giganteschi set di dati, diversi ordini di grandezza più grandi di quelli a cui siamo abituati, quando ci adattiamo a modelli statistici parametrici non lineari più standard (le NN appartengono a questa famiglia, in teoria).

  3. normalizzare o standardizzare i dati in qualche modo. Poiché gli NN sono modelli non lineari, la normalizzazione dei dati può influire non solo sulla stabilità numerica, ma anche sul tempo di addestramento e sugli output NN (una funzione lineare come la normalizzazione non commuta con una funzione gerarchica non lineare).

  4. dividere i dati in training / validation / test set o in più fold se si usa la validazione incrociata.

  5. addestrare la rete neurale, controllando allo stesso tempo la perdita sul set di validazione. Qui puoi goderti i piaceri strazianti dell'anima dell'ottimizzazione non convessa, dove non sai se esiste una soluzione, se esistono più soluzioni, qual è la migliore (e) soluzione (e) in termini di errore di generalizzazione e quanto sei vicino esso. Il confronto tra la perdita di allenamento e la curva di perdita di convalida ti guida, ovviamente, ma non sottovalutare l' atteggiamento duro da morire degli NN (e specialmente dei DNN): spesso mostrano una perdita di addestramento / validazione in calo (forse lentamente) anche quando hai bug paralizzante nel tuo codice.

  6. Verificare l'accuratezza sul set di test ed eseguire alcuni grafici / tabelle diagnostici.

  7. Torna al punto 1 perché i risultati non sono buoni. Ribadire fino alla nausea .

Naturalmente i dettagli cambieranno in base al caso d'uso specifico, ma con questa tela ruvida in mente, possiamo pensare a cosa è più probabile che vada storto.

Controlli di architettura di base

Questo può essere una fonte di problemi. Di solito eseguo questi controlli preliminari:

  • cerca un'architettura semplice che funzioni bene sul tuo problema (ad esempio, MobileNetV2 nel caso della classificazione delle immagini) e applica un'adeguata inizializzazione (a questo livello, generalmente lo farà casualmente). Se questo si allena correttamente sui tuoi dati, almeno sai che non ci sono problemi evidenti nel set di dati. Se non riesci a trovare un'architettura semplice e testata che funzioni nel tuo caso, pensa a una semplice base . Ad esempio un classificatore Naive Bayes per la classificazione (o anche solo classificare sempre la classe più comune) o un modello ARIMA per la previsione di serie storiche

  • Costruisci test unitari. Trascurare di farlo (e l'uso del sanguinoso Jupyter Notebook) sono di solito le cause alla radice dei problemi nel codice NN che mi viene chiesto di rivedere, specialmente quando il modello dovrebbe essere distribuito in produzione. Poiché la risposta più votata ha già trattato i test unitari, aggiungerò semplicemente che esiste una libreria che supporta lo sviluppo dei test unitari per NN (purtroppo solo a Tensorflow).

Set di allenamento

Ricontrolla i tuoi dati di input. Verifica se hai invertito il set di addestramento e le etichette del set di test, ad esempio (mi è capitato una volta -___-) o se hai importato il file sbagliato. Dai un'occhiata ad alcuni esempi di input e alle etichette associate e assicurati che abbiano un senso. Verifica che i dati normalizzati siano veramente normalizzati (dai un'occhiata al loro intervallo). Inoltre, i set di dati del mondo reale sono sporchi: per la classificazione, potrebbe esserci un alto livello di rumore dell'etichetta (campioni con un'etichetta di classe errata) o per previsioni di serie temporali multivariate, alcuni dei componenti delle serie temporali potrebbero avere molti dati mancanti ( Ho visto numeri fino al 94% per alcuni degli ingressi).

L'ordine in cui il set di allenamento viene immesso in rete durante l'allenamento può avere un effetto. Prova uno shuffle casuale del set di allenamento ( senza interrompere l'associazione tra input e output ) e vedi se la perdita di training diminuisce.

Infine, il modo migliore per verificare se si hanno problemi con i set di training è utilizzare un altro set di training. Se stai eseguendo la classificazione delle immagini, anziché le immagini che hai raccolto, utilizza un set di dati standard come CIFAR10 o CIFAR100 (o ImageNet, se puoi permetterti di allenarti su quello). Questi set di dati sono ben testati: se la perdita di allenamento scende qui ma non sul set di dati originale, è possibile che si verifichino problemi nel set di dati.

Fai i test d'oro

Esistono due test che chiamo Golden Test, che sono molto utili per trovare problemi in una NN che non si allena:

  • ridurre l'allenamento impostato su 1 o 2 campioni e allenarsi su questo. L'NN dovrebbe immediatamente sovrautilizzare il set di allenamento, raggiungendo un'accuratezza del 100% sul set di allenamento molto rapidamente, mentre l'accuratezza sul set di validazione / test andrà allo 0%. Se ciò non accade, c'è un bug nel tuo codice.

  • il test opposto: si mantiene l'intero set di allenamento, ma si mescolano le etichette. L'unico modo in cui NN può imparare ora è memorizzare il set di allenamento, il che significa che la perdita di allenamento diminuirà molto lentamente, mentre la perdita del test aumenterà molto rapidamente. In particolare, dovresti raggiungere la perdita casuale casuale sul set di test . Ciò significa che se hai 1000 classi, dovresti raggiungere una precisione dello 0,1%. Se non vedi alcuna differenza tra la perdita di allenamento prima e dopo aver mischiato le etichette, ciò significa che il tuo codice è difettoso (ricorda che abbiamo già controllato le etichette del set di addestramento nel passaggio precedente).

Verifica che la metrica di allenamento abbia senso

La precisione (perdita 0-1) è una metrica scadente se si ha un forte squilibrio di classe. Prova qualcosa di più significativo come la perdita di entropia: non vuoi solo classificare correttamente, ma ti piacerebbe classificare con alta precisione.

Tira fuori le pistole grandi

Se nulla ha aiutato, ora è il momento di iniziare a giocherellare con iperparametri. Questa è facilmente la parte peggiore della formazione NN, ma si tratta di modelli giganteschi e non identificabili i cui parametri sono adeguati risolvendo un'ottimizzazione non convessa, quindi spesso queste iterazioni non possono essere evitate.

  • prova diversi ottimizzatori: SGD si allena più lentamente, ma porta a un errore di generalizzazione inferiore, mentre Adam si allena più velocemente, ma la perdita del test si blocca a un valore più alto
  • prova a ridurre la dimensione del lotto
  • aumentare inizialmente il tasso di apprendimento, quindi decaderlo o utilizzare un tasso di apprendimento ciclico
  • aggiungi livelli
  • aggiungi unità nascoste
  • rimuovere la regolarizzazione gradualmente (forse cambiare norma batch per alcuni livelli). La perdita di allenamento ora dovrebbe diminuire, ma la perdita del test potrebbe aumentare.
  • visualizzare la distribuzione di pesi e distorsioni per ogni strato. Non ho mai dovuto arrivare qui, ma se stai usando BatchNorm, ti aspetteresti distribuzioni normali approssimativamente standard. Vedi se la norma dei pesi aumenta in modo anomalo con le epoche.
  • se ricevi un errore durante l'allenamento, cercalo su Google . Ho perso una mattina mentre cercavo di riparare un'architettura perfettamente funzionante, solo per scoprire che la versione di Keras che avevo installato aveva un supporto multi-GPU difettoso e ho dovuto aggiornarlo. A volte ho dovuto fare il contrario (downgrade di una versione del pacchetto).
  • aggiorna il tuo CV e inizia a cercare un lavoro diverso :-)

+1, ma "Bloody Jupyter Notebook"? Vuoi commentare questo? :)
amoeba,

2
Ecco perché odio i quaderni di Jupyter . TL; DR: stato nascosto, diffondere è una seccatura, problemi di sicurezza e incoraggia cattive pratiche di programmazione, come non usare test di unità / regressione / integrazione. La formazione di NN è già abbastanza difficile, senza che le persone si dimentichino dei fondamenti della programmazione.
DeltaIV,

2
Probabilmente sono troppo negativo, ma francamente ne ho avuto abbastanza con le persone che clonavano i quaderni Jupyter di GitHub, pensando che sarebbe stata una questione di minuti per adattare il codice al loro caso d'uso e poi venire da me lamentandomi che nulla funziona. Per amor di Dio, prendi un vero IDE come PyCharm o VisualStudio Code e crea un codice ben strutturato, piuttosto che cucinare un Notebook! Soprattutto se si prevede di spedire il modello in produzione, le cose saranno molto più facili.
DeltaIV,

2
Lol. 'Notebook Jupyter' e 'unit test' sono anti-correlati.
Sycorax,

2
(+1) Questo è un buon commento. I suggerimenti per i test di randomizzazione sono davvero ottimi modi per accedere a reti con problemi.
Sycorax,

6

Se il modello non sta imparando, c'è una buona possibilità che la tua backpropagation non funzioni. Ma ci sono così tante cose che possono andare storte con un modello di scatola nera come Neural Network, ci sono molte cose che devi controllare. Penso che Sycorax e Alex forniscano entrambe ottime risposte complete. Voglio solo aggiungere una tecnica non ancora discussa.

ε

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.