1

J'ai construit un réseau de neurones avec tensorflow. C'est un simple réseau de neurones à 3 couches dont la dernière couche est softmax.faible précision de formation d'un réseau de neurones avec des données de revenu adulte

Je l'ai essayé sur un jeu de données de revenu adulte standard (par exemple https://archive.ics.uci.edu/ml/datasets/adult) car il est disponible au public, a une bonne quantité de données (environ 50k exemples) et fournit également des données de test distinctes.

Comme il y a quelques attributs catégoriques, je les ai convertis en un codage à chaud. Pour le réseau de neurones, j'ai utilisé l'initialisation de Xavier et Adam Optimizer. Comme il n'y a que deux classes de sortie (> 50k et < = 50k), la dernière couche softmax n'avait que deux neurones. Après une extension de codage à chaud, les 14 attributs/colonnes se sont étendus à 108 colonnes. J'ai expérimenté avec un nombre différent de neurones dans les deux premières couches cachées (de 5 à 25). J'ai aussi expérimenté avec le nombre d'itérations (de 1000 à 20000).

La précision de l'entraînement n'a pas été beaucoup affectée par le nombre de neurones. Il est monté un peu avec plus d'itérations. Cependant, je ne pouvais pas faire mieux que 82% :(

Ai-je manqué quelque chose de basique dans mon approche? Quelqu'un at-il essayé ceci (réseau de neurones avec cet ensemble de données)? Si oui, quels sont les résultats attendus? en raison de valeurs manquantes? (J'ai l'intention d'essayer de filtrer toutes les valeurs manquantes s'il n'y a pas beaucoup dans le jeu de données.)

D'autres idées? Voici mon code de réseau neural tensorflow au cas où il y aurait des bugs dans il etc.

def create_placeholders(n_x, n_y): 
    X = tf.placeholder(tf.float32, [n_x, None], name = "X") 
    Y = tf.placeholder(tf.float32, [n_y, None], name = "Y") 
    return X, Y 

def initialize_parameters(num_features): 
    tf.set_random_seed(1)     # so that your "random" numbers match ours 
    layer_one_neurons = 5 
    layer_two_neurons = 5 
    layer_three_neurons = 2 
    W1 = tf.get_variable("W1", [layer_one_neurons,num_features], initializer = tf.contrib.layers.xavier_initializer(seed = 1)) 
    b1 = tf.get_variable("b1", [layer_one_neurons,1], initializer = tf.zeros_initializer()) 
    W2 = tf.get_variable("W2", [layer_two_neurons,layer_one_neurons], initializer = tf.contrib.layers.xavier_initializer(seed = 1)) 
    b2 = tf.get_variable("b2", [layer_two_neurons,1], initializer = tf.zeros_initializer()) 
    W3 = tf.get_variable("W3", [layer_three_neurons,layer_two_neurons], initializer = tf.contrib.layers.xavier_initializer(seed = 1)) 
    b3 = tf.get_variable("b3", [layer_three_neurons,1], initializer = tf.zeros_initializer()) 
    parameters = {"W1": W1, 
         "b1": b1, 
         "W2": W2, 
         "b2": b2, 
         "W3": W3, 
         "b3": b3} 

    return parameters 

def forward_propagation(X, parameters): 
    """ 
    Implements the forward propagation for the model: LINEAR -> RELU -> LINEAR -> RELU -> LINEAR -> SOFTMAX 

    Arguments: 
    X -- input dataset placeholder, of shape (input size, number of examples) 
    parameters -- python dictionary containing your parameters "W1", "b1", "W2", "b2", "W3", "b3" 
        the shapes are given in initialize_parameters 

    Returns: 
    Z3 -- the output of the last LINEAR unit 
    """ 

    # Retrieve the parameters from the dictionary "parameters" 
    W1 = parameters['W1'] 
    b1 = parameters['b1'] 
    W2 = parameters['W2'] 
    b2 = parameters['b2'] 
    W3 = parameters['W3'] 
    b3 = parameters['b3'] 

    Z1 = tf.add(tf.matmul(W1, X), b1)           
    A1 = tf.nn.relu(Z1)            
    Z2 = tf.add(tf.matmul(W2, A1), b2)         
    A2 = tf.nn.relu(Z2)           
    Z3 = tf.add(tf.matmul(W3, A2), b3) 

    return Z3 

def compute_cost(Z3, Y): 
    """ 
    Computes the cost 

    Arguments: 
    Z3 -- output of forward propagation (output of the last LINEAR unit), of shape (6, number of examples) 
    Y -- "true" labels vector placeholder, same shape as Z3 

    Returns: 
    cost - Tensor of the cost function 
    """ 

    # to fit the tensorflow requirement for tf.nn.softmax_cross_entropy_with_logits(...,...) 
    logits = tf.transpose(Z3) 
    labels = tf.transpose(Y) 

    cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits = logits, labels = labels)) 

    return cost 

