Read and preprocess image for tensorflow pretrained model - python

I don't have much experience in Tensorflow. I am trying to use a pretrained ResNet152 model to get the activations of the last layer as output. The images I use for input are stored on my harddrive. So I need to load the images, preprocess them and then get the output from the pretrained model. I found examples for that using URLs of images but when I try it with image paths I can't get it to work. This is what I have so far (only one image for now):
with tf.Graph().as_default():
filename_queue = tf.train.string_input_producer(['./testimg/A_008.jpg'])
reader = tf.WholeFileReader()
key, value = reader.read(filename_queue)
image = tf.image.decode_jpeg(value, channels=3)
preprocessing = preprocessing_factory.get_preprocessing('resnet_v2_152', is_training=False)
processed_image = preprocessing(image, 299,299)
processed_images = tf.expand_dims(processed_image, 0)
with slim.arg_scope(resnet_v2.resnet_arg_scope()):
logits, end_points = resnet_v2.resnet_v2_152(processed_images, is_training=False)
checkpoints_dir='./models/resnet_v2_152'
init_fn = slim.assign_from_checkpoint_fn(
os.path.join(checkpoints_dir, 'resnet_v2_152.ckpt'),
slim.get_variables_to_restore())
with tf.Session() as sess:
init_fn(sess)
np_image, fv = sess.run([image, logits])
I am doing this in a Jupyter Notebook. When I execute the code I don't get an error message, it just keeps running and running until I restart the kernel.
Any ideas what I did wrong? And how would I do it for multiple images?

I found the solution by replacing the tf.WholeFileReader() with tf.read_file():
graph = tf.Graph()
with graph.as_default():
image_path = image = tf.placeholder(tf.string)
image = tf.image.decode_jpeg(tf.read_file(image_path), channels=3)
preprocessing = preprocessing_factory.get_preprocessing('resnet_v2_152', is_training=False)
processed_image = preprocessing(image, image_size, image_size)
processed_images = tf.expand_dims(processed_image, 0)
with slim.arg_scope(resnet_v2.resnet_arg_scope()):
logits, end_points = resnet_v2.resnet_v2_152(processed_images, is_training=False)
checkpoints_dir='./models/resnet_v2_152'
init_fn = slim.assign_from_checkpoint_fn(
os.path.join(checkpoints_dir, 'resnet_v2_152.ckpt'),
slim.get_variables_to_restore())
images = ['./testimg/A_008.jpg', './testimg/logo.jpg']
with tf.Session(graph=graph) as sess:
init_fn(sess)
for img in images:
fv = sess.run(logits, feed_dict={image_path: img})
print(fv)

Related

Loading TF Records into Keras

