TensorFlow: training on my own image

62,848

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:

  1. Create a list containing the filenames of the images and a corresponding list of labels
  2. Create a tf.data.Dataset reading these filenames and labels
  3. Preprocess the data
  4. 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:

  1. Create a list of filenames (ex: the paths to your images)
  2. Create a TensorFlow filename queue
  3. Read and decode each image, resize them to a fixed size (necessary for batching)
  4. 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)
Share:
62,848

Related videos on Youtube

VICTOR
Author by

VICTOR

BY NIGHT: I write code.

Updated on November 08, 2021

Comments

  • VICTOR
    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
    VICTOR almost 8 years
    For 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
    Olivier Moindrot almost 8 years
    You are right, the first argument of tf.train.batch or tf.train.shuffle_batch should be a list [image] instead of just image. I fixed it in the code.
  • VICTOR
    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
    Olivier Moindrot almost 8 years
    Once 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
    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
    Olivier Moindrot almost 8 years
    If 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
    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
    Olivier Moindrot almost 8 years
  • iamas
    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
    Jack over 7 years
    resized_image = tf.image.resize_images(images, [224, 224])
  • Saravanabalagi Ramachandran
    Saravanabalagi Ramachandran about 7 years
    where will the image labels go into?
  • Sakhri Houssem
    Sakhri Houssem over 6 years
    thank's Mr @olivier-moindrot but if I have a batch of picture format .tif
  • Sakhri Houssem
    Sakhri Houssem over 6 years
    Thanks, 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
    Bastian about 6 years
    How to handle the labels in such case?
  • Dee
    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
    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
    D T almost 5 years
    After train my data ,how can use to detect a image ?
  • Aadnan Farooq A
    Aadnan Farooq A over 4 years
    How about if there is more than three 3 channel image and format of file .mat.. the code will be same?
  • Olivier Moindrot
    Olivier Moindrot over 4 years
    @AadnanFarooqA: in this case you need to change the _parse_function to read the .mat file
  • Aadnan Farooq A
    Aadnan Farooq A over 4 years
    from 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
    Olivier Moindrot over 4 years
    You can just get all the filenames and labels in python, then use my code to put it in tensorflow
  • Mehdi Zare
    Mehdi Zare almost 4 years
    for Tensorflow 2, replace tf.read_file(filename) with tf.io.read_file(filename)
  • Roi Mulia
    Roi Mulia over 3 years
    Hey @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
    Samantha Garcia about 3 years
    how do you resize the images in the new version?
  • Olivier Moindrot
    Olivier Moindrot about 3 years
    @SamanthaCruz: you can add it in the _parse_function