def model(X_train, Y_train, X_test, Y_test, learning_rate = 0.0001, num_epochs = 1000, print_cost = True): 
    """ 
    Implements a three-layer tensorflow neural network: LINEAR->RELU->LINEAR->RELU->LINEAR->SOFTMAX. 

    Arguments: 
    X_train -- training set, of shape (input size = 12288, number of training examples = 1080) 
    Y_train -- test set, of shape (output size = 6, number of training examples = 1080) 
    X_test -- training set, of shape (input size = 12288, number of training examples = 120) 
    Y_test -- test set, of shape (output size = 6, number of test examples = 120) 
    learning_rate -- learning rate of the optimization 
    num_epochs -- number of epochs of the optimization loop 
    print_cost -- True to print the cost every 100 epochs 

    Returns: 
    parameters -- parameters learnt by the model. They can then be used to predict. 
    """ 

    ops.reset_default_graph()       # to be able to rerun the model without overwriting tf variables 
    tf.set_random_seed(1)        # to keep consistent results 
    seed = 3           # to keep consistent results 
    (n_x, m) = X_train.shape       # (n_x: input size, m : number of examples in the train set) 
    n_y = Y_train.shape[0]       # n_y : output size 
    costs = []          # To keep track of the cost 

    # Create Placeholders of shape (n_x, n_y) 
    X, Y = create_placeholders(n_x, n_y) 

    # Initialize parameters 
    parameters = initialize_parameters(X_train.shape[0]) 

    # Forward propagation: Build the forward propagation in the tensorflow graph 
    Z3 = forward_propagation(X, parameters) 

    # Cost function: Add cost function to tensorflow graph 
    cost = compute_cost(Z3, Y) 

    # Backpropagation: Define the tensorflow optimizer. Use an AdamOptimizer. 
    optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost) 

    # Initialize all the variables 
    init = tf.global_variables_initializer() 

    # Start the session to compute the tensorflow graph 
    with tf.Session() as sess: 

     # Run the initialization 
     sess.run(init) 

     # Do the training loop 
     for epoch in range(num_epochs): 
      _ , epoch_cost = sess.run([optimizer, cost], feed_dict={X: X_train, Y: Y_train}) 

      # Print the cost every epoch 
      if print_cost == True and epoch % 100 == 0: 
       print ("Cost after epoch %i: %f" % (epoch, epoch_cost)) 
      if print_cost == True and epoch % 5 == 0: 
       costs.append(epoch_cost) 

     # plot the cost 
     plt.plot(np.squeeze(costs)) 
     plt.ylabel('cost') 
     plt.xlabel('iterations (per tens)') 
     plt.title("Learning rate =" + str(learning_rate)) 
     plt.show() 

     # lets save the parameters in a variable 
     parameters = sess.run(parameters) 
     print ("Parameters have been trained!") 

     # Calculate the correct predictions 
     correct_prediction = tf.equal(tf.argmax(Z3), tf.argmax(Y)) 

     # Calculate accuracy on the test set 
     accuracy = tf.reduce_mean(tf.cast(correct_prediction, "float")) 

     print ("Train Accuracy:", accuracy.eval({X: X_train, Y: Y_train})) 
     #print ("Test Accuracy:", accuracy.eval({X: X_test, Y: Y_test})) 

     return parameters 

import math 
import numpy as np 
import h5py 
import matplotlib.pyplot as plt 
import tensorflow as tf 
from tensorflow.python.framework import ops 
import pandas as pd 
%matplotlib inline 
np.random.seed(1) 

df = pd.read_csv('adult.data', header = None) 
X_train_orig = df.drop(df.columns[[14]], axis=1, inplace=False) 
Y_train_orig = df[[14]] 
X_train = pd.get_dummies(X_train_orig) # get one hot encoding 
Y_train = pd.get_dummies(Y_train_orig) # get one hot encoding 
parameters = model(X_train.T, Y_train.T, None, None, num_epochs = 10000) 

Toutes les suggestions pour d'autres ensemble de données publiques pour essayer cela?

J'ai essayé des algorithmes standards sur cet ensemble de données à partir scikit apprendre avec les paramètres par défaut et je me suis exactitudes suivantes:

Random Forest: 86 
SVM:    96 
kNN:    83 
MLP:    79 

J'ai téléchargé mon carnet ipython pour cela à: https://github.com/sameermahajan/ClassifiersWithIncomeData/blob/master/Scikit%2BLearn%2BClassifiers.ipynb

La meilleure précision est avec SVM ce qui peut être attendu d'une explication qui peut être vu de: http://scikit-learn.org/stable/auto_examples/classification/plot_classifier_comparison.html intéressant SVM a également pris beaucoup de temps à courir, beaucoup plus que toute autre méthode.

