2017-04-25 2 views
0

J'essaie de mnist pour les débutants, en utilisant des données csv. J'ai obtenu les données csv à partir de here et fait de chaque étiquette un vecteur à chaud. Chaque ligne a 794dims (colum1 ~ 10 comme étiquette et 11 ~ 794 comme pixels). Voici le code que j'ai écrit qui résulte dans l'exactitude terrible.Mauvaise précision à mnist csv données dans tensorflow

from __future__ import absolute_import 
from __future__ import division 
from __future__ import print_function 
import argparse 
import sys 

import tensorflow as tf 
import numpy  as np 

FLAGS = None 

def main(_): 
    # Import data 
    def csv_to_numpy_array(filepath, delimiter): 
     return np.genfromtxt(filepath,delimiter=delimiter, dtype=None) 

    def import_data(): 
     print("loading training data") 
     traindata = csv_to_numpy_array("data/mnist_train_onehot.csv",delimiter=",") 
     [trainY, trainX] = np.hsplit(traindata,[10]); 
     print("loading test data") 
     [testY, testX] = np.hsplit(testdata,[10]); 
     return trainX, trainY, testX, testY 

    x_train, y_train, x_test, y_test = import_data() 

    numX = x_train.shape[1] #784 
    numY = y_train.shape[1] #10 

    # Prepare the placeholder 
    x = tf.placeholder(tf.float32, [None, numX]) #input box 
    y_ = tf.placeholder(tf.float32, [None, numY]) #output box 

    #define weight and biases 
    w = tf.Variable(tf.zeros([numX,numY])) 
    b = tf.Variable(tf.zeros([numY])) 

    #create the model 
    def model(X, w, b): 
     pyx = tf.nn.softmax(tf.matmul(X, w) + b) 
     return pyx 

    y = model(x, w, b) 

    #cost function 
    loss = -tf.reduce_sum(y_*tf.log(y)) 
    # the loss and acc 
    cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_*tf.log(y),reduction_indices=[1])) 
    train_step = tf.train.GradientDescentOptimizer(0.01).minimize(cross_entropy) 
    init = tf.initialize_all_variables() 
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) 
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 

    sess = tf.InteractiveSession() 
    tf.global_variables_initializer().run() 

    # Train 
    for i in range(1000): 
     ind = np.random.choice(100,100) 
     x_train_batch = x_train[ind] 
     y_train_batch = y_train[ind] 
     #run optimization op (backprop) and cost op (to get loss value) 
     _,c = sess.run([train_step, loss], feed_dict={x: x_train_batch, y_: y_train_batch}) 
     if i % 50 == 0: 
      train_acc = accuracy.eval({x: x_train_batch, y_: y_train_batch}) 
      print('step: %d, acc: %6.3f' % (i, train_acc)) 

    # Test trained model 
    print(sess.run(accuracy, feed_dict={x: x_test, 
             y_: y_test})) 

if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 
    parser.add_argument('--data_dir', type=str, default='/tmp/tensorflow/mnist/input_data', 
         help='Directory for storing input data') 
    FLAGS, unparsed = parser.parse_known_args() 
    tf.app.run(main=main, argv=[sys.argv[0]] + unparsed) 

La précision est de 0,098pt. Quelqu'un peut-il s'il vous plaît essayer ce code et me dire ce qui ne va pas sur ce code? Merci beaucoup d'avance.

+0

Essayez de remplacer 'w = tf.Variable (tf.zeros ([NUMX, numY]))' 'avec tf .Variable (tf.random_normal ([numX, numY])) '. Vous devriez essayer d'initialiser vos poids au hasard. Si ce sont tous des zéros, la descente de gradient peut rester bloquée dans la position initiale. Cela peut également être utile: https://www.youtube.com/watch?v=eBbEDRsCmv4 – niczky12

Répondre

0

ici est que vous code avec les changements nécessaires.. Plus précisément, vous pouvez utiliser tf.nn.softmax_cross_entropy_with_logits pour effectuer la lourde levée du calcul de l'entropie croisée pour vous. Une autre amélioration consiste à utiliser loss = tf.reduce_mean ... au lieu de loss = tf.reduce_sum ... *. Cela fera de votre correction d'entraînement la moyenne de toutes les erreurs qui ont été faites au lieu de la somme. Vous obtiendrez des balançoires d'entraînement sauvages et incontrôlées si vous utilisez la somme et vous devrez compenser en utilisant un très petit facteur de descente de gradient. Si vous trouvez que vous devez utiliser quelque chose en descente de gradient supérieure à 1 ou inférieure à .1, vous pouvez probablement résoudre le problème en utilisant reduce_mean pour la perte.

Voici votre code.

from __future__ import absolute_import 
from __future__ import division 
from __future__ import print_function 
import argparse 
import sys 

import tensorflow as tf 
import numpy  as np 

FLAGS = None 

