J'ai converti l'ensemble de données MNIST en utilisant le script ici: https://github.com/tensorflow/ tensorflow / blob / master / tensorflow / examples / how_tos / reading_data / convert_to_records.py

Voici le code que j'utilise pour lire le TFRecord, construire le modèle et m'entraîner.

import tensorflow as tf

BATCH_SIZE = 32
epoch = 20

n_hidden_1 = 256 # 1st layer number of neurons
n_hidden_2 = 256 # 2nd layer number of neurons
num_input = 784 # MNIST data input (img shape: 28*28)
num_classes = 10 # MNIST total classes (0-9 digits)

def parse_func(serialized_data):
    keys_to_features = {'image_raw': tf.FixedLenFeature([],tf.string),
                        'label': tf.FixedLenFeature([], tf.int64)}

    parsed_features = tf.parse_single_example(serialized_data, keys_to_features)
    prices = tf.decode_raw(parsed_features['image_raw'],tf.float32)
    label = tf.cast(parsed_features['label'], tf.int32)
    return prices,tf.one_hot(label - 1, 10)

def input_fn(filenames):
    dataset = tf.data.TFRecordDataset(filenames=filenames)
    dataset = dataset.map(parse_func,num_parallel_calls=8)
    dataset = dataset.batch(BATCH_SIZE).prefetch(50)
    # dataset = dataset.shuffle(2000)

    return dataset.make_initializable_iterator()


weights = {
    'h1': tf.Variable(tf.random_normal([num_input, n_hidden_1])),
    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
    'out': tf.Variable(tf.random_normal([n_hidden_2, num_classes]))
}
biases = {
    'b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'b2': tf.Variable(tf.random_normal([n_hidden_2])),
    'out': tf.Variable(tf.random_normal([num_classes]))
}

# Create model
def neural_net(x):
    # Hidden fully connected layer with 256 neurons
    layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
    # Hidden fully connected layer with 256 neurons
    layer_1 = tf.nn.relu(layer_1)
    layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
    layer_2 = tf.nn.relu(layer_2)
    # Output fully connected layer with a neuron for each class
    out_layer = tf.matmul(layer_2, weights['out']) + biases['out']
    return out_layer

def inference(input):
    input = tf.reshape(input,[-1,784])
    dense = tf.layers.dense(inputs=input, units=1024, activation=tf.nn.relu)

    # Logits Layer
    output = tf.layers.dense(inputs=dense, units=10)
    return output


train_iter = input_fn('train_mnist.tfrecords')
valid_iter = input_fn('validation_mnist.tfrecords')

is_training  = tf.placeholder(shape=[],dtype=tf.bool)

img,labels = tf.cond(is_training,lambda :train_iter.get_next(),lambda :valid_iter.get_next())
# img,labels = train_iter.get_next()

logits = neural_net(img)
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=labels))
train_op = tf.train.AdamOptimizer().minimize(loss_op)

prediction = tf.nn.softmax(logits)
correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(labels, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, "float"))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    for e in range(epoch):
        epoch_loss = 0
        sess.run(train_iter.initializer)
        count = 0
        while True:
            try:
                count +=1
                _,c = sess.run([train_op,loss_op],feed_dict={is_training:True})
                epoch_loss += c
            except tf.errors.OutOfRangeError:
                break

        print('Epoch', e, ' completed out of ', epoch, ' Epoch loss: ',epoch_loss,' count :',count)

        total_acc = 0
        count = 0
        sess.run(valid_iter.initializer)
        while True:
            try:
                count += 1
                acc = sess.run(accuracy,feed_dict={is_training:False})
                total_acc += acc
            except tf.errors.OutOfRangeError:
                break

        print('Accuracy: ', total_acc/count,' count ',count)

Je ne sais pas si j'ai fait quelque chose de mal, mais la perte et la précision ne s'améliorent pas après quelques époques. J'ai testé le modèle ci-dessus avec la méthode traditionnelle, la méthode feed_dict. Tout a bien fonctionné, j'ai pu atteindre une précision de 85% avec ce modèle. Voici la sortie du code ci-dessus

Epoch 0  completed out of  20  Epoch loss:  295472940.19140625  count : 1720
Accuracy:  0.5727848101265823  count  158
Epoch 1  completed out of  20  Epoch loss:  2170057598.328125  count : 1720
Accuracy:  0.22231012658227847  count  158
Epoch 2  completed out of  20  Epoch loss:  6578130587.9375  count : 1720
Accuracy:  0.29944620253164556  count  158
Epoch 3  completed out of  20  Epoch loss:  13321823489.0  count : 1720
Accuracy:  0.13310917721518986  count  158
Epoch 4  completed out of  20  Epoch loss:  22460952288.75  count : 1720
Accuracy:  0.20787183544303797  count  158
Epoch 5  completed out of  20  Epoch loss:  34615459125.0  count : 1720
Accuracy:  0.28560126582278483  count  158
Epoch 6  completed out of  20  Epoch loss:  50057282083.0  count : 1720
Accuracy:  0.11748417721518987  count  158  

J'ai vérifié la sortie de l'ensemble de données. Tout semble normal et a une forme correcte. Quelqu'un peut-il signaler ce que j'ai fait de mal ici?

MODIFIER Ceci est le code de travail, qui utilise la méthode traditionnelle feed_dict

