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}))
3 réponses
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)
@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()
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.
Questions connexes
De nouvelles questions
python
Python est un langage de programmation multi-paradigme, typé dynamiquement et polyvalent. Il est conçu pour être rapide à apprendre, comprendre, utiliser et appliquer une syntaxe propre et uniforme. Veuillez noter que Python 2 est officiellement hors support à partir du 01-01-2020. Néanmoins, pour les questions Python spécifiques à la version, ajoutez la balise [python-2.7] ou [python-3.x]. Lorsque vous utilisez une variante Python (par exemple, Jython, PyPy) ou une bibliothèque (par exemple, Pandas et NumPy), veuillez l'inclure dans les balises.