CIFAR-10 Impossibile ottenere una precisione superiore al 60%, Keras con backend Tensorflow [chiuso]


11

L'allenamento dopo 15 epoche sul set di dati CIFAR-10 sembra che la perdita di validazione non diminuisca più, rimanendo intorno all'1,4 (con un'accuratezza della validazione del 60%). Ho mischiato il set di allenamento, diviso per 255 e importato come float32. Ho provato numerose architetture, sia con che senza dropout nei livelli Conv2D e nulla sembra funzionare. La stessa architettura raggiunge un'accuratezza del 99,7% sui set di test per MNIST. Si prega di vedere l'architettura di seguito:

(Nota: ho provato ad aumentare l'abbandono e ad aumentare / diminuire il tasso di apprendimento dell'ottimizzatore Adam per evitare un eccesso di adattamento, tutto ciò è evitare un eccesso di adattamento ma con entrambi i set di allenamento e test ora hanno una precisione simile intorno al 60%).

with tf.device('/gpu:0'):
    tf.placeholder(tf.float32, shape=(None, 20, 64))
    #placeholder initialized (pick /cpu:0 or /gpu:0)
    seed = 6
    np.random.seed(seed)
    modelnn = Sequential()
    neurons = x_train_reduced.shape[1:]

    modelnn.add(Convolution2D(32, 3, 3, input_shape=neurons, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(32, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    #modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    #modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    #modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Flatten())
    #modelnn.add(Dropout(0.5))
    modelnn.add(Dense(1024, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(512, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(10, activation='softmax'))
    modelnn.compile(loss='categorical_crossentropy', optimizer=optimizer_input, metrics=['accuracy'])
    y_train = to_categorical(y_train)
    modelnn.fit(x_train_reduced, y_train, nb_epoch=nb_epoch_count, shuffle=True, batch_size=bsize,
                           validation_split=0.1)

risultati:

    44100/44100 [==============================] - 22s - loss: 2.1453 - acc: 0.2010 - val_loss: 1.9812 - val_acc: 0.2959
    Epoch 2/50
    44100/44100 [==============================] - 24s - loss: 1.9486 - acc: 0.3089 - val_loss: 1.8685 - val_acc: 0.3567
    Epoch 3/50
    44100/44100 [==============================] - 18s - loss: 1.8599 - acc: 0.3575 - val_loss: 1.7822 - val_acc: 0.3982
    Epoch 4/50
    44100/44100 [==============================] - 18s - loss: 1.7925 - acc: 0.3933 - val_loss: 1.7272 - val_acc: 0.4229
    Epoch 5/50
    44100/44100 [==============================] - 18s - loss: 1.7425 - acc: 0.4195 - val_loss: 1.6806 - val_acc: 0.4459
    Epoch 6/50
    44100/44100 [==============================] - 18s - loss: 1.6998 - acc: 0.4440 - val_loss: 1.6436 - val_acc: 0.4682
    Epoch 7/50
    44100/44100 [==============================] - 18s - loss: 1.6636 - acc: 0.4603 - val_loss: 1.6156 - val_acc: 0.4837
    Epoch 8/50
    44100/44100 [==============================] - 18s - loss: 1.6333 - acc: 0.4781 - val_loss: 1.6351 - val_acc: 0.4776
    Epoch 9/50
    44100/44100 [==============================] - 18s - loss: 1.6086 - acc: 0.4898 - val_loss: 1.5732 - val_acc: 0.5063
    Epoch 10/50
    44100/44100 [==============================] - 18s - loss: 1.5776 - acc: 0.5065 - val_loss: 1.5411 - val_acc: 0.5227
    Epoch 11/50
    44100/44100 [==============================] - 18s - loss: 1.5585 - acc: 0.5145 - val_loss: 1.5485 - val_acc: 0.5212
    Epoch 12/50
    44100/44100 [==============================] - 18s - loss: 1.5321 - acc: 0.5288 - val_loss: 1.5354 - val_acc: 0.5316
    Epoch 13/50
    44100/44100 [==============================] - 18s - loss: 1.5082 - acc: 0.5402 - val_loss: 1.5022 - val_acc: 0.5427
    Epoch 14/50
    44100/44100 [==============================] - 18s - loss: 1.4945 - acc: 0.5438 - val_loss: 1.4916 - val_acc: 0.5490
    Epoch 15/50
    44100/44100 [==============================] - 192s - loss: 1.4762 - acc: 0.5535 - val_loss: 1.5159 - val_acc: 0.5394
    Epoch 16/50
    44100/44100 [==============================] - 18s - loss: 1.4577 - acc: 0.5620 - val_loss: 1.5389 - val_acc: 0.5257
    Epoch 17/50
    44100/44100 [==============================] - 18s - loss: 1.4425 - acc: 0.5671 - val_loss: 1.4590 - val_acc: 0.5667
    Epoch 18/50
    44100/44100 [==============================] - 18s - loss: 1.4258 - acc: 0.5766 - val_loss: 1.4552 - val_acc: 0.5763
    Epoch 19/50
    44100/44100 [==============================] - 18s - loss: 1.4113 - acc: 0.5805 - val_loss: 1.4439 - val_acc: 0.5767
    Epoch 20/50
    44100/44100 [==============================] - 18s - loss: 1.3971 - acc: 0.5879 - val_loss: 1.4473 - val_acc: 0.5769
    Epoch 21/50
    44100/44100 [==============================] - 18s - loss: 1.3850 - acc: 0.5919 - val_loss: 1.4251 - val_acc: 0.5871
    Epoch 22/50
    44100/44100 [==============================] - 18s - loss: 1.3668 - acc: 0.6006 - val_loss: 1.4203 - val_acc: 0.5910
    Epoch 23/50
    44100/44100 [==============================] - 18s - loss: 1.3549 - acc: 0.6051 - val_loss: 1.4207 - val_acc: 0.5939
    Epoch 24/50
    44100/44100 [==============================] - 18s - loss: 1.3373 - acc: 0.6111 - val_loss: 1.4516 - val_acc: 0.5784
    Epoch 25/50
    44100/44100 [==============================] - 18s - loss: 1.3285 - acc: 0.6149 - val_loss: 1.4146 - val_acc: 0.5922
    Epoch 26/50
    44100/44100 [==============================] - 18s - loss: 1.3134 - acc: 0.6205 - val_loss: 1.4090 - val_acc: 0.6024
    Epoch 27/50
    44100/44100 [==============================] - 18s - loss: 1.3043 - acc: 0.6239 - val_loss: 1.4307 - val_acc: 0.5959
    Epoch 28/50
    44100/44100 [==============================] - 18s - loss: 1.2862 - acc: 0.6297 - val_loss: 1.4241 - val_acc: 0.5978
    Epoch 29/50
    44100/44100 [==============================] - 18s - loss: 1.2706 - acc: 0.6340 - val_loss: 1.4046 - val_acc: 0.6067
    Epoch 30/50
    44100/44100 [==============================] - 18s - loss: 1.2634 - acc: 0.6405 - val_loss: 1.4120 - val_acc: 0.6037
    Epoch 31/50
    44100/44100 [==============================] - 18s - loss: 1.2473 - acc: 0.6446 - val_loss: 1.4067 - val_acc: 0.6045
    Epoch 32/50
    44100/44100 [==============================] - 18s - loss: 1.2411 - acc: 0.6471 - val_loss: 1.4083 - val_acc: 0.6098
    Epoch 33/50
    44100/44100 [==============================] - 18s - loss: 1.2241 - acc: 0.6498 - val_loss: 1.4091 - val_acc: 0.6076
    Epoch 34/50
    44100/44100 [==============================] - 18s - loss: 1.2121 - acc: 0.6541 - val_loss: 1.4209 - val_acc: 0.6127
    Epoch 35/50
    44100/44100 [==============================] - 18s - loss: 1.1995 - acc: 0.6582 - val_loss: 1.4230 - val_acc: 0.6131
    Epoch 36/50
    44100/44100 [==============================] - 18s - loss: 1.1884 - acc: 0.6622 - val_loss: 1.4024 - val_acc: 0.6124
    Epoch 37/50
    44100/44100 [==============================] - 18s - loss: 1.1778 - acc: 0.6657 - val_loss: 1.4328 - val_acc: 0.6080
    Epoch 38/50
    44100/44100 [==============================] - 18s - loss: 1.1612 - acc: 0.6683 - val_loss: 1.4246 - val_acc: 0.6159
    Epoch 39/50
    44100/44100 [==============================] - 18s - loss: 1.1466 - acc: 0.6735 - val_loss: 1.4282 - val_acc: 0.6122
    Epoch 40/50
    44100/44100 [==============================] - 18s - loss: 1.1325 - acc: 0.6783 - val_loss: 1.4311 - val_acc: 0.6157
    Epoch 41/50
    44100/44100 [==============================] - 18s - loss: 1.1213 - acc: 0.6806 - val_loss: 1.4647 - val_acc: 0.6047
    Epoch 42/50
    44100/44100 [==============================] - 18s - loss: 1.1064 - acc: 0.6842 - val_loss: 1.4631 - val_acc: 0.6047
    Epoch 43/50
    44100/44100 [==============================] - 18s - loss: 1.0967 - acc: 0.6870 - val_loss: 1.4535 - val_acc: 0.6106
    Epoch 44/50
    44100/44100 [==============================] - 18s - loss: 1.0822 - acc: 0.6893 - val_loss: 1.4532 - val_acc: 0.6149
    Epoch 45/50
    44100/44100 [==============================] - 18s - loss: 1.0659 - acc: 0.6941 - val_loss: 1.4691 - val_acc: 0.6108
    Epoch 46/50
    44100/44100 [==============================] - 18s - loss: 1.0610 - acc: 0.6956 - val_loss: 1.4751 - val_acc: 0.6106
    Epoch 47/50
    44100/44100 [==============================] - 18s - loss: 1.0397 - acc: 0.6981 - val_loss: 1.4857 - val_acc: 0.6041
    Epoch 48/50
    44100/44100 [==============================] - 18s - loss: 1.0208 - acc: 0.7039 - val_loss: 1.4901 - val_acc: 0.6106
    Epoch 49/50
    44100/44100 [==============================] - 18s - loss: 1.0187 - acc: 0.7036 - val_loss: 1.4994 - val_acc: 0.6106
    Epoch 50/50
    44100/44100 [==============================] - 18s - loss: 1.0024 - acc: 0.7070 - val_loss: 1.5078 - val_acc: 0.6039
    Time: 1109.7512991428375
    Neural Network now trained from dimensions (49000, 3, 32, 32)

Aggiornamento: ulteriori test tra cui BatchNormalization sia con che senza MaxNorm -

img

Nuova architettura:

    modelnn.add(Convolution2D(32, 3, 3, input_shape=neurons, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(32, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.2))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(Convolution2D(128, 3, 3, activation='relu', border_mode='same'))
    modelnn.add(BatchNormalization())
    modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Dropout(0.2))
    # modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    # modelnn.add(Convolution2D(256, 3, 3, activation='relu', border_mode='same'))
    # modelnn.add(MaxPooling2D(pool_size=(2, 2)))
    modelnn.add(Flatten())
    modelnn.add(Dense(1024, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(512, activation='relu', W_constraint=maxnorm(3)))
    modelnn.add(BatchNormalization())
    modelnn.add(Dropout(0.5))
    modelnn.add(Dense(10, activation='softmax'))

Risposte:


8

Si noti che MNIST è un set di problemi molto più semplice rispetto a CIFAR-10 e che è possibile ottenere il 98% da una NNet completamente connessa (non convoluzionale) con pochissime difficoltà. Anche una CNN molto semplice con solo uno o due strati convoluzionali può raggiungere lo stesso livello di precisione.

Non sono sicuro della tua architettura NNet, ma posso ottenere una precisione del test del 78% su CIFAR-10 con la seguente architettura (che è relativamente più semplice e ha meno pesi). Non sono state richieste inizializzazioni o maniglie speciali, utilizzando i valori predefiniti vaniglia e l'ottimizzatore Adam:

model = Sequential()
model.add(Conv2D(input_shape=trainX[0,:,:,:].shape, filters=96, kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(Conv2D(filters=96, kernel_size=(3,3), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Conv2D(filters=192, kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(Conv2D(filters=192, kernel_size=(3,3), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Flatten())
model.add(BatchNormalization())
model.add(Dense(256))
model.add(Activation('relu'))
model.add(Dense(n_classes, activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

Questa architettura è piuttosto semplice ed è liberamente basata su https://arxiv.org/pdf/1412.6806.pdf .

Addestrando questo modello così:

n_epochs = 25
batch_size = 256
callbacks_list = None
H = model.fit(trainX, trainY, validation_data=(testX, testY), 
              epochs=n_epochs, batch_size=batch_size, callbacks=callbacks_list)
print('Done!!!')

Fornisce quanto segue, che puoi vedere arriva a quasi il 77% entro la 25a epoca e più o meno si appiattisce da lì (ma ha abbastanza regolarizzazione dall'abbandono per evitare che si degradi a causa di un eccesso di montaggio, almeno oltre il numero testato di iterazioni) .

Addestramento su 50000 campioni, validazione su 10000 campioni
Epoca 1/50
50000/50000 [==============================] - 19s 390us / step - perdita: 1.6058 - acc: 0.4150 - val_loss: 1.5285 - val_acc: 0.4669
Epoca 2/50
50000/50000 [======================= =======] - 19s 371us / step - loss: 1.2563 - acc: 0.5477 - val_loss: 1.1447 - val_acc: 0.5901
Epoca 3/50
50000/50000 [============= =================] - 19s 373us / step - perdita: 1.0784 - acc: 0.6163 - val_loss: 1.1577 - val_acc: 0.6002
...
Epoca 25/50
50000/50000 [ ==============================] - 19s 374us / step - perdita: 0,3188 - acc: 0,8857 - val_loss: 0,7493 - val_acc : 0,7680
...
Epoca 50/50
50000/50000 [==============================] - 19s 373us / step - perdita: 0,1928 - acc: 0,9329 - val_loss : 0.8718 - val_acc: 0.7751
Fatto !!!

Ecco un'architettura ancora più semplice e molto più piccola che può arrivare al 70% abbastanza rapidamente con lo stesso regime di allenamento (senza livelli di normalizzazione o pooling batch):

# CNN architecture with Keras
model = Sequential()
model.add(Conv2D(input_shape=trainX[0,:,:,:].shape, filters=32, 
                 use_bias=True, kernel_size=(3,3)))
model.add(Activation('relu'))
model.add(Dropout(0.1))
model.add(Conv2D(filters=64, use_bias=False, kernel_size=(5,5), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.2))
model.add(Flatten())
model.add(Dense(128))
model.add(Activation('relu'))
model.add(Dropout(0.3))
model.add(Dense(n_classes, activation="softmax"))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=    ['accuracy'])

Vale la pena notare che le architetture che ottengono la migliore precisione pubblicata su CIFAR-10 (attualmente nella gamma del 90-96%) sono generalmente più complicate e richiedono molte ore per la formazione sull'hardware GPU. Ma sono stato in grado di arrivare al 70-80% con architetture abbastanza semplici che si allenano in pochi minuti, il che è ciò che consiglierei prima di andare per i risultati meglio pubblicati che di solito richiedono architetture più complicate, periodi di formazione più lunghi, a volte regimi speciali di gestione / addestramento o aumento dei dati e ore di treno.

AGGIORNARE:

Sulla base dei grafici aggiornati nella domanda, il problema più evidente che viene dimostrato è l'adattamento eccessivo. Ciò è dimostrato dalla divergenza dei dati di prova del treno dopo circa la 15a epoca che dimostra una regolarizzazione insufficiente per questa architettura, per questo set di dati. È improbabile che tu ottenga miglioramenti dall'ottimizzazione di altri iperparametri (strategie di normalizzazione, tassi di apprendimento, ecc.) A meno che non venga affrontato il sovradimensionamento.

Nell'uso delle reti, consiglio quanto segue:

  1. Inizia da architetture che imitano o replicano quelle note per produrre buoni risultati
  2. Verifica le prestazioni sul tuo set di dati, con particolare attenzione all'adattamento eccessivo nella rete (evidenziato da una significativa divergenza di errori di test del treno)
  3. Aggiungi ulteriore regolarizzazione (aumenta i tassi di abbandono) quando si osserva un eccesso di adattamento (stai cercando "quanto basta" per evitare un eccesso di adattamento - troppo si tradurrà in un insufficiente adattamento)
  4. Sperimenta con struttura, approcci formativi e iperparametri per trovare strade di miglioramento

Le prescrizioni relative a quest'ultimo sono in realtà piuttosto difficili da trovare, perché ci sono poche basi teoriche su come la struttura, la formazione o gli iperparametri interagiscono per produrre prestazioni su un dato set di dati. Il fatto che gli approcci adottati dalle architetture pubblicate che raggiungono livelli di prestazioni simili sui set di dati di riferimento variano così notevolmente ne è la prova.

Si è scoperto che la batchnormalization migliora significativamente alcune architetture, ma altre possono fare abbastanza bene senza di essa (o sono indifferenti alla sua presenza). L'unica vera guida da fornire qui è di provarlo e vedere se aiuta.

I tassi di apprendimento di messa a punto devono essere generalmente evitati a meno che tu non sia un professionista avanzato con una profonda conoscenza delle ConvNets e la corrispondente capacità di leggere le foglie di tè in merito alle prestazioni incrementali inter-epoca durante l'allenamento. In alcuni casi, i tassi di apprendimento personalizzati e altri regimi di addestramento specializzati possono aiutare le reti a navigare nei minimi locali e a trovare soluzioni globali migliori, ma a meno che tu non abbia molto tempo e il know-how per diagnosticare il comportamento di convergenza della rete, questo non è un buon punto di partenza. La maggior parte di noi dovrebbe usare un ottimizzatore come Adam che supererà i tentativi dei principianti di tassi di apprendimento ottimizzati nella maggior parte dei casi.

L'aumento dei dati tramite la preelaborazione delle immagini può talvolta portare a significativi miglioramenti delle prestazioni (in generale, più vari sono i dati di input, migliore sarà la generalizzazione del modello - la preelaborazione dei dati aggiunge una variazione allo spazio di input che può migliorare l'accuratezza fuori dal campione e puòpermettere una riduzione dei requisiti di regolarizzazione - ipoteticamente, con infiniti dati di allenamento non avremmo bisogno di alcuna regolarizzazione, ma nello spazio di elaborazione delle immagini è improbabile che ci avviciniamo a quell'asintoto). Ciò può aumentare significativamente il tempo di allenamento e rallentare i tassi di convergenza, e introduce tutta un'altra serie di iperparametri relativi alle tecniche di permutazione dell'immagine in ingresso (rotazione, ritaglio, ridimensionamento, rumore, ecc. Ecc.). Poiché questo percorso può aumentare i tempi di formazione e richiedere ulteriori esperimenti per ottimizzare i risultati, alcuni consigli generali sarebbero quelli di guidare per la migliore precisione nella rete senza aumentare prima, quindi vedere se qualche aumento modesto produce miglioramenti. In tal caso, potrebbe giustificare ulteriori sperimentazioni.

Per tutti gli esperimenti di ottimizzazione, dovrai tenere d'occhio i cambiamenti nel comportamento eccessivo e insufficiente. La modifica dell'architettura di rete, dei regimi di allenamento o dell'iperparametro può richiedere un'ulteriore messa a punto della regolarizzazione del dropout. La capacità di accertare prontamente il comportamento eccessivo e insufficiente delle prestazioni del treno / test è probabilmente l'abilità di base più importante nel lavorare con le reti virtuali, e questo diventa più intuitivo con l'esperienza.

Questa è la candela attraverso la quale saranno guidati tutti i tuoi sforzi. La candela può solo illuminare debolmente il percorso, ma senza di essa ti imbatterai nell'oscurità. Se la tua rete è fortemente sovra o sottoadatta, dovrebbe essere affrontata prima di tentare permutazioni casuali della struttura della rete o iperparametri.

Le architetture relativamente semplici con i regimi di addestramento alla vaniglia inclusi in questa risposta dimostrano la realtà di lavorare con le architetture NNET su problemi difficili come la classificazione delle immagini: ottenere un risultato "abbastanza buono" basato su approcci che funzionano bene non è difficile, ma un miglioramento incrementale è sempre più costoso. Raggiungere i risultati migliori pubblicati tramite la sperimentazione andrà oltre le capacità o la disponibilità di tempo di molti (anche se è possibile, con tempo e sforzi sufficienti, seguire le ricette del ricettario degli approcci pubblicati per replicare i loro risultati - ma anche questo non è affatto significa banale). Raggiungere un miglioramento incrementale da un punto di partenza "piuttosto buono" può essere un processo di tentativi ed errori che richiede molto tempo e molti esperimenti non produrranno alcun miglioramento significativo.

Questo non ha lo scopo di dissuadere chiunque dal tentare di apprendere, ma solo per chiarire che vi è un investimento significativo richiesto per padroneggiare il set di strumenti (in continua espansione) nella borsa di trucchi NNet e che può essere necessario guidare miglioramenti attraverso prove ed errori dozzine (o centinaia) di esperimenti nel corso di giorni o settimane di formazione dedicata alla GPU.

Il tempo, le competenze e le risorse (GPU dedicate) necessarie per addestrare le reti a livelli molto elevati di prestazioni spiegano in parte la popolarità delle reti pre-formate.


1
Le architetture di rete neurale non hanno livelli di pooling? questo non crea un numero ingestibile di parametri?
Spandyie,

2
Pooling - pfft! Sopravvalutato. Questo utilizza un approccio onnicomprensivo che utilizza la lotta per la decimazione piuttosto che il raggruppamento - vedere il documento collegato per la descrizione. Il passo convoluzionale può ottenere lo stesso effetto "incanalamento" del raggruppamento con mezzi leggermente diversi. Il fatto che entrambi funzionino, semplicemente dimostra che non c'è molta solida base teorica per sostenere il motivo per cui una di queste cose funziona.
T3am5hark,

6

Guardando i tuoi valori di perdita e accuratezza nel campione e fuori campione, il tuo modello è attualmente insufficiente, ma sta migliorando monotonicamente. In altre parole, sembra che eseguirlo per più epoche si tradurrebbe in prestazioni predittive più elevate / minori perdite di entropia.

Stai usando un'architettura altamente regolarizzata (livelli di drop-out), che non è male. Tuttavia, non sorprende inoltre che l'allenamento richieda molto più tempo che senza alcuna regolarizzazione. A causa dei livelli di abbandono, è improbabile che ti vestirai (sostanzialmente).

Cose che puoi provare ad accelerare l'apprendimento:

io. modificare il tasso di apprendimento: ad es. iniziare con uno piccolo, aumentarlo nel mezzo e verso la fine abbassarlo di nuovo.

ii. aggiungi batchnormalization : nell'architettura sopra, puoi includere batch-norm sia nei tuoi blocchi convoluzionali che nei layer densi. Di solito, il livello della norma batch viene aggiunto dopo l'attivazione non lineare ma prima dell'abbandono. Non sono sicuro di come la norma batch funzioni con maxnorm. Per i tuoi strati densi, proverei batch-norm + dropuout con / senza maxnorm. Ho la sensazione che non ti serva maxnorm se applichi la normalizzazione in lotti.

iii. aumentare le dimensioni del batch: non sono sicuro di quale sia la dimensione del batch e se si possiede una GPU. Se hai una GPU, probabilmente dovresti provare a massimizzare la dimensione del tuo batch in moltiplicativi di 32.

Infine, per garantire che i tuoi dati siano "apprendibili" / non corrotti (ad esempio, non hai applicato involontariamente una trasformazione per deformarla), eliminerei tutta la regolarizzazione dalla tua architettura, esegui l'addestramento e vedo che puoi adattarti al set di addestramento . Se riesci ad apprendere con successo i dati di allenamento, il resto è un esercizio di generalizzazione. Se non riesci ad adattarti eccessivamente ai dati di training anche senza regolarizzazione, molto probabilmente il tuo modello ha bisogno di più capacità (architettura più profonda e più ampia).


Grazie per il consiglio! Avevi ragione sul fatto che MaxNorm interferisse leggermente. Tuttavia, anche dopo aver aggiunto i livelli di BatchNormalization (consultare l'aggiornamento) ed aver rimosso / incluso MaxNorm, l'accuratezza è ancora bassa. Non si sta verificando alcun aumento. Ho una GPU e ho provato ad allenarmi con 64.128.256 e 512 lotti, ma si notano poche differenze. Per quanto riguarda il tasso di apprendimento, sto usando l'ottimizzatore Adam e hai pensato che questo dovrebbe essere più o meno lasciato solo? Tuttavia, ho provato LR a 0,05, 0,001, 0,0005 e ho notato che l'impostazione predefinita 0,001 sembra ancora migliore. Qualche idea?
user4779

Inoltre sono in grado di adattarmi bene. Ho fatto del mio meglio per copiare l'architettura nei documenti che sembrano essere in grado di raggiungere una precisione dell'80% ++ con MNIST10. Quando lascio l'allenamento modello per epoche più lunghe, sembra che la perdita ora aumenti (più di 20 epoche circa).
user4779

Commento di modifica - a seguito delle modifiche al modello, i grafici indicano ora che sta sovrastimando in modo significativo i dati (in base alla divergenza dell'errore di convalida dopo ~ 15 epoche)
T3am5hark,

In realtà contendo l'utilità dei consigli offerti qui, specialmente per i nuovi professionisti. Queste sono tutte cose che puoi fare, certo, ma per le persone che non conoscono la CNN e che non hanno l'intuizione o la comprensione di come funzionano queste cose, ci sono troppe manopole e leve per modificare senza alcuna guida prescrittiva diversa dal cieco processo ed errore, difficilmente produrrà risultati positivi. Meglio sarebbe innanzitutto iniziare con architetture più semplici che sono in grado di ottenere buone prestazioni (non meglio pubblicate) con una rotazione minima, quindi esplorare strade di miglioramento da lì. I miei due centesimi.
T3am5hark,

Per elaborare ulteriormente - non giocare con i tassi di apprendimento, usa Adam. Batterà il tuning manuale dei tassi di apprendimento il 99,99% delle volte. Inoltre, l'affermazione secondo cui è "improbabile che tu possa mai esagerare" è semplicemente sbagliata (come indicato dalla grafica di follow-up che ora dimostra un significativo adattamento eccessivo), e non c'è motivo per cui il poster supponga che ... non c'è niente da dirti a priori per una determinata architettura se un determinato tasso di abbandono si regolarizzerà sufficientemente per evitare un adattamento eccessivo.
T3am5hark,

1

Oggi ho provato a farlo e sono stato costantemente in grado di raggiungere quasi il 75-80% di precisione nei test.

Storia dell'allenamento

  • Il numero totale di parametri utilizzati era: 183,242

  • Puoi fare di meglio aggiungendo forse qualche altro livello, ma non devi essere eccessivo. Reti più complesse non sempre danno risultati migliori.

suggerimenti

Il mio suggerimento per te è di mantenere semplice la tua architettura. Segui Occam's Razor , semplice è meglio.

  • Ridimensiona i tuoi dati

  • Non usare un seme casuale

  • Utilizzare un ottimizzatore appropriato; Ho usato Adadelta come viene da Keras.

  • Le CNN non devono essere contorte; mantienilo semplice

  • Le reti più magre a volte funzionano meglio di quelle più ampie

  • Usa regolarizzazione (ad es. Dropout)

Di seguito è riportato il mio codice (usando Keras)

# Define the model
model = Sequential()
model.add(Convolution2D(64, (4, 4), padding='same', input_shape=(3, 32, 32)))
model.add(MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Convolution2D(64, (2, 2), padding='same'))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Convolution2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Convolution2D(32, (3, 3), padding='same'))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2, 2), strides=2))
model.add(Dropout(0.15))
model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.25))
model.add(Dense(64))
model.add(Activation('tanh'))
model.add(Dropout(0.25))
model.add(Dense(num_classes, activation='softmax'))
# Compile the model
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.