I am trying to load a custom TFRecord file into my keras model. I attempted to follow this tutorial: https://medium.com/#moritzkrger/speeding-up-keras-with-tfrecord-datasets-5464f9836c36, but adapting for my use.
My goal is to have the functions work similar to ImageDataGenerator from Keras. I cannot use that function because I specific metadata from the images that the generator does not grab. I'm not including that metadata here because I just need the basic network to function first.
I also want to be able to apply this to a transfer learning application.
I keep getting this error: TypeError: Could not build a TypeSpec for None with type NoneType
I am using Tensorflow 2.2
def _parse_function(serialized):
features = \
{
'image': tf.io.FixedLenFeature([], tf.string),
'label': tf.io.FixedLenFeature([], tf.int64),
'shapex': tf.io.FixedLenFeature([], tf.int64),
'shapey': tf.io.FixedLenFeature([], tf.int64),
}
parsed_example = tf.io.parse_single_example(serialized=serialized,
features=features)
shapex = tf.cast(parsed_example['shapex'], tf.int32)
shapey = tf.cast(parsed_example['shapey'], tf.int32)
image_shape = tf.stack([shapex, shapey, 3])
image_raw = parsed_example['image']
# Decode the raw bytes so it becomes a tensor with type.
image = tf.io.decode_raw(image_raw, tf.uint8)
image = tf.reshape(image, image_shape)
# Get labels
label = tf.cast(parsed_example['label'], tf.float32)
return image, label
def imgs_inputs(type, perform_shuffle=False):
records_dir = '/path/to/tfrecord/'
record_paths = [os.path.join(records_dir,record_name) for record_name in os.listdir(records_dir)]
full_dataset = tf.data.TFRecordDataset(filenames=record_paths)
full_dataset = full_dataset.map(_parse_function, num_parallel_calls=16)
dataset_length = (len(list(full_dataset))) #Gets length of datase
iterator = tf.compat.v1.data.make_one_shot_iterator(databatch)
image, label = iterator.get_next()
#labels saved as values ex: [1,2,3], and are now converted to one hot encoded
label = to_categorical(label)
return image, label
image, label = imgs_inputs(type ='Train',perform_shuffle=True)
#Combine it with keras
# base_model = MobileNet(weights='imagenet', include_top=False, input_shape=(200,200,3), dropout=.3)
model_input = Input(shape=[200,200,3])
#Build your network
model_output = Flatten(input_shape=(200, 200, 3))(model_input)
model_output = Dense(19, activation='relu')(model_output)
#Create your model
train_model = Model(inputs=model_input, outputs=model_output)
#Compile your model
optimizer = Adam(learning_rate=.001)
train_model.compile(optimizer=optimizer,loss='mean_squared_error',metrics=['accuracy'],target_tensors=[label])
#Train the model
train_model.fit(epochs=10,steps_per_epoch=2)
image returns array of shape (100,200,200,3) which is a batch of 100 images
label returns array of shape(100,19) which is a batch of 100 labels (there are 19 labels)
The issue related to shapex and shapey but I don't know exactly why.
I set shapex = 200 and shapey=200. Then I rewrote the model to include the transfer learning.
base_model = MobileNet(weights='imagenet', include_top=False, input_shape=(200,200,3), dropout=.3)
x = base_model.output
types = Dense(19,activation='softmax')(x)
model = Model(inputs=base_model.input,outputs=types)
model.compile(
optimizer='adam',
loss = 'sparse_categorical_crossentropy',
metrics=['accuracy']
history = model.fit(get_batches(), steps_per_epoch=1000, epochs=10)
I found everything I needed on this Google Colab:
[https://colab.research.google.com/github/GoogleCloudPlatform/training-data-analyst/blob/master/courses/fast-and-lean-data-science/04_Keras_Flowers_transfer_learning_solution.ipynb#scrollTo=XLJNVGwHUDy1][1]
[1]: https://colab.research.google.com/github/GoogleCloudPlatform/training-data-analyst/blob/master/courses/fast-and-lean-data-science/04_Keras_Flowers_transfer_learning_solution.ipynb#scrollTo=XLJNVGwHUDy1

How to convert MapDataset variable into np.array?

Environment
Ubuntu 18.04
Python 3.6.8
Tensorflow 1.12.0
The problem
I want to convert the data with MapDataset class into numpy.array to check the contents.
Data detail
I have data as TFRecord. This data contains images (150x150x3) and labels (1 or 0). This TFRecord was created from the following code.
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]))
np.random.seed(42)
rnd_index = np.random.permutation(len(image_paths))
X_train, y_train = image_paths[rnd_index[:-1000]], labels[rnd_index[:-1000]]
X_test, y_test = image_paths[rnd_index[-1000:]], labels[rnd_index[-1000:]]
writer = tf.python_io.TFRecordWriter('training.tfrecord')
for image_path, label in zip(X_train, y_train):
image = cv2.imread(image_path)
image = cv2.resize(image, (150, 150)) / 255.0
img_raw = image.tostring()
ex = tf.train.Example(features=tf.train.Features(feature={
'image': bytes_feature(img_raw),
'label': int64_feature(label)
}))
writer.write(ex.SerializeToString())
writer.close()
Parsing data
I parsed the data by following code.
def parse(example_proto):
features = {
'label' : tf.FixedLenFeature((), tf.int64),
'image' : tf.FixedLenFeature((), tf.string)
}
parsed_features = tf.parse_single_example(example_proto, features)
img_shape = tf.stack([150, 150, 3])
image = tf.decode_raw(parsed_features['image'], tf.float32)
image = tf.reshape(image, img_shape)
label = tf.cast(parsed_features['label'], tf.int32)
return image, label
with tf.Session() as sess:
dataset = tf.data.TFRecordDataset('training.tfrecord')
dataset = dataset.map(parse)
I want to get the image from 'dataset' variable, but I don't know how to do.
I tried running the following code on the jupyter notebook.
with tf.Session() as sess:
dataset = tf.data.TFRecordDataset('training.tfrecord')
dataset = dataset.map(parse)
iterator = dataset.make_initializable_iterator()
sess.run(iterator.initializer)
next_element = iterator.get_next()
elem = next_element[0].eval()
dataset
But I got the error message.
InvalidArgumentError: Feature: image (data type: string) is required but could not be found.
[[{{node ParseSingleExample/ParseSingleExample}} = ParseSingleExample[Tdense=[DT_STRING, DT_INT64], dense_keys=["image", "label"], dense_shapes=[[], []], num_sparse=0, sparse_keys=[], sparse_types=[]](arg0, ParseSingleExample/Const, ParseSingleExample/Const_1)]]
[[node IteratorGetNext (defined at <ipython-input-3-350cc5050691>:19) = IteratorGetNext[output_shapes=[[150,150,3], []], output_types=[DT_FLOAT, DT_INT32], _device="/job:localhost/replica:0/task:0/device:CPU:0"](IteratorV2)]]
I'm a beginner of Tensorflow, so I cannot understand what this message means, and how to deal with it.

