Tensorflow shuffle_batch from multiple files breaks labelling - python

I am trying to write my own MNIST digits classifier using Tensorflow and I am stuck with a tf.train.shuffle_batch function's weird behaviour.
The problem appears when I am trying to load images and labels from different files, shuffle batch seems to shuffle both labels and images on their own, therefore producing bad labeled data. The data was taken from here
Is it a defined behaviour for shuffle_batch function?
How would you suggest dealing with such situations when data and labels are different files?
Here is my code
DATA = 'train-images.idx3-ubyte'
LABELS = 'train-labels.idx1-ubyte'
data_queue = tf.train.string_input_producer([DATA,])
label_queue = tf.train.string_input_producer([LABELS,])
NUM_EPOCHS = 2
BATCH_SIZE = 10
reader_data = tf.FixedLengthRecordReader(record_bytes=28*28, header_bytes = 16)
reader_labels = tf.FixedLengthRecordReader(record_bytes=1, header_bytes = 8)
(_,data_rec) = reader_data.read(data_queue)
(_,label_rec) = reader_labels.read(label_queue)
image = tf.decode_raw(data_rec, tf.uint8)
image = tf.reshape(image, [28, 28, 1])
label = tf.decode_raw(label_rec, tf.uint8)
label = tf.reshape(label, [1])
image_batch, label_batch = tf.train.shuffle_batch([image, label],
batch_size=BATCH_SIZE,
capacity=100,
min_after_dequeue = 30)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
image = image_batch[1]
im = image.eval()
print("im_batch shape :" + str(image_batch.get_shape().as_list()))
print("label shape :" + str(label_batch.get_shape().as_list()))
print("label is :" + str(label_batch[1].eval()))
# print("output is :" + str(conv1.eval()))
plt.imshow(np.reshape(im, [-1, 28]), cmap='gray')
plt.show()
coord.request_stop()
coord.join(threads)

I think the problem arises because you evaluate image and label_batch[1] in separate Tensor.eval() calls. This means that you are getting values from two different batches. If instead you write:
im, lbl = sess.run([image_batch[1], label_batch[1]])
...you should get a matching image and label from the same batch.

Related

How to resize image tensors

The following is my code where I'm converting every image to PIL and then turning them into Pytorch tensors:
transform = transforms.Compose([transforms.PILToTensor()])
# choose the training and test datasets
train_data = os.listdir('data/training/')
testing_data = os.listdir('data/testing/')
train_tensors = []
test_tensors = []
for train_image in train_data:
img = Image.open('data/training/' + train_image)
train_tensors.append(transform(img))
for test_image in testing_data:
img = Image.open('data/testing/' + test_image)
test_tensors.append(transform(img))
# Print out some stats about the training and test data
print('Train data, number of images: ', len(train_data))
print('Test data, number of images: ', len(testing_data))
batch_size = 20
train_loader = DataLoader(train_tensors, batch_size=batch_size, shuffle=True)
test_loader = DataLoader(test_tensors, batch_size=batch_size, shuffle=True)
# specify the image classes
classes = ['checked', 'unchecked', 'other']
# obtain one batch of training images
dataiter = iter(train_loader)
images, labels = dataiter.next()
images = images.numpy()
However, I am getting this error:
RuntimeError: stack expects each tensor to be equal size, but got [4, 66, 268] at entry 0 and [4, 88, 160] at entry 1
This is because my images are not resized prior to PIL -> Tensor. What is the correct way of resizing data images?
Try to utilize ImageFolder from torchvision, and assuming that images have diff size, you can use CenterCrop or RandomResizedCrop depending on your task. Check the Full list.
Here is an example:
train_dir = "data/training/"
train_dataset = datasets.ImageFolder(
train_dir,
transforms.Compose([
transforms.RandomResizedCrop(img_size), # image size int or tuple
# Add more transforms here
transforms.ToTensor(), # convert to tensor at the end
]))
train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)

Keras image generator keep giving different number of labels