def main(_): 
    # Import data 
    def csv_to_numpy_array(filepath, delimiter): 
     return np.genfromtxt(filepath,delimiter=delimiter, dtype=None) 

    def import_data(): 
     print("loading training data") 
     traindata = csv_to_numpy_array("data/mnist_train_onehot.csv",delimiter=",") 
     [trainY, trainX] = np.hsplit(traindata,[10]); 
     print("loading test data") 
     [testY, testX] = np.hsplit(testdata,[10]); 
     return trainX, trainY, testX, testY 

    x_train, y_train, x_test, y_test = import_data() 

    numX = x_train.shape[1] #784 
    numY = y_train.shape[1] #10 

    # Prepare the placeholder 
    x = tf.placeholder(tf.float32, [None, numX]) #input box 
    y_ = tf.placeholder(tf.float32, [None, numY]) #output box 

    #define weight and biases 
    w = tf.Variable(tf.zeros([numX,numY])) 
    b = tf.Variable(tf.zeros([numY])) 

    y = tf.matmul(x, w) + b 

    # unused for this model 
    keep_prob = tf.placeholder(tf.float32) 

    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=y, labels=y_)) 
    train = tf.train.GradientDescentOptimizer(0.5).minimize(loss) 

    # Test trained model 
    correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_, 1)) 
    percent_correct = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) 

    init = tf.initialize_all_variables() 

    sess = tf.InteractiveSession() 
    tf.global_variables_initializer().run() 

    # Train 
    for i in range(1000): 
     ind = np.random.choice(x_train.shape[0],100) 
     x_train_batch = x_train[ind] 
     y_train_batch = y_train[ind] 
     #run optimization op (backprop) and cost op (to get loss value) 
     _,c = sess.run([train_step, loss], feed_dict={x: x_train_batch, y_: y_train_batch}) 
     if i % 50 == 0: 
      train_acc = percent_correct.eval({x: x_train_batch, y_: y_train_batch}) 
      print('step: %d, acc: %6.3f' % (i, train_acc)) 

    # Test trained model 
    print(sess.run(percent_correct, feed_dict={x: x_test, 
             y_: y_test})) 

if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 
    parser.add_argument('--data_dir', type=str, default='/tmp/tensorflow/mnist/input_data', 
         help='Directory for storing input data') 
    FLAGS, unparsed = parser.parse_known_args() 
    tf.app.run(main=main, argv=[sys.argv[0]] + unparsed) 

Voici un lien vers quelques architectures différentes de tensorflow de mnist https://github.com/panchishin/learn-to-tensorflow/blob/master/examples/mnist_model_comparison.py tous dans un seul script

+0

Merci pour la réponse rapide. J'ai changé la fonction de perte comme vous l'avez mentionné, ainsi que de changer l'initialisation de poids et de biais. Mais la précision est encore faible (0.53). Je vais également me référer au lien. – Ted

+0

En regardant la ligne "ind = np.random.choice (100,100)" Je vois que vous n'utilisez que les 100 premiers éléments pour l'entraînement mais vous voulez utiliser tous les éléments d'entraînement pour l'entraînement. Essayez d'utiliser "ind = np.random.choice (x_train.shape [0], 100)" – Wontonimo

+0

Merci beaucoup. Maintenant, j'ai obtenu le résultat "plausible" (0.89pt) grâce à votre aide. Je comprends que l'utilisation du choix aléatoire dans ce cas est "random.choice (#alldata, #batchsize)". Je suis tellement content que vous m'avez aidé. Merci encore. – Ted

0

Il y a des problèmes possibles:

1- Initialiser vos variables au hasard et non zéro

2- Vous pouvez mal comprendre le format de fichier .csv, où vous avez obtenu .csv, dit le format est label, pix-11, pix-12, pix-13, ...

3- Essayez d'utiliser tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits , llabels)) la méthode que vous utilisez pour calculer la perte est numériquement instable. Mise à jour: dans ce cas ne pas user tf.nn.softmax parce que tf.nn.softmax_cross_entropy_with_logits ont en interne softmax normalisateur et entropie croisée (merci pour @ commentaire ml4294)

+0

Remarque: Si vous utilisez 'tf.nn.softmax_cross_entropy_with_logits()', vous ne devriez pas utiliser la fonction 'softmax()' dans votre Fonction 'model()', car la fonction d'entropie croisée softmax intégrée à TensorFlow attend des logits non normalisés. – ml4294

+0

Oui, votre droite. Je mets à jour ma réponse –

+0

Merci pour le conseil. J'ai essayé 1 et 3, puis la précision est devenue un peu plus élevée (mais toujours faible, 0.53pt). En ce qui concerne le format, j'ai fait les étiquettes 10dims vecteur à chaud. (ex étiquette 2 correspond à [0,0,1,0,0,0,0,0,0,0]) Ensuite, il ne devrait pas se tromper je suppose ... – Ted