When I used tf.nn.read_file() to test an image in vgg, it was wrong.But when I used PIL to open it, it was correct. So strange

I have written a vgg model, and trained it.Now, i'm going to test a new image.When I use code1, it works well, but it is wrong in code2.
vgg() is the model i defined it. And the ckpt file has been saved in "D:\Demo\ckpt".
code1: It printed prediction as [[ 1.77901700e-01 8.22093844e-01 4.42284863e-06]]
def evaluate_one_image(path):
with tf.Graph().as_default():
image_plt = Image.open(path)
image = image_plt.resize([224, 224])
image_array = np.array(image)
image = np.reshape(image_array, (1,224,224,3))
x = tf.placeholder(tf.float32, shape=[1, 224, 224, 3])
logit = vgg(x)
logit = tf.nn.softmax(logit)
logs_train_dir = 'D:\\Demo\\ckpt'
saver = tf.train.Saver(tf.global_variables())
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(logs_train_dir)
saver.restore(sess, ckpt.model_checkpoint_path)
prediction = sess.run(logit, feed_dict={x: image})
print(prediction)
------------------------------------------------Dividing Line--------------------------------------
code2: I used some functions in tensorflow.It printed prediction as [[ 0.33333334 0.33333334 0.33333334]].
def test_one_image(path):
with tf.Graph().as_default():
image_plt = Image.open(path)
image_tensor = tf.image.decode_jpeg(tf.read_file(path), channels=3)
image_tensor = tf.image.resize_image_with_crop_or_pad(image_tensor, 224, 224)
# image_tensor = tf.image.per_image_standardization(image_tensor)
image_tensor = tf.reshape(image_tensor, [1, 224, 224, 3])
x = tf.placeholder(tf.float32, shape=[1, 224, 224, 3])
logit = vgg(x)
logit = tf.nn.softmax(logit)
logs_train_dir = 'D:\\Demo\\ckpt'
saver = tf.train.Saver(tf.global_variables())
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(logs_train_dir)
saver.restore(sess, ckpt.model_checkpoint_path)
prediction = sess.run(logit, feed_dict={x: image_tensor.eval()})
print(prediction)
I think the two codes have nearly same steps.But I don't know why it's wrong, and how to handle it.Help me,thank you very much!
First code resize image. Second code crop image. These are two different action, first action scales full image to new size, second action cuts of part of image to make it's size equal 224 x 224
Update:
Try this code:
def test_one_image(path):
with tf.Graph().as_default():
image_plt = Image.open(path)
image_tensor = tf.image.decode_jpeg(tf.read_file(path), channels=3)
image_tensor = tf.expand_dims(image_tensor, [0])
image_tensor = tf.image.resize_images(image_tensor, [224, 224])
logit = vgg(image_tensor)
logit = tf.nn.softmax(logit)
logs_train_dir = 'D:\\Demo\\ckpt'
saver = tf.train.Saver(tf.global_variables())
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(logs_train_dir)
saver.restore(sess, ckpt.model_checkpoint_path)
prediction = sess.run(logit)
print(prediction)
When I used this code, error occured. The result was [[ 0.33333334 0.33333334 0.33333334]] again.
def test_one_image(path):
with tf.Graph().as_default():
image_plt = Image.open(path)
image_tensor = tf.image.decode_jpeg(tf.read_file(path), channels=3)
image_tensor = tf.image.per_image_standardization(image_tensor)
image_tensor = tf.reshape(image_tensor, [1, 224, 224, 3])
x = tf.placeholder(tf.float32, shape=[1, 224, 224, 3])
logit = vgg(x)
logit = tf.nn.softmax(logit)
logs_train_dir = 'D:\\Demo\\ckpt'
saver = tf.train.Saver(tf.global_variables())
with tf.Session() as sess:
ckpt = tf.train.get_checkpoint_state(logs_train_dir)
saver.restore(sess, ckpt.model_checkpoint_path)
prediction = sess.run(logit, feed_dict={x: image_tensor.eval()})
print(prediction)