I am trying to make a simple fine turned Resnet50 model using the Market1501 dataset and keras.
So the data set contains images (12000 or so) and 751 labels that I want to use (0-750). I can fit the data into a single go so I have to use a image generator for this.
So my base model is like this
base_model = ResNet50(weights='imagenet', include_top=False,input_tensor=Input(shape=(224,224,3)))
x = base_model.output
x = Flatten(name="flatten")(x)
x = Dropout(0.5)(x)
x = Dense(750, activation='softmax', name='fc8',kernel_initializer=RandomNormal(mean=0.0, stddev=0.001))(x)
model = Model(input=base_model.input, output=x)
And my image generator is like this
def image_generator(image_array, batch_size):
# Define data generator arguments
datagen_args = dict(rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.1,
zoom_range=0.1,
horizontal_flip=True)
# Create different data generators for each image
# This gives each image a unique transformation which will make it harder for the network
datagen = ImageDataGenerator(**datagen_args)
while True:
number_of_images = len(image_array)
indices = np.random.permutation(np.arange(number_of_images))
num_batches = number_of_images // batch_size
for bid in range(num_batches):
# loop once per batch
images = []
lables = []
batch_indices = indices[bid * batch_size: (bid + 1) * batch_size]
for i in batch_indices:
img, lbl = image_array[i]
# Process images
img = image.load_img(os.path.join(TRAIN, img), target_size=[224, 224])
img = image.img_to_array(img)
#img = np.expand_dims(img, axis=0)
img = preprocess_input(img)
img = datagen.random_transform(img)
images.append(img)
lables.append(lbl)
yield np.array(images), to_categorical(lables)
And I use it like this
batch_size = 64
NUM_EPOCHS = 40
train_gen = image_generator(image_array, batch_size)
num_train_steps = len(image_array)
The issue is it give me this error
Error when checking target: expected fc8 to have shape (751,) but got array with shape (742,)
And the bigger issue is the 2nd number keep changing so I know its something with the image generator not getting every label in for each iteration.
EDIT
How the data is generated:
There is a external list with the image and the label like this
['0002_451_03.jpg', '0']
img001.jpg, 0
img002.jpg, 0
...
img1500.jpg, 750
This is read in and loaded into a array. The label is the number after the image
change
batch_indices = indices[bid * batch_size: (bid + 1) * batch_size]
with
batch_indices = indices[bid * batch_size: min((bid + 1) * batch_size, number_of_images)]

Tensor () is not an element of this graph

