Evitare l'overfitting con una grande rete LSTM su una piccola quantità di dati
Sto ripubblicando questa domanda da AI.SE qui perché penso che fosse forse fuori tema per AI.SE ...
1. Contesto
Sto studiando tecniche di monitoraggio della salute e pratico sul set di dati C-MAPSS . L'obiettivo è prevedere la vita utile rimanente (RUL) di un motore in base alle serie di misurazioni del sensore. Esiste un'ampia letteratura sul set di dati C-MAPSS, comprese le tecniche ML classiche (non DL) e gli approcci basati su DL. Alcuni anni fa, le reti basate su LSTM hanno mostrato risultati promettenti (vedi Rete di memoria a lungo termine per la stima della vita utile rimanente, Zheng et al , 2017 ) e sto cercando di riprodurre questi risultati.
Il set di dati C-MAPSS contiene una quantità ridotta di dati. Il sottoinsieme FD001 ha ad esempio solo 100 serie run-to-failure. Quando lo preparo per ottenere serie temporali di durata fissa, posso ottenere fino a ~ 20.000 serie incorniciate. Nell'articolo citato sopra usando LSTM, usano due strati LSTM nascosti con 64 unità ciascuno e due strati completamente connessi con 8 neuroni ciascuno (~ 55.000 parametri).
2. Problema
Gli LSTM inducono un gran numero di parametri, quindi è possibile riscontrare un overfitting durante l'addestramento di una rete di questo tipo. Posso usare la regolarizzazione L1 o L2, abbandoni, la rete sarà ancora ampiamente sovradimensionata rispetto al set di dati. Mantenendo la stessa architettura, non riesco a raggiungere i punteggi e l'RMSE nel documento nel set di convalida e l'overfitting è sempre qui.
Tuttavia, una cosa che funziona è ridurre il numero di unità dei livelli LSTM. Prevedibilmente, con solo 24 unità invece di 64 per strato, la rete ha molti meno parametri (~ 9000) e non presenta overfitting. I punteggi e l'RMSE sono un po 'peggiori di quelli sul giornale, ma è il massimo che posso ottenere finora. Sebbene questi risultati vadano bene per me, sono curioso di sapere come sia stato possibile per gli autori dell'articolo evitare l'overfitting sulla loro rete LSTM (64,64).
3. Domanda
Gli LSTM sono ottimi, ma inducono molti parametri che ostacolano un corretto apprendimento su piccoli dataset: mi chiedo se esista un metodo per affrontare questo specifico problema. Avresti qualche consiglio su come evitare l'overfitting con una rete basata su LSTM su un piccolo set di dati?
4. Informazioni
Fornisco di seguito maggiori informazioni sulla mia rete e sui risultati:
Architettura di rete
model = keras.models.Sequential([
keras.layers.LSTM(24, return_sequences=True, kernel_regularizer=keras.regularizers.l1(0.01),
input_shape=input_shape),
keras.layers.Dropout(0.2),
keras.layers.LSTM(24, return_sequences=False, kernel_regularizer=keras.regularizers.l1(0.01)),
keras.layers.Dropout(0.2),
keras.layers.Dense(8, activation='relu', kernel_regularizer=keras.regularizers.l2()),
keras.layers.Dropout(0.2),
keras.layers.Dense(8, activation='relu', kernel_regularizer=keras.regularizers.l2(), bias_regularizer=keras.regularizers.l2()),
keras.layers.Dense(1, activation='relu')
])
Punteggi (set di convalida)
- Carta: punteggio = 16,14; RMSE = 338
- Il mio LSTM (64, 64): punteggio = 26,47; RMSE = 3585 (overfit)
- Il mio LSTM (24, 24): punteggio = 16,82; RMSE = 515
Modifica: risultati per la soluzione proposta da @ hH1sG0n3
- LSTM (64, 64) con
recurrent_dropout=0.3
: Punteggio = 16,36; RMSE = 545
Risposte
Potresti voler controllare un paio di iperparametri che sembra non stai testando nel tuo codice sopra:
- Ritaglio del gradiente: aggiornamenti di grandi dimensioni ai pesi durante l'allenamento possono causare un overflow o un underflow numerico, spesso denominato "sfumature esplosive".
# configure your optimizer with gradient norm clipping
opt = SGD(lr=0.01, momentum=0.9, clipnorm=1.0)
- Dropout ricorrente: Dropout applicato al segnale di ingresso ricorrente delle unità del layer LSTM.
keras.layers.LSTM(24, kernel_regularizer=keras.regularizers.l1(0.01), ..., recurrent_dropout=0.3)
- Stateful: è chiaro dal documento se il modello mantiene il suo stato con ogni iterazione di addestramento. Puoi anche sperimentare con questo.
keras.layers.LSTM(24, kernel_regularizer=keras.regularizers.l1(0.01), ..., stateful=True)
Quindi, la domanda chiede come prevenire l'overfitting, in particolare con un set di dati piccolo.
Ovviamente, la mia prima intuizione dice di ridurre il numero di strati (es. Rimuovere il secondo strato LSTM, per esempio), ma questo ovviamente cambierebbe l'architettura complessiva del modello, in modo tale che abbia meno strati rispetto al modello descritto nel documento.
Un altro suggerimento particolarmente ovvio è quello di fare una qualche forma di aumento dei dati, per aumentare artificialmente il numero di campioni utilizzando il set di dati che hai attualmente.
Hai anche applicato una preelaborazione ai dati (es. Valori numerici in scala, ecc.)? In caso contrario, anche questo potrebbe aiutare.