# Import MNIST data
from tensorflow.examples.tutorials.mnist import input_data
mnist = input_data.read_data_sets("/tmp/data/", one_hot=True)

import tensorflow as tf

BATCH_SIZE = 32
epoch = 5

# Network Parameters
n_hidden_1 = 256 # 1st layer number of neurons
n_hidden_2 = 256 # 2nd layer number of neurons
num_input = 784 # MNIST data input (img shape: 28*28)
num_classes = 10 # MNIST total classes (0-9 digits)

# tf Graph input
X = tf.placeholder("float", [None, num_input])
Y = tf.placeholder("float", [None, num_classes])

# Store layers weight & bias
weights = {
    'h1': tf.Variable(tf.random_normal([num_input, n_hidden_1])),
    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2])),
    'out': tf.Variable(tf.random_normal([n_hidden_2, num_classes]))
}
biases = {
    'b1': tf.Variable(tf.random_normal([n_hidden_1])),
    'b2': tf.Variable(tf.random_normal([n_hidden_2])),
    'out': tf.Variable(tf.random_normal([num_classes]))
}


# Create model
def neural_net(x):
    # Hidden fully connected layer with 256 neurons
    layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
    # Hidden fully connected layer with 256 neurons
    layer_2 = tf.add(tf.matmul(layer_1, weights['h2']), biases['b2'])
    # Output fully connected layer with a neuron for each class
    out_layer = tf.matmul(layer_2, weights['out']) + biases['out']
    return out_layer

# Construct model
logits = neural_net(X)
loss_op = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits_v2(logits=logits, labels=Y))
train_op = tf.train.AdamOptimizer().minimize(loss_op)

prediction = tf.nn.softmax(logits)
correct_pred = tf.equal(tf.argmax(prediction, 1), tf.argmax(Y, 1))
accuracy = tf.reduce_mean(tf.cast(correct_pred, "float"))

# Start training
with tf.Session() as sess:

    # Run the initializer
    sess.run(tf.global_variables_initializer())

    for e in range(epoch):
        epoch_loss = 0
        for _ in range(int(mnist.train.num_examples / BATCH_SIZE)):
            epoch_x, epoch_y = mnist.train.next_batch(BATCH_SIZE)
            _, c = sess.run([train_op, loss_op], feed_dict={X: epoch_x, Y: epoch_y})
            epoch_loss += c

        print('Epoch', e, ' completed out of ', epoch, ' Epoch loss: ', epoch_loss)

        # Calculate accuracy for MNIST test images
        print("Testing Accuracy:",sess.run(accuracy, feed_dict={X: mnist.test.images,Y: mnist.test.labels}))
0
Thien 15 avril 2018 à 05:05

3 réponses

Meilleure réponse

J'ai trouvé mon erreur. Dans la fonction d'analyse, je décode l'étiquette en un vecteur chaud en utilisant

tf.one_hot(label - 1, 10)

Ça devrait être

tf.one_hot(label, 10)
0
Thien 20 avril 2018 à 00:03

@Thien, j'ai téléchargé tous vos fichiers et les ai exécutés pour générer les tfrecords puis charger les enregistrements tf. J'ai inspecté vos enregistrements tf et le lot d'images renvoie une forme de 32 194 (qui est 14 x 14, pas 28 x 28). J'ai ensuite utilisé matplotlib pour regarder les images et elles ne ressemblent pas du tout à des chiffres et ne ressemblent pas aux données mnist d'origine. Votre encodage / décodage en tfrecords est le problème. Envisagez d'écrire une fonction de codage pour vos enregistrements tf, une fonction de décodage pour vos enregistrements tf, puis de tester ce tfdecode (tfencode (a)) == a.

    x,y = train_iter.get_next()
    a = sess.run(x)
    import matplotlib.pyplot as plt
    plt.imshow( a[0].reshape(14,14) )
    plt.gray()
    plt.show()

enter image description here

0
Anton Codes 16 avril 2018 à 16:24

Sans voir vos fichiers tfrecords, il est difficile de dire avec certitude, mais si vos données sont triées en fonction de l'étiquette (c'est-à-dire que les 10% des premières étiquettes sont 0s, les 10% suivants sont 1s, etc.), un effet significatif sur vos résultats. La précision de 57% après une seule époque semble également assez surprenante (même si je n'ai jamais examiné les résultats à ce stade), il est donc possible que votre métrique d'évaluation (précision) ne soit pas correcte (même si je ne vois rien de mal).

Si vous n'avez pas visualisé vos entrées (c'est-à-dire les images et les étiquettes réelles, pas seulement la forme), faites-le définitivement comme première étape.

Indépendamment de votre question, une faiblesse évidente de votre code est le manque de non-linéarités - une couche linéaire suivie immédiatement d'une couche linéaire équivaut à une couche linéaire. Pour obtenir un comportement plus complexe / de meilleurs résultats, ajoutez une non-linéarité, par ex. tf.nn.relu après chaque couche en dehors de la dernière, par exemple

layer_1 = tf.add(tf.matmul(x, weights['h1']), biases['b1'])
layer_1 = tf.nn.relu(layer_1)

Enfin, prefetch ing un grand nombre d'éléments d'ensemble de données va à l'encontre de l'objectif de prefetching. 1 ou 2 est généralement suffisant.

1
DomJack 15 avril 2018 à 02:35