I am new to tensorflow and i am trying to implement a GAN by following this example in jupyter notebook.
Example here
Instead of using the MNIST data-set as used in this example i am trying to use my own data-set. I am creating an input pipeline for reading in TFRecords files and producing random batches of images. For associating objects with a randomly selected batch of images i am using this function tf.train.shuffle_batch(). But as soon i start my training and run sess.run([image_batch]) to get a random batch of images i get this error.
"ValueError: Fetch argument cannot be interpreted as a Tensor. (Tensor Tensor("shuffle_batch:0", shape=(100, 4096), dtype=float32) is not an element of this graph.)"
Is this error because i have written my get_image() function separately?
Here is the complete code:
# imports
# Paths to DIRs
IMAGE_WIDTH = 64
IMAGE_HEIGHT = 64
def get_image(files, num_classes):
# Convert filenames to a queue for an input pipeline.
file_queue = tf.train.string_input_producer(files)
# Create object to read TFRecords.
reader = tf.TFRecordReader()
# Read the full set of features for a single example.
key, example = reader.read(file_queue)
# Parse the example to get a dict mapping feature keys to tensors.
# image/class/label: integer denoting the index in a classification layer.
# image/encoded: string containing JPEG encoded image
features = tf.parse_single_example(
example,
features={
'image/class/label': tf.FixedLenFeature([], tf.int64),
'image/encoded': tf.FixedLenFeature([], dtype=tf.string,
default_value='')
})
label = features['image/class/label']
image_encoded = features['image/encoded']
# Decode the JPEG.
image = tf.image.decode_jpeg(image_encoded, channels=1)
image = tf.image.convert_image_dtype(image, dtype=tf.float32)
image = tf.reshape(image, [IMAGE_WIDTH*IMAGE_HEIGHT])
# Represent the label as a one hot vector.
label = tf.stack(tf.one_hot(label, num_classes))
return image
labels = io.open(DEFAULT_LABEL_FILE, 'r', encoding='utf-8').read().splitlines()
num_classes = len(labels)
print('Processing data...')
tf_record_pattern = os.path.join(DEFAULT_TFRECORDS_DIR, '%s-*' % 'train')
train_data_files = tf.gfile.Glob(tf_record_pattern)
image = get_image(train_data_files, num_classes)
# Associate objects with a randomly selected batch of labels and images.
image_batch = tf.train.shuffle_batch(
[image], batch_size=100,
capacity=2000,
min_after_dequeue=1000)
def model_inputs(real_dim, z_dim):
inputs_real = tf.placeholder(tf.float32, (None, real_dim), name='input_real')
inputs_z = tf.placeholder(tf.float32, (None, z_dim), name='input_z')
return inputs_real, inputs_z
def generator(z, out_dim, n_units=128, reuse=False, alpha=0.01):
.
.
# return output
def discriminator(x, n_units=128, reuse=False, alpha=0.01):
.
.
# return output
# Size of input image to discriminator
input_size = 4096
# Size of latent vector to generator
z_size = 100
# Sizes of hidden layers in generator and discriminator
g_hidden_size = 128
d_hidden_size = 128
# Leak factor for leaky ReLU
alpha = 0.01
# Smoothing
smooth = 0.1
tf.reset_default_graph()
# Create our input placeholders
input_real, input_z = model_inputs(input_size, z_size)
# Build the model
g_model = generator(input_z, input_size, n_units=g_hidden_size, alpha=alpha)
# g_model is the generator output
d_model_real, d_logits_real = discriminator(input_real, n_units=d_hidden_size, alpha=alpha)
d_model_fake, d_logits_fake = discriminator(g_model, reuse=True, n_units=d_hidden_size, alpha=alpha)
# Calculate losses
# Optimizers
learning_rate = 0.002
# Get the trainable_variables, split into G and D parts
t_vars = tf.trainable_variables()
g_vars = [var for var in t_vars if var.name.startswith('generator')]
d_vars = [var for var in t_vars if var.name.startswith('discriminator')]
d_train_opt = tf.train.AdamOptimizer(learning_rate).minimize(d_loss, var_list=d_vars)
g_train_opt = tf.train.AdamOptimizer(learning_rate).minimize(g_loss, var_list=g_vars)
batch_size = 100
epochs = 100
samples = []
losses = []
# Only save generator variables
saver = tf.train.Saver(var_list=g_vars)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
# Initialize the queue threads.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for e in range(epochs):
for ii in range(391510//batch_size): # training_images//batchsize
# Get a random batch of images.
batch = sess.run([image_batch])
# Get images, reshape and rescale to pass to D
batch_images = batch[0].reshape((batch_size, 4096))
batch_images = batch_images*2 - 1
# Sample random noise for G
batch_z = np.random.uniform(-1, 1, size=(batch_size, z_size))
# Run optimizers
_ = sess.run(d_train_opt, feed_dict={input_real: batch_images, input_z: batch_z})
_ = sess.run(g_train_opt, feed_dict={input_z: batch_z})
# At the end of each epoch, get the losses and print them out
train_loss_d = sess.run(d_loss, {input_z: batch_z, input_real: batch_images})
train_loss_g = g_loss.eval({input_z: batch_z})
# calculate accuracy
# Save training generator samples
with open('train_samples.pkl', 'wb') as f:
pkl.dump(samples, f)
# Stop queue threads and close session.
coord.request_stop()
coord.join(threads)
sess.close()
In the code, after creating the image_batch tensor, you are resetting the graph by using "tf.reset_default_graph()".
So the graph gets reset and all the tensors created before the resetting of the graph are no more elements of the new graph, because of which you are getting this error.
Create all your required tensors after resetting the graph and check. It should work.

Tensorflow error when training: Caused by op 'shuffle_batch'

I am trying to read images and labels from a TFRecord file, and then train with these.
I know that my TFRecord file exists, and have checked that it does contain 1000 images and labels. My problem only seems to arise when I want to pipe as input to train.
I am new to python and tensor flow, and not sure how to fix the problem
I get the following error occuring at tf.train.shuffle_batch
...
Caused by op 'shuffle_batch', defined at:
File "C:/AI/projects/DataGen/train.py", line 40, in
images_batch, labels_batch = tf.train.shuffle_batch([image, label], batch_size=10, capacity=1000,min_after_dequeue=2)
...
Here is my code, cobbled together from various mnist examples
import tensorflow as tf
def read_and_decode_single_example(filename):
# first construct a queue containing a list of filenames.
# this lets a user split up there dataset in multiple files to keep
# size down
filename_queue = tf.train.string_input_producer([filename],
num_epochs=None)
# Unlike the TFRecordWriter, the TFRecordReader is symbolic
reader = tf.TFRecordReader()
# One can read a single serialized example from a filename
# serialized_example is a Tensor of type string.
_, serialized_example = reader.read(filename_queue)
# The serialized example is converted back to actual values.
# One needs to describe the format of the objects to be returned
feature = {'image': tf.FixedLenFeature([], tf.string),
'label': tf.FixedLenFeature([], tf.int64)}
features = tf.parse_single_example(serialized_example, features=feature)
# now return the converted data
label = tf.cast(features['label'], tf.float32)
image = tf.decode_raw(features['image'], tf.float32)
image = tf.reshape(image, [28, 28, 3])
return label, image
with tf.Session() as sess:
sess.run(tf.local_variables_initializer())
sess.run(tf.global_variables_initializer())
# get single examples
label, image = read_and_decode_single_example("train.tfrecords")
image = tf.cast(image, tf.float32) / 255.
# groups examples into batches randomly
images_batch, labels_batch = tf.train.shuffle_batch([image, label], batch_size=10, capacity=1000, min_after_dequeue=2)
# The model is:
#
# Y = softmax( X * W + b)
# X: matrix for rgb images of 28x28 pixels, flattened (there are 100 images in a mini-batch)
# W: weight matrix with (28x28x3) lines and 10 columns
# b: bias vector with 10 dimensions
# +: add with broadcasting: adds the vector to each line of the matrix (numpy)
# softmax(matrix) applies softmax on each line
# softmax(line) applies an exp to each value then divides by the norm of the resulting line
# Y: output matrix with 100 lines and 10 columns
# input X: 28x28x3 RGB images
X = images_batch
# correct answers will go here
Y_ = labels_batch
# weights W[28 * 28 * 3, 10]
W = tf.Variable(tf.zeros([28 * 28 * 3, 10]))
# biases b[10]
b = tf.Variable(tf.zeros([10]))
# flatten the images into a single line of pixels
# -1 in the shape definition means "the only possible dimension that will preserve the number of elements"
XX = tf.reshape(X, [-1, 28 * 28 * 3])
# The model
Y = tf.nn.softmax(tf.matmul(XX, W) + b)
# loss function: cross-entropy = - sum( Y_i * log(Yi) )
# Y: the computed output vector
# Y_: the desired output vector
# cross-entropy
# log takes the log of each element, * multiplies the tensors element by element
# reduce_mean will add all the components in the tensor
# so here we end up with the total cross-entropy for all images in the batch
cross_entropy = -tf.reduce_mean(Y_ * tf.log(Y)) * 100.0 # normalized for batches of 100 images,
# *10 because "mean" included an unwanted division by 10
# accuracy of the trained model, between 0 (worst) and 1 (best)
correct_prediction = tf.equal(tf.argmax(Y, 1), tf.argmax(Y_, 1))
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
# training, learning rate = 0.005
train_step = tf.train.GradientDescentOptimizer(0.005).minimize(cross_entropy)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(100 + 1):
print(i)
sess.run(train_step)
coord.request_stop()
# Wait for threads to stop
coord.join(threads)
sess.close()
I moved the initialization to just before the tf.train.start_queue_runners call and that solved the problem i.e. after the model is setup
sess.run(tf.local_variables_initializer())
sess.run(tf.global_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)

Tensorflow: How can I run my testing set on a trained Neural Net

I have created a Neural Net that takes as input an RGB corrupted image and produces a clean version of it. After I finish training my NN I want to test it on a big set of 50 images. Each input (image) consists of a batch sized 64*32*32*3( I crop my image in 64 patches and then feed it to the NN). I train my NN with the following code:
# placeholders, variables etc here
train_step = tf.train.AdamOptimizer().minimize(loss)
#loading data to queue
training_queue = tf.train.string_input_producer(clean_set, shuffle=False)
cor_queue = tf.train.string_input_producer(corrupted_set, shuffle=False)
reader = tf.WholeFileReader()
key, value = reader.read(training_queue)
cor_key, cor_value = reader.read(cor_queue)
data = tf.image.decode_jpeg(value, channels = 3)
cor_data = tf.image.decode_jpeg(cor_value, channels = 3)
sess = tf.InteractiveSession()
sess.run(tf.global_variables_initializer())
sess.run(tf.local_variables_initializer())
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range (64):
my_data = sess.run([key,data,cor_key,cor_data])
im_list.append(my_data[1].reshape(1,-1))
key_list.append(my_data[0])
cor_im_list.append(my_data[3].reshape(1,-1))
cor_key_list.append(my_data[2])
for j in range(my_times):
_, y = sess.run([train_step,h_y],feed_dict={x: cor_im_list, y_: im_list})
print 'finished training NN'
coord.request_stop()
coord.join(threads)
This works fine!
Now I want to test my data set:
ressu = []
test_im_list = []
test_key_list = []
# I have 50 images in 50 folders (each folder contains the 64 patches of the image)
for i in range(50):
path = 'randomize_text/permutated_data/perm_test_' + str(i) + '/*.jpg'
testing_set = glob.glob(path)
testing_queue = tf.train.string_input_producer(testing_set, shuffle=False)
reader = tf.WholeFileReader()
test_key, test_value = reader.read(testing_queue)
test_data = tf.image.decode_jpeg(test_value, channels = 3)
for j in range (64):
print j
my_data = sess.run([test_key,test_data])
test_im_list.append(my_data[1].reshape(1,-1))
test_key_list.append(my_data[0])
psi = sess.run(y,feed_dict={x: test_im_list})
ressu.append(psi)
If put this code right after finishing training the NN the program becomes unresponsive and my guess is that I dont use the coord and threads so I cant handle the big set (even if place it right before I close threads). If I load it the way I loaded my training set I can only do it for one image which is not enough, I need to load them all.
How can I test my trained NN with my testing set?
Thanks

Categories

Resources