2017-10-09 2 views
1

Je suis entrain de former un MLP simple pour classer les chiffres MNIST en utilisant Keras. Je rencontre un problème où, quel que soit l'optimiseur et le taux d'apprentissage que j'utilise, le modèle n'apprend pas/ne descend pas et ma précision reste à peu près aussi bonne qu'une estimation aléatoire.Keras MNIST gradient descente coincé/apprentissage très lentement

Voici le code:

model2=Sequential() 
model2.add(Dense(output_dim=512, input_dim=784, activation='relu', name='dense1', kernel_initializer='random_uniform')) 
model2.add(Dropout(0.2, name='dropout1')) 
model2.add(Dense(output_dim=512, input_dim=512, activation='relu', name='dense2', kernel_initializer='random_uniform')) 
model2.add(Dropout(0.2, name='dropout2')) 
model2.add(Dense(output_dim=10, input_dim=512, activation='softmax', name='dense3', kernel_initializer='random_uniform')) 
model2.compile(optimizer=Adagrad(), loss='categorical_crossentropy', metrics=['accuracy']) 
model2.summary() 
model2.fit(image_train.as_matrix(),img_keras_lb,batch_size=128,epochs = 100) 

et la sortie:

Epoch 1/100 
33600/33600 [==============================] - 5s - loss: 14.6704 - acc: 0.0894  
Epoch 2/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 3/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 4/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 5/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 6/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 7/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 8/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 9/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 10/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 11/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 12/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 13/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 14/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 15/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 16/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 17/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 18/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 19/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 20/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 21/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892  
Epoch 22/100 
33600/33600 [==============================] - 4s - loss: 14.6809 - acc: 0.0892 

Comme vous pouvez le voir, le modèle est rien apprendre. J'ai également essayé SGD, Adam, RMSprop, ainsi que la réduction de la taille de lot à 32, 16, etc

Tout pointeur sur ce qui se passe est grandement apprécié!

Répondre

3

Vous utilisez une activation ReLU qui coupe fondamentalement les activations inférieures à 0 et utilise une initialisation random_normal par défaut qui a les paramètres keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None) par défaut. Comme vous pouvez le voir, les valeurs d'initialisation sont très proches de 0 et la moitié d'entre elles (-0.05 à 0) ne sont pas activées du tout. Et ceux qui sont activés (0 à 0.05) propagent les gradients très très lentement.

Je pense que l'initialisation doit être environ 0 et n (ce qui correspond à la plage de fonctionnement des unités ReLU) et votre modèle devrait converger rapidement.

0

La raison pour laquelle vous ne faites pas de convergence est que vous devez ajuster les hyper-paramètres du modèle à l'aide de la validation croisée. Par exemple, pour l'optimiseur Adagrad, essayez de définir le taux d'apprentissage à 1e-3 au lieu du 1e-2 par défaut, par exemple. :

model2.compile(optimizer=Adagrad(1e-3), loss='categorical_crossentropy', metrics=['accuracy']) 

Et vous verrez que le modèle commencera à apprendre mieux. De plus, l'initialisation et le taux d'abandon jouent un rôle et doivent être ajustés comme mentionné dans l'autre réponse.