Cela peut ne pas être un bon problème à résoudre par un réseau de neurones regardant la précision MLPClassifier ci-dessus. Mon réseau de neurones n'était pas si mauvais après tout! Merci pour toutes les réponses et votre intérêt pour cela.

Répondre

1

Je n'ai pas expérimenté sur ce jeu de données, mais après avoir lu des articles et fait quelques recherches, il semble que votre réseau fonctionne bien.

D'abord, votre précision est-elle calculée à partir de l'ensemble d'apprentissage ou de l'ensemble de test? Avoir les deux vous donnera un bon aperçu de la performance de votre réseau.

Je suis encore un peu nouvelle à l'apprentissage de la machine, mais je peux peut-être donner un peu d'aide:

En regardant le lien de documentation de données ici: https://archive.ics.uci.edu/ml/machine-learning-databases/adult/adult.names

Et cet article: https://cseweb.ucsd.edu/classes/wi17/cse258-a/reports/a120.pdf

De ces liens 85% de précision sur la formation et l'ensemble de test ressemble à un bon score, vous n'êtes pas trop loin.

Avez-vous une sorte de validation croisée pour rechercher le sur-réseau de votre réseau?

Je n'ai pas votre code donc je ne peux pas vous aider si c'est un bug ou un problème de programmation, peut-être que partager votre code pourrait être une bonne idée.

Je pense que vous obtiendrez plus de précision en pré-traitant vos données: Il y a beaucoup d'inconnues dans vos données et les réseaux de neurones sont très sensibles aux erreurs d'étiquetage et aux mauvaises données.

  • Vous devriez essayer de trouver et remplacer ou supprimer les inconnus.

  • Vous pouvez également essayer d'identifier les fonctionnalités les plus utiles et supprimer celles qui sont presque inutiles.

  • La mise à l'échelle/normalisation des données peut également être très importante pour les réseaux de neurones, je n'ai pas beaucoup étudié les données mais peut-être pouvez-vous essayer de faire évoluer vos données entre 0 et 1 déjà fait.

  • Le document que j'ai lié vous semble voir une amélioration des performances en ajoutant des couches jusqu'à 5 couches, avez-vous essayé d'ajouter plus de couches?

  • Vous pouvez également ajouter la suppression si vous avez des sur-réseaux, si ce n'est déjà fait. J'essaierais peut-être d'autres réseaux qui sont généralement bons pour les tâches comme SVM (Support Vector Machine) ou Logistic Regression ou encore Random Forest mais je ne suis pas sûr en regardant le résultat que ceux-ci fonctionneront mieux que le réseau neuronal artificiel .

Je prends aussi un coup d'œil à ces liens: https://www.kaggle.com/wenruliu/adult-income-dataset/feed

https://www.kaggle.com/wenruliu/income-prediction

Dans ce lien, il y a des gens qui essaient d'algorithmes et de donner des conseils pour traiter les données et à aborder ce sujet.

L'espoir a aidé

Bonne chance, Marc.

+0

Merci pour les liens. Je vais aller au-dessus d'eux. C'est la précision de l'entraînement donc sur les données d'entraînement. Je n'ai pas calculé la précision du test car je pensais que la précision de l'entraînement elle-même était si faible. Je vais partager mon code et aussi essayer le prétraitement. Bon de savoir que je ne suis pas loin :) Je m'attendais à au moins 95% + précision de formation ... –

+0

Pas de problème, j'espère que ma réponse vous aidera! Tenez-moi au courant de vos résultats, je suis très intéressé. –

0

Je pense que vous vous concentrez trop sur la structure de votre réseau et vous oubliez que vos résultats dépendent aussi largement de la qualité des données. J'ai essayé une forêt aléatoire rapide et prête à l'emploi et elle m'a donné des résultats similaires à ceux que vous avez obtenus (acc = 0.8275238).

Je vous suggère de faire de l'ingénierie de fonctionnalités (le lien kaggle fourni par @Marc a quelques bons exemples).Déterminez une stratégie pour vos NA (regardez here), regroupez des valeurs lorsque vous avez plusieurs niveaux de facteur dans des variables catégorielles (par exemple des pays regroupés en continents) ou discrétisez des variables continues (variable d'âge en niveaux comme ancien, moyen, jeune). Jouez avec vos données, étudiez votre jeu de données et essayez d'appliquer votre expertise pour supprimer les informations redondantes ou trop étroites. Une fois cela fait, commencez à peaufiner votre modèle. De plus, vous pouvez envisager de faire comme moi: utilisez des modèles d'ensemble (qui sont généralement rapides et assez précis avec les valeurs par défaut) comme RF ou XGB pour vérifier si les résultats sont cohérents entre tous vos modèles. Une fois que vous êtes sûr d'être dans la bonne voie, vous pouvez commencer à peaufiner la structure, les couches, etc. et voir si vous pouvez pousser vos résultats encore plus loin.

Espérons que cela aide.

Bonne chance!

+0

merci pour les conseils. Je vais essayer ça. –