2016-04-29 4 views
3

Je compare Keras Neural-Net avec Logistic Regression from Scikit-learn simple sur les données IRIS. Je m'attends à ce que Keras-NN fonctionnera mieux, comme suggéré par this post.Comment faire Keras Neural Net surperformant la régression logistique sur les données Iris

Mais pourquoi en imitant le code là-bas, le résultat de Keras-NN est inférieur à Régression logistique?

import seaborn as sns 
import numpy as np 
from sklearn.cross_validation import train_test_split 
from sklearn.linear_model import LogisticRegressionCV 
from keras.models import Sequential 
from keras.layers.core import Dense, Activation 
from keras.utils import np_utils 

# Prepare data 
iris = sns.load_dataset("iris") 
X = iris.values[:, 0:4] 
y = iris.values[:, 4] 

# Make test and train set 
train_X, test_X, train_y, test_y = train_test_split(X, y, train_size=0.5, random_state=0) 

################################ 
# Evaluate Logistic Regression 
################################ 
lr = LogisticRegressionCV() 
lr.fit(train_X, train_y) 
pred_y = lr.predict(test_X) 
print("Test fraction correct (LR-Accuracy) = {:.2f}".format(lr.score(test_X, test_y))) 



################################ 
# Evaluate Keras Neural Network 
################################ 

# Make ONE-HOT 
def one_hot_encode_object_array(arr): 
    '''One hot encode a numpy array of objects (e.g. strings)''' 
    uniques, ids = np.unique(arr, return_inverse=True) 
    return np_utils.to_categorical(ids, len(uniques)) 


train_y_ohe = one_hot_encode_object_array(train_y) 
test_y_ohe = one_hot_encode_object_array(test_y) 

model = Sequential() 
model.add(Dense(16, input_shape=(4,))) 
model.add(Activation('sigmoid')) 
model.add(Dense(3)) 
model.add(Activation('softmax')) 
model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer='adam') 

# Actual modelling 
model.fit(train_X, train_y_ohe, verbose=0, batch_size=1) 
score, accuracy = model.evaluate(test_X, test_y_ohe, batch_size=16, verbose=0) 
print("Test fraction correct (NN-Score) = {:.2f}".format(score)) 
print("Test fraction correct (NN-Accuracy) = {:.2f}".format(accuracy)) 

J'utilise cette version de Keras

In [2]: keras.__version__ 
Out[2]: '1.0.1' 

Le résultat montre:

Test fraction correct (LR-Accuracy) = 0.83 
Test fraction correct (NN-Score) = 0.75 
Test fraction correct (NN-Accuracy) = 0.60 

Selon that post, la précision de Keras devrait être 0,99. Qu'est ce qui ne s'est pas bien passé?

Répondre

1

Le nombre par défaut d'époques a été réduit de 100 dans Keras version 0 à 10 dans Keras version 1, vient de sortir ce mois-ci (Avril 2016). Essayez:

model.fit(train_X, train_y_ohe, verbose=0, batch_size=1, nb_epoch=100) 
2

Votre réseau de neurones est assez simple. Essayez de créer un réseau neuronal profond en y ajoutant plus de neurones et de couches. En outre, il est important d'adapter vos fonctionnalités. Essayez l'initialiseur glorot_uniform. Last but not least, augmenter l'époque et voir si la perte diminue à chaque époque.

Alors là, vous allez:

model = Sequential() 
model.add(Dense(input_dim=4, output_dim=512, init='glorot_uniform')) 
model.add(PReLU(input_shape=(512,))) 
model.add(BatchNormalization((512,))) 
model.add(Dropout(0.5)) 

model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform')) 
model.add(PReLU(input_shape=(512,))) 
model.add(BatchNormalization((512,))) 
model.add(Dropout(0.5)) 

model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform')) 
model.add(PReLU(input_shape=(512,))) 
model.add(BatchNormalization((512,))) 
model.add(Dropout(0.5)) 

model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform')) 
model.add(PReLU(input_shape=(512,))) 
model.add(BatchNormalization((512,))) 
model.add(Dropout(0.5)) 

model.add(Dense(input_dim=512, output_dim=512, init='glorot_uniform')) 
model.add(PReLU(input_shape=(512,))) 
model.add(BatchNormalization((512,))) 
model.add(Dropout(0.5)) 

model.add(Dense(input_dim=512, output_dim=3, init='glorot_uniform')) 
model.add(Activation('softmax')) 

Cela atteint environ 0,97 à 120e époque