J'ai ajusté le chargement des données du TensorFlow MNIST example pour utiliser le original MNIST data. L'exemple original obtient une précision supérieure à 0,80 après 100 époques. Mon exemple ajusté (défini use_original = False
pour l'utiliser) obtient seulement environ 0,09 - 0,10 précision (qui est juste aléatoire). Pourriez-vous s'il vous plaît expliquer pourquoi?Pourquoi l'exemple TF MNIST ne fonctionne pas avec les données d'origine?
#!/usr/bin/env python
"""MNIST with Tensorflow."""
from tensorflow.examples.tutorials.mnist import input_data
import tensorflow as tf
from struct import unpack
import gzip
from numpy import zeros, uint8
from sklearn.preprocessing import OneHotEncoder
use_original = True
def get_labeled_data(imagefile, labelfile):
"""
Read input-vector (image) and target class (label, 0-9).
Return
------
tuple of lists
"""
# Open the images with gzip in read binary mode
images = gzip.open(imagefile, 'rb')
labels = gzip.open(labelfile, 'rb')
# Read the binary data
# We have to get big endian unsigned int. So we need '>I'
# Get metadata for images
images.read(4) # skip the magic_number
number_of_images = images.read(4)
number_of_images = unpack('>I', number_of_images)[0]
rows = images.read(4)
rows = unpack('>I', rows)[0]
cols = images.read(4)
cols = unpack('>I', cols)[0]
# Get metadata for labels
labels.read(4) # skip the magic_number
N = labels.read(4)
N = unpack('>I', N)[0]
if number_of_images != N:
raise Exception('number of labels did not match the number of images')
# Get the data
x = zeros((N, rows * cols), dtype=uint8) # Initialize numpy array
y = zeros((N, 1), dtype=uint8) # Initialize numpy array
for i in range(N):
if i % 1000 == 0:
print("%s: %i" % (imagefile, i))
j = 0
for row in range(rows):
for col in range(cols):
tmp_pixel = images.read(1) # Just a single byte
tmp_pixel = unpack('>B', tmp_pixel)[0]
x[i][j] = tmp_pixel
j += 1
tmp_label = labels.read(1)
y[i] = unpack('>B', tmp_label)[0]
enc = OneHotEncoder()
enc.fit(y)
y = enc.transform(y).toarray()
return (x, y)
epochs = 20000
def weight_variable(shape):
initial = tf.truncated_normal(shape, stddev=0.1)
return tf.Variable(initial)
def bias_variable(shape):
initial = tf.constant(0.1, shape=shape)
return tf.Variable(initial)
def conv2d(x, W):
return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')
def max_pool_2x2(x):
return tf.nn.max_pool(x, ksize=[1, 2, 2, 1],
strides=[1, 2, 2, 1], padding='SAME')
def eval_network(dataset, correct_prediction):
correct_sum = 0
total_test = 0
for i in range(dataset.labels.shape[0]/1000):
feed_dict = {x: dataset.images[i * 1000:(i + 1) * 1000],
y_: dataset.labels[i * 1000:(i + 1) * 1000],
keep_prob: 1.0}
test_correct = correct_prediction.eval(feed_dict=feed_dict)
correct_sum += sum(test_correct)
total_test += len(test_correct)
return float(correct_sum)/total_test
def add_score(filename, mnist, scoring, epoch, other=''):
with open(filename, "a") as myfile:
train = eval_network(mnist.train, scoring)
test = eval_network(mnist.test, scoring)
myfile.write("%i;%0.6f;%0.6f;%s\n" % (epoch, train, test, other))
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
sess = tf.InteractiveSession()
x = tf.placeholder(tf.float32, shape=[None, 784])
y_ = tf.placeholder(tf.float32, shape=[None, 10])
W = tf.Variable(tf.zeros([784, 10]))
b = tf.Variable(tf.zeros([10]))
sess.run(tf.initialize_all_variables())
y = tf.nn.softmax(tf.matmul(x, W) + b)
W_conv1 = weight_variable([5, 5, 1, 32])
b_conv1 = bias_variable([32])
x_image = tf.reshape(x, [-1, 28, 28, 1])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
h_pool1 = max_pool_2x2(h_conv1)
W_conv2 = weight_variable([5, 5, 32, 64])
b_conv2 = bias_variable([64])
h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)
h_pool2 = max_pool_2x2(h_conv2)
W_fc1 = weight_variable([7 * 7 * 64, 1024])
b_fc1 = bias_variable([1024])
h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
keep_prob = tf.placeholder(tf.float32)
h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)
W_fc2 = weight_variable([1024, 10])
b_fc2 = bias_variable([10])
y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)
cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv),
reduction_indices=[1]))
train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)
correct_prediction = tf.equal(tf.argmax(y_conv, 1), tf.argmax(y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
sess.run(tf.initialize_all_variables())
# Data loading
if use_original:
mnist = input_data.read_data_sets('MNIST_data', one_hot=True)
else:
mnist = lambda: None
setattr(mnist, 'train', lambda: None)
setattr(mnist, 'test', lambda: None)
setattr(mnist.train, 'images', lambda: None)
setattr(mnist.train, 'labels', lambda: None)
setattr(mnist.test, 'images', lambda: None)
setattr(mnist.test, 'labels', lambda: None)
xs, ys = get_labeled_data('mnist/train-images-idx3-ubyte.gz',
'mnist/train-labels-idx1-ubyte.gz')
mnist.train.images = xs
mnist.train.labels = ys
xst, yst = get_labeled_data('mnist/t10k-images-idx3-ubyte.gz',
'mnist/t10k-labels-idx1-ubyte.gz')
mnist.test.images = xst
mnist.test.labels = yst
for i in range(epochs):
if use_original:
batch = mnist.train.next_batch(50) # This works
else:
# This doesnt work
batch = (xs[i * 50:(i + 1) * 50], ys[i * 50:(i + 1) * 50])
if i % 100 == 0:
add_score('accuracy.csv',
mnist,
correct_prediction,
i)
train_step.run(feed_dict={x: batch[0],
y_: batch[1],
keep_prob: 0.5})
add_score('accuracy.csv', mnist, correct_prediction, epochs)
C'est beaucoup de code à lire, et encore plus de contexte à lire hors site. Serait-il possible de sortir et d'annoter vos changements? Il est probable que vous ayez une nouvelle forme manquante ou défectueuse, de sorte que les images sont présentées au réseau de manière efficace avec les pixels mélangés. Comme vous utilisez CNN, il ne sera pas en mesure d'apprendre à partir d'une réorganisation arbitraire, il doit y avoir une image avec une corrélation à courte distance. –
@NeilSlater Les modifications sont tout ce qui devient actif lorsque vous utilisez 'use_original = False'. Donc, l'erreur est la plus probable dans 'get_labeled_data'. Je vais tester dans une minute si le brassage est la raison. –
Je ne pense pas que le shuffling soit la raison. Les étiquettes ne sont pas commandées et comme seulement 100 époques (5000 exemplaires vus de 60 000 exemplaires disponibles) sont nécessaires pour obtenir une précision supérieure à 0,8, je doute que ce soit la raison. –