Loading images in tensorflow queue provides random image instead of FIFO - python

I am trying to load an image with tensorflow, but I need the files to be in order. When I load the image it loads a random image but not in the order I provided through my initial array. However, my understanding is that string_input_producer(file_names) is FIFO. Why are my images random and how do I make it load images in order?
with open("name.json", 'r') as f:
data = json.load(f)
file_names = []
for i, row in enumerate(data):
load_location = row['location']
file_names.append(load_location)
filename_queue = tf.train.string_input_producer(file_names) # list of files to read
count_num_files = tf.size(file_names)
reader=tf.WholeFileReader()
key,value=reader.read(filename_queue)
img = tf.image.decode_png(value)
init = tf.global_variables_initializer()
with tf.Session() as sess:
sess.run(init)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
num_files = sess.run(count_num_files)
for i in range(num_files):
# this does not match
location = file_names[i]
# with this image
image_eval=img.eval()
coord.request_stop()
coord.join(threads)

Stupid mistake, string_input_producer shuffle setting defaults to True:
filename_queue = tf.train.string_input_producer(file_names, shuffle=False)

Related

Different results reading tf.record of an image and the image directly

I want to read an image to make predictions of my model, first probe doing a tf.record of the image that I wanted to predict with my model this is the code that decodes tf.record
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
data_path = '/Users/David/SA_TfRecord' # address to save the hdf5 file
with tf.Session() as sess:
feature = {'pred/image': tf.FixedLenFeature([], tf.string),
'pred/label': tf.FixedLenFeature([], tf.int64)}
# Create a list of filenames and pass it to a queue
filename_queue = tf.train.string_input_producer([data_path], num_epochs=1)
# Define a reader and read the next record
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)
# Decode the record read by the reader
features = tf.parse_single_example(serialized_example, features=feature)
# Convert the image data from string back to the numbers
image = tf.decode_raw(features['pred/image'], tf.float32)
# Cast label data into int32
label = tf.cast(features['pred/label'], tf.int32)
# Reshape image data into the original shape
image = tf.reshape(image, [224, 224, 3])
# Creates batches by randomly shuffling tensors
images, labels = tf.train.shuffle_batch([image, label], batch_size=1,
capacity=30, num_threads=1, min_after_dequeue=1)
print(images)
# Initialize all global and local variables
init_op = tf.group(tf.global_variables_initializer(),
tf.local_variables_initializer())
sess.run(init_op)
# Create a coordinator and run all QueueRunner objects
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for batch_index in range(1):
img, lbl = sess.run([images, labels])
print(img)
# Stop the threads
coord.request_stop()
# Wait for threads to stop
coord.join(threads)
sess.close()
I get this as a result of the decoding
[[[[ 53. 49. 66.]
[ 53. 49. 66.]
[ 53. 49. 66.]
...
[ 68. 154. 171.]
[ 68. 151. 167.]
[ 69. 150. 167.]].......
with this code I make my tf.record
from random import shuffle
import glob
import cv2
import tensorflow as tf
import numpy as np
import sys
shuffle_data = True # shuffle the addresses before saving
data_path = '/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Sexta_Version_Combinacion/Direct/SA.jpg'
# read addresses and labels from the 'train' folder
addrs = glob.glob(data_path)
labels = [0 if 'CA' in addr else 1 for addr in addrs] # 0 = Con Arms, 1 = Sin Arma
# to shuffle data
if shuffle_data:
c = list(zip(addrs, labels))
shuffle(c)
addrs, labels = zip(*c)
# Divide the hata into 60% train, 20% validation, and 20% test
#train_addrs = addrs[0:int(0.8 * len(addrs))]
#train_labels = labels[0:int(0.8 * len(labels))]
#val_addrs = addrs[int(0.8 * len(addrs)):int(1 * len(addrs))]
#val_labels = labels[int(0.8 * len(addrs)):int(1 * len(addrs))]
pred_addrs = addrs[0:int(1 * len(addrs))]
pred_labels = labels[0:int(1 * len(labels))]
def load_image(addr):
# read an image and resize to (224, 224)
# cv2 load images as BGR, convert it to RGB
img = cv2.imread(addr)
img = cv2.resize(img, (224, 224), interpolation=cv2.INTER_CUBIC)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img.astype(np.float32)
return img
def _int64_feature(value):
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
def _bytes_feature(value):
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
pred_filename ='/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Sexta_Version_Combinacion/Direct/SA_TfRecord' # address to save the TFRecords file
# open the TFRecords file
writer = tf.python_io.TFRecordWriter(pred_filename)
for i in range(len(pred_addrs)):
# print how many images are saved every 1000 images
if not i % 1:
print 'pred data: {}/{}'.format(i, len(pred_addrs))
sys.stdout.flush()
# Load the image
img = load_image(pred_addrs[i])
label = pred_labels[i]
# Create a feature
feature = {'pred/label': _int64_feature(label),
'pred/image': _bytes_feature(tf.compat.as_bytes(img.tostring()))}
# Create an example protocol buffer
example = tf.train.Example(features=tf.train.Features(feature=feature))
# Serialize to string and write on the file
writer.write(example.SerializeToString())
writer.close()
sys.stdout.flush()
Then I want to put my image directly, so as not to make a tfrecord, but when I read it I get a different result. this is my code to read directly
import tensorflow as tf
with tf.Session() as sess:
# Make a queue of file names including all the JPEG images files in the relative
# image directory.
filename_queue = tf.train.string_input_producer(
tf.train.match_filenames_once("/Users/David/Desktop/David/Tesis/Practica/Programas/Versiones/Sexta_Version_Combinacion/Direct/SA.jpg"))
# Read an entire image file which is required since they're JPEGs, if the images
# are too large they could be split in advance to smaller files or use the Fixed
# reader to split up the file.
image_reader = tf.WholeFileReader()
# Read a whole file from the queue, the first returned value in the tuple is the
# filename which we are ignoring.
_, image_file = image_reader.read(filename_queue)
# Decode the image as a JPEG file, this will turn it into a Tensor which we can
# then use in training.
image = tf.image.decode_jpeg(image_file)
image = tf.image.resize_images(image, [224, 224])
image.set_shape((224, 224, 3))
print(image)
batch_size = 1
num_preprocess_threads = 1
min_queue_examples = 1
images = tf.train.shuffle_batch([image],batch_size=batch_size,num_threads=num_preprocess_threads,capacity=min_queue_examples+3*batch_size,min_after_dequeue=min_queue_examples)
print(images)
# Start a new session to show example output.
# Required to get the filename matching to run.
tf.local_variables_initializer().run()
# Coordinate the loading of image files.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
# Get an image tensor and print its value.
image_tensor = sess.run(images)
print(image_tensor)
# Finish off the filename queue coordinator.
coord.request_stop()
coord.join(threads)
I get this as a result
[[[[ 51. 49. 63.]
[ 52. 50. 64.]
[ 51. 49. 63.]
...
[ 66. 153. 170.]
[ 67. 150. 166.]
[ 68. 151. 167.]]........
I do not know what the error is, please help me,why I get different results??
I think this is because jpeg is a loss compression, it differs every time you save the image.
If you want the decode result be the same every time you read it, you can use other format, such as png, bmp, etc.

Tensorflow's decode_csv only reading one line

How do I get the decode_csv function to read every line in my CSV?
I'm currently trying to load data from my CSV file onto my GPU. Data loads fine onto the GPU, except... only one line of my 640-line CSV file is actually read. Where do you think I'm going wrong?
import tensorflow as tf
with tf.device('/gpu:0'):
filename_queue = tf.train.string_input_producer(['dataset.csv'])
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
record_defaults = [['']]*121
all_columns = tf.decode_csv(value, record_defaults=record_defaults)
with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess:
# Start populating the filename queue.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
# Iterate through all the columns
vals = []
for x in range(121):
tmp = all_columns.pop()
myval = tmp.eval(session=sess)
vals.append(myval)
coord.request_stop()
coord.join(threads)
Then if I do...
>>> import numpy as np
>>> vals = np.asarray(vals)
>>> vals.shape
(121,)
I do have 121 columns per each of the 640 rows in my CSV. The values in vals look fine to me, except I'm not actually getting all 640 lines read. I'm guessing it has to do with:
all_columns = tf.decode_csv(value, record_defaults=record_defaults)
Nvm. Figured it out.
Apparently there is a difference between sess.run() and pop() in terms of how we extract row data.
I happen to have 640 lines in my CSV file and 121 columns, hence the:
record_defaults = [['']]*121
and
for x in range(640):
Note that this is mostly hardcoded just for testing purposes. Solution below:
import tensorflow as tf
with tf.device('/gpu:0'):
filename_queue = tf.train.string_input_producer(['../Datasets/CMU_face_images_dataset.csv'])
reader = tf.TextLineReader()
key, value = reader.read(filename_queue)
record_defaults = [['']]*121
all_columns = tf.decode_csv(value, record_defaults=record_defaults)
# TWO NEW LINES
name = all_columns[0]
data = all_columns[1:]
with tf.Session(config=tf.ConfigProto(allow_soft_placement=True)) as sess:
# Start populating the filename queue.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
vals = []
names = []
for x in range(640):
# THIS IS THE NEW LINE
_name, _val = sess.run([name, data])
# OLD LINES
# tmp = all_columns.pop()
# myval = tmp.eval(session=sess)
# vals.append(myval)
names.append(_name)
vals.append(_val)
coord.request_stop()
coord.join(threads)

tf.WholeFileReader() not reading

My code seems to find the jpeg image perfectly, because if I mess up the path it will not proceed, also I printed out the return from match_filenames_once and there was the correct list of image files. However the following code does not seem to load the images into the queue. What is wrong with the filename_queue?
Here is my code:
filename_queue = tf.train.string_input_producer(
tf.train.match_filenames_once("./resized2/*.jpg"),shuffle=False)
image_reader = tf.WholeFileReader()
myfilename, image_file = image_reader.read(filename_queue)
image = tf.image.decode_jpeg(image_file)
# Start a new session to show example output.
with tf.Session() as sess:
init_op = tf.global_variables_initializer(), tf.local_variables_initializer()
sess.run(init_op)
# Start populating the filename queue.
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(1): #length of your filename list
image_tensor = image.eval() #here is your image Tensor :)
print(myfilename)
print(image.shape)
#Image.fromarray(np.asarray(image_tensor)).show()
coord.request_stop()
coord.join(threads)
Here is the output:
Tensor("ReaderReadV2:0", shape=(), dtype=string)
(?, ?, ?)
Try to print shape of image_tensor
print(image_tensor.shape)
image in your code is Tensor, and it has unknown size, because it come to graph from arbitrary jpeg image, and TF can't define it's size, when TF create graph. But image_tensor is np.array with image loaded from disk.

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

How to feed Cifar10 trained model with my own image and get label as output?

I am trying to use the trained model based on the Cifar10 tutorial and would like to feed
it with an external image 32x32 (jpg or png).
My goal is to be able to get the label as an output.
In other words, I want to feed the Network with a single jpeg image of size 32 x 32, 3 channels with no label as an input and have the inference process give me the tf.argmax(logits, 1).
Basically I would like to be able to use the trained cifar10 model on an external image and see what class it will spit out.
I have been trying to do that based on the Cifar10 Tutorial and unfortunately always have issues. especially with the Session concept and the batch concept.
Any help doing that with Cifar10 would be greatly appreciated.
Here is the implemented code so far with compilation issues :
#!/usr/bin/env python
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from datetime import datetime
import math
import time
import tensorflow.python.platform
from tensorflow.python.platform import gfile
import numpy as np
import tensorflow as tf
import cifar10
import cifar10_input
import os
import faultnet_flags
from PIL import Image
FLAGS = tf.app.flags.FLAGS
def evaluate():
filename_queue = tf.train.string_input_producer(['/home/tensor/.../inputImage.jpg'])
reader = tf.WholeFileReader()
key, value = reader.read(filename_queue)
input_img = tf.image.decode_jpeg(value)
init_op = tf.initialize_all_variables()
# Problem in here with Graph / session
with tf.Session() as sess:
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
for i in range(1):
image = input_img.eval()
print(image.shape)
Image.fromarray(np.asarray(image)).show()
# Problem in here is that I have only one image as input and have no label and would like to have
# it compatible with the Cifar10 network
reshaped_image = tf.cast(image, tf.float32)
height = FLAGS.resized_image_size
width = FLAGS.resized_image_size
resized_image = tf.image.resize_image_with_crop_or_pad(reshaped_image, width, height)
float_image = tf.image.per_image_whitening(resized_image) # reshaped_image
num_preprocess_threads = 1
images = tf.train.batch(
[float_image],
batch_size=128,
num_threads=num_preprocess_threads,
capacity=128)
coord.request_stop()
coord.join(threads)
logits = faultnet.inference(images)
# Calculate predictions.
#top_k_predict_op = tf.argmax(logits, 1)
# print('Current image is: ')
# print(top_k_predict_op[0])
# this does not work since there is a problem with the session
# and the Graph conflicting
my_classification = sess.run(tf.argmax(logits, 1))
print ('Predicted ', my_classification[0], " for your input image.")
def main(argv=None):
evaluate()
if __name__ == '__main__':
tf.app.run() '''
Some basics first:
First you define your graph: image queue, image preprocessing, inference of the convnet, top-k accuracy
Then you create a tf.Session() and work inside it: starting the queue runners, and calls to sess.run()
Here is what your code should look like
# 1. GRAPH CREATION
filename_queue = tf.train.string_input_producer(['/home/tensor/.../inputImage.jpg'])
... # NO CREATION of a tf.Session here
float_image = ...
images = tf.expand_dims(float_image, 0) # create a fake batch of images (batch_size=1)
logits = faultnet.inference(images)
_, top_k_pred = tf.nn.top_k(logits, k=5)
# 2. TENSORFLOW SESSION
with tf.Session() as sess:
sess.run(init_op)
coord = tf.train.Coordinator()
threads = tf.train.start_queue_runners(coord=coord)
top_indices = sess.run([top_k_pred])
print ("Predicted ", top_indices[0], " for your input image.")
EDIT:
As #mrry suggests, if you only need to work on a single image, you can remove the queue runners:
# 1. GRAPH CREATION
input_img = tf.image.decode_jpeg(tf.read_file("/home/.../your_image.jpg"), channels=3)
reshaped_image = tf.image.resize_image_with_crop_or_pad(tf.cast(input_img, width, height), tf.float32)
float_image = tf.image.per_image_withening(reshaped_image)
images = tf.expand_dims(float_image, 0) # create a fake batch of images (batch_size = 1)
logits = faultnet.inference(images)
_, top_k_pred = tf.nn.top_k(logits, k=5)
# 2. TENSORFLOW SESSION
with tf.Session() as sess:
sess.run(init_op)
top_indices = sess.run([top_k_pred])
print ("Predicted ", top_indices[0], " for your input image.")
The original source code in cifar10_eval.py can also be used for testing own individual images as it is shown in the following console output
nbatfai#robopsy:~/Robopsychology/repos/gpu/tensorflow/tensorflow/models/image/cifar10$ python cifar10_eval.py --run_once True 2>/dev/null
[ -0.63916457 -3.31066918 2.32452989 1.51062226 15.55279636
-0.91585422 1.26451302 -4.11891603 -7.62230825 -4.29096413]
deer
nbatfai#robopsy:~/Robopsychology/repos/gpu/tensorflow/tensorflow/models/image/cifar10$ python cifar2bin.py matchbox.png input.bin
nbatfai#robopsy:~/Robopsychology/repos/gpu/tensorflow/tensorflow/models/image/cifar10$ python cifar10_eval.py --run_once True 2>/dev/null
[ -1.30562115 12.61497402 -1.34208572 -1.3238833 -6.13368177
-1.17441642 -1.38651907 -4.3274951 2.05489922 2.54187846]
automobile
nbatfai#robopsy:~/Robopsychology/repos/gpu/tensorflow/tensorflow/models/image/cifar10$
and code snippet
#while step < num_iter and not coord.should_stop():
# predictions = sess.run([top_k_op])
print(sess.run(logits[0]))
classification = sess.run(tf.argmalogits[0], 0))
cifar10classes = ["airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"]
print(cifar10classes[classification])
#true_count += np.sum(predictions)
step += 1
# Compute precision # 1.
precision = true_count / total_sample_count
# print('%s: precision # 1 = %.3f' % (datetime.now(), precision))
More details can be found in the post How can I test own image to Cifar-10 tutorial on Tensorflow?

Categories

Resources