2017-05-01 1 views
1

Afin de comprendre Keras avec TensorFlow backend pour d'autres projets de recherche, j'ai essayé d'implémenter un NN pour un problème de classification simple. Je veux seulement différencier randomly distributed points in 2D into two categories depending on their coordinates (la couleur indique la catégorie). Le code associé pour générer les données est:Simple NN dans Keras - Classification

import numpy as np  
np.random.seed(40) 

def createData(N=120, M=75): 
    train_x1 = np.random.random(size=N) 
    train_x2 = np.random.random(size=N) 

    test_x1 = np.random.random(size=M) 
    test_x2 = np.random.random(size=M) 

    train_x = np.zeros((N, 2)) 
    train_y = np.zeros((N, 1)) 

    test_x = np.zeros((M, 2)) 
    test_y = np.zeros((M, 1)) 

    for i in range(N): 
     train_x[i][0] = train_x1[i] 
     train_x[i][1] = train_x2[i] 
     if train_x1[i] < 0.5: 
      if train_x2[i] < 0.5: 
       train_y[i][0] = 1 
      else: 
       train_y[i][0] = 2 
     else: 
      if train_x2[i] < 0.5: 
       train_y[i][0] = 2 
      else: 
       train_y[i][0] = 1 

    for j in range(M): 
     test_x[j][0] = test_x1[j] 
     test_x[j][1] = test_x2[j] 
     if test_x1[j] < 0.5: 
      if test_x2[j] < 0.5: 
       test_y[j][0] = 1 
      else: 
       test_y[j][0] = 2 
     else: 
      if test_x2[j] < 0.5: 
       test_y[j][0] = 2 
      else: 
       test_y[j][0] = 1 

    return train_x, train_y, test_x, test_y 

Mon code pour le réseau de neurones est comme suit:

from keras.models import Sequential 
from keras.layers import Dense 
import numpy as np 
import matplotlib.pyplot as plt 

X, Y, x, y = createData() 

# Model 
model = Sequential() 
model.add(Dense(4, input_dim=2, activation='relu')) 
model.add(Dense(10, activation='sigmoid')) 
model.add(Dense(1, activation='sigmoid')) 

# Compile 
model.compile(loss='binary_crossentropy', optimizer='sgd', metrics=['accuracy']) 

# Fit 
model.fit(X, Y, epochs=500, batch_size=25) 

# Evaluation 
scores = model.evaluate(X, Y) 
print("\n%s: %.2f%%" % (model.metrics_names[1], scores[1]*100)) 

# Predictions 
predictions = model.predict(x) 
rounded = [round(z[0]) for z in predictions] 
print(rounded) 

Mon problème est que le réseau de neurones atteint une avec une précision de 47,5% ci-dessus graines et configuration mentionnées. Il affecte all test coordinates to only one category. Cependant, d'autres configurations (plus de couches, plus/moins de neurones, autres fonctions d'activation, autres fonctions de perte, etc.) conduisent à des résultats similaires.

Les dernières lignes du « moniteur époque » sur la coquille ressemble à ceci:

Epoch 490/500 
120/120 [==============================] - 0s - loss: -8.3351 - acc: 0.4750  
Epoch 491/500 
120/120 [==============================] - 0s - loss: -8.1866 - acc: 0.4750  
Epoch 492/500 
120/120 [==============================] - 0s - loss: -8.3524 - acc: 0.4750  
Epoch 493/500 
120/120 [==============================] - 0s - loss: -8.2608 - acc: 0.4750  
Epoch 494/500 
120/120 [==============================] - 0s - loss: -8.3269 - acc: 0.4750  
Epoch 495/500 
120/120 [==============================] - 0s - loss: -8.2039 - acc: 0.4750  
Epoch 496/500 
120/120 [==============================] - 0s - loss: -8.1786 - acc: 0.4750  
Epoch 497/500 
120/120 [==============================] - 0s - loss: -8.2488 - acc: 0.4750  
Epoch 498/500 
120/120 [==============================] - 0s - loss: -8.3090 - acc: 0.4750  
Epoch 499/500 
120/120 [==============================] - 0s - loss: -8.3457 - acc: 0.4750  
Epoch 500/500 
120/120 [==============================] - 0s - loss: -8.1235 - acc: 0.4750 

Comment puis-je améliorer le réseau de neurones pour sortir de ce comportement stupide? Merci beaucoup pour vos commentaires et suggestions!

Répondre

0

D'abord je vérifierais que vos données d'entrée sont créées/étiquetées correctement. Essayez d'imprimer quelques valeurs pour vous assurer que cela a du sens. Deuxièmement, je vois généralement ce problème lorsque le taux d'apprentissage est élevé. Vous pouvez essayer de supprimer la couche cachée avec 10 neurones au centre ou d'abaisser le taux d'apprentissage. Je pense qu'un réseau de plusieurs couches est excessif pour ce problème. Essayez d'utiliser ceci pour votre ligne de compilation.

model.compile(loss='binary_crossentropy', optimizer=keras.optimizers.Adam(lr=0.0001), metrics=['accuracy']) 

Un taux d'apprentissage de 0,001 est la valeur par défaut pour Adam mais j'ai trouvé que si 0,001 ne converge pas en utilisant 0,0001 toujours.

+0

Le paramètre supplémentaire du taux d'apprentissage a conduit à des améliorations significatives. Avec le code suivant j'ai eu un résultat au moins décent: 'model.add (Dense (2, input_dim = 2, activation = 'relu')) model.add (Dense (4, activation = 'relu')) model.add (chute de tension (0,5)) model.add (dense (1, activation = 'sigmoïde')) model.compile (perte = 'binary_crossentropy', optimiseur = keras.optimizers.Adam (lr = 0,0001), métriques = ['exactitude']) ' – Inco83