Tensorflow: Image Preprocessing Inception v4 not accepting my jpg

I'm new to tensorflow and I tried using the script mentioned in Tensorflow: use pretrained inception model to avoid using a TF Record but all my predictions end up in the same wrong class. The evaluation classifier however produces correct results, so it's not the model, I believe the pre processing is what I'm doing wrong.
So I decided to try the inception preprocessing function but now it won't accept my jpgs. I get this error:
inception_preprocessing.py", line 265, in preprocess_for_eval
image = tf.image.central_crop(image, central_fraction=central_fraction)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/image_ops_impl.py", line 335, in central_crop
_Check3DImage(image, require_static=False)
File "/usr/local/lib/python2.7/dist-packages/tensorflow/python/ops/image_ops_impl.py", line 129, in _Check3DImage
raise ValueError("'image' must be three-dimensional.")
ValueError: 'image' must be three-dimensional.
Here's my code:
arg_scope = inception_utils.inception_arg_scope()
im_size = 299
inputs = tf.placeholder(tf.float32, (None, im_size, im_size, 3))
inputs = inception_preprocessing.preprocess_image(inputs, im_size, im_size)
with slim.arg_scope(arg_scope):
logits, end_points = inception_v4.inception_v4(inputs)
saver = tf.train.Saver()
saver.restore(sess,ckpt_file)
for image in sample_img:
im = Image.open(image)
im = im.resize((im_size,im_size))
im = np.array(im)
logit_values = sess.run(logits, feed_dict={inputs:im})
print(np.argmax(logit_values))
inputs_processed = inception_preprocessing.preprocess_image(tf.squeeze(inputs), im_size, im_size)
inputs_processed = tf.expand_dims(inputs_processed, 0)
with slim.arg_scope(arg_scope):
logits, end_points = inception_v4.inception_v4(inputs_processed)
# placeholder feed value should be 4D
im = np.exapnd_dims(np.array(im), 0)

How to feed one image after another by feed_dict in Tensorflow

I'm tring to feed an image one after another by feed_dict .
I cloned this repository https://github.com/affinelayer/pix2pix-tensorflow , and in "pix2pix.py", images are fed from a folder by tf.WholeFileReader(). But I want to feed loaded images from memory. I made a list of images which is numpy.ndarray , and using feed_dict in a for loop. But after an image fed, program does't respond.
I changed "test" part of the original code, and here is my code.
tf.reset_default_graph()
init = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
holder = tf.placeholder(dtype=tf.float32, shape=[None, None, 3])
with tf.name_scope("load_images"):
paths=[]
paths.append(1)
assertion = tf.assert_equal(tf.shape(holder)[2], 3, message="image does not have 3 channels")
with tf.control_dependencies([assertion]):
raw_input = tf.identity(holder)
raw_input.set_shape([ None, None, 3])
width = tf.shape(raw_input)[2] # [height, width, channels]
#just copy for now
a_images = cls.preprocess(raw_input[:,:,:])
b_images = cls.preprocess(raw_input[:,:,:])
inputs, targets = [b_images, a_images]
After some processing, following is session part. "arg_img" is an argument which is a list of images, and converted_outputs is an array of converted image by pix2pix.
saver = tf.train.Saver(max_to_keep=1)
#logdir = cls.a.output_dir if (cls.a.trace_freq > 0 or cls.a.summary_freq > 0) else None
#sv = tf.train.Supervisor(logdir=logdir, save_summaries_secs=0, saver=None)
with tf.Session() as sess:
print("entered sess")
if cls.a.checkpoint is not None:
print("loading model from checkpoint")
checkpoint = tf.train.latest_checkpoint(cls.a.checkpoint)
saver.restore(sess, checkpoint)
print("checkpoint loaded")
for j, img in enumerate(arg_img):
im=np.asarray(img,dtype=np.float32)
print(type(arg_img))
ret_im=(sess.run(converted_outputs, feed_dict={holder:im}))
print("passed")
out_img_list.append(ret_im)
return out_img_list

Categories