TensorFlow: training on my own image
Solution 1
If you are interested in how to input your own data in TensorFlow, you can look at this tutorial.
I've also written a guide with best practices for CS230 at Stanford here.
New answer (with tf.data
) and with labels
With the introduction of tf.data
in r1.4
, we can create a batch of images without placeholders and without queues. The steps are the following:
- Create a list containing the filenames of the images and a corresponding list of labels
- Create a
tf.data.Dataset
reading these filenames and labels - Preprocess the data
- Create an iterator from the
tf.data.Dataset
which will yield the next batch
The code is:
# step 1
filenames = tf.constant(['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg'])
labels = tf.constant([0, 1, 0, 1])
# step 2: create a dataset returning slices of `filenames`
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
# step 3: parse every image in the dataset using `map`
def _parse_function(filename, label):
image_string = tf.read_file(filename)
image_decoded = tf.image.decode_jpeg(image_string, channels=3)
image = tf.cast(image_decoded, tf.float32)
return image, label
dataset = dataset.map(_parse_function)
dataset = dataset.batch(2)
# step 4: create iterator and final input tensor
iterator = dataset.make_one_shot_iterator()
images, labels = iterator.get_next()
Now we can run directly sess.run([images, labels])
without feeding any data through placeholders.
Old answer (with TensorFlow queues)
To sum it up you have multiple steps:
- Create a list of filenames (ex: the paths to your images)
- Create a TensorFlow filename queue
- Read and decode each image, resize them to a fixed size (necessary for batching)
- Output a batch of these images
The simplest code would be:
# step 1
filenames = ['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg']
# step 2
filename_queue = tf.train.string_input_producer(filenames)
# step 3: read, decode and resize images
reader = tf.WholeFileReader()
filename, content = reader.read(filename_queue)
image = tf.image.decode_jpeg(content, channels=3)
image = tf.cast(image, tf.float32)
resized_image = tf.image.resize_images(image, [224, 224])
# step 4: Batching
image_batch = tf.train.batch([resized_image], batch_size=8)
Solution 2
Based on @olivier-moindrot's answer, but for Tensorflow 2.0+:
# step 1
filenames = tf.constant(['im_01.jpg', 'im_02.jpg', 'im_03.jpg', 'im_04.jpg'])
labels = tf.constant([0, 1, 0, 1])
# step 2: create a dataset returning slices of `filenames`
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
def im_file_to_tensor(file, label):
def _im_file_to_tensor(file, label):
path = f"../foo/bar/{file.numpy().decode()}"
im = tf.image.decode_jpeg(tf.io.read_file(path), channels=3)
im = tf.cast(image_decoded, tf.float32) / 255.0
return im, label
return tf.py_function(_im_file_to_tensor,
inp=(file, label),
Tout=(tf.float32, tf.uint8))
dataset = dataset.map(im_file_to_tensor)
If you are hitting an issue similar to:
ValueError: Cannot take the length of Shape with unknown rank
when passing tf.data.Dataset tensors to model.fit, then take a look at https://github.com/tensorflow/tensorflow/issues/24520. A fix for the code snippet above would be:
def im_file_to_tensor(file, label):
def _im_file_to_tensor(file, label):
path = f"../foo/bar/{file.numpy().decode()}"
im = tf.image.decode_jpeg(tf.io.read_file(path), channels=3)
im = tf.cast(image_decoded, tf.float32) / 255.0
return im, label
file, label = tf.py_function(_im_file_to_tensor,
inp=(file, label),
Tout=(tf.float32, tf.uint8))
file.set_shape([192, 192, 3])
label.set_shape([])
return (file, label)
Related videos on Youtube
Comments
-
VICTOR over 2 years
I am new to TensorFlow. I am looking for the help on the image recognition where I can train my own image dataset.
Is there any example for training the new dataset?
-
VICTOR almost 8 yearsI have read this googleresearch.blogspot.hk/2016/03/… However, i have no idea that where should I change the code.
-
sansknwoledge over 5 yearsnew link location ai.googleblog.com/2016/03/…
-
-
VICTOR almost 8 yearsFor shuffle_batch(), it requires at least 4 arguments. After I adding two more arguments: num_threads=1, capacity=5000. It says: TypeError: 'Tensor' object is not iterable.
-
Olivier Moindrot almost 8 yearsYou are right, the first argument of
tf.train.batch
ortf.train.shuffle_batch
should be a list[image]
instead of justimage
. I fixed it in the code. -
VICTOR almost 8 years@Olivier Moindrot Sorry, I still have some error. It says: ValueError: All shapes must be fully defined: [TensorShape([Dimension(None), Dimension(None), Dimension(3)])]. These error happens in the batching step.
-
Olivier Moindrot almost 8 yearsOnce again you are right, I fixed it in the code. You have to resize all the images to the same shape to make a batch of them.
-
VICTOR almost 8 years@Olivier Moindrot Thank you very much. It works now. I want to ask, after training the model, how can I classify the input image with my owned database?
-
Olivier Moindrot almost 8 yearsIf you have the labels of the training images, you should also get them as input and batch them with the images:
image_batch, label_batch = tf.train.batch([resized_image, label], batch_size=8)
. Then you have to build a model with images as input and labels as output, refer to this tutorial for more info. -
VICTOR almost 8 years@Olivier Moindrot What if I am doing one class classification. I only got the data for one class. I wanna classify between "Target" and "Outlier". Then how can I make up an array for label?
-
Olivier Moindrot almost 8 yearsLet us continue this discussion in chat.
-
iamas over 7 years
resized_image = tf.image.resize_images(images, 224, 224)
Here, the first argument of resize_images method should be image instead of images, right? -
Jack over 7 yearsresized_image = tf.image.resize_images(images, [224, 224])
-
Saravanabalagi Ramachandran about 7 yearswhere will the image labels go into?
-
Sakhri Houssem over 6 yearsthank's Mr @olivier-moindrot but if I have a batch of picture format
.tif
-
Sakhri Houssem over 6 yearsThanks, Mr @olivier-moindrot I used
tf.image.decode_gif
and this my DataSetGen code but I don't know If this the right way -
Bastian about 6 yearsHow to handle the labels in such case?
-
Dee about 5 years@OlivierMoindrot i got error out of range at get_next when the files are only 2, and 2 matching label [0,1] instead of 4 files and labels [0,1,0,1]
-
Olivier Moindrot about 5 years@datdinhquoc: if you have only two files and labels, with a batch size of 2, you can only do one iteration and then you will receive an
OutOfRange
error. -
D T almost 5 yearsAfter train my data ,how can use to detect a image ?
-
Aadnan Farooq A over 4 yearsHow about if there is more than three 3 channel image and format of file .mat.. the code will be same?
-
Olivier Moindrot over 4 years@AadnanFarooqA: in this case you need to change the
_parse_function
to read the .mat file -
Aadnan Farooq A over 4 yearsfrom step 1, I have 100's images and stored in a folder like Root directory -> Class1 -> images; Class 2 -> images; Class 3 -> images; how I will read all the images with the label as folder name?
-
Olivier Moindrot over 4 yearsYou can just get all the filenames and labels in python, then use my code to put it in tensorflow
-
Mehdi Zare almost 4 yearsfor Tensorflow 2, replace
tf.read_file(filename)
withtf.io.read_file(filename)
-
Roi Mulia over 3 yearsHey @OlivierMoindrot , thank you for this answer. I'm encountering an issue understanding the expected input for TFLite model. Can you please take a look? stackoverflow.com/questions/63486440/…
-
Samantha Garcia about 3 yearshow do you resize the images in the new version?
-
Olivier Moindrot about 3 years@SamanthaCruz: you can add it in the
_parse_function