Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Image conversion in TensorFlow slows over time

I have this method that takes an image and converts it into a tensor. I am invoking it in a loop and the execution time of the conversion starts small and keep growing.

def read_tensor_from_image_file(file_name, input_height=299, input_width=299, input_mean=0, input_std=255):
    input_name = "file_reader"
    output_name = "normalized"
    file_reader = tf.read_file(file_name, input_name)

    image_reader = tf.image.decode_jpeg(file_reader, channels = 3,
        name='jpeg_reader')
    float_caster = tf.cast(image_reader, tf.float32)
    dims_expander = tf.expand_dims(float_caster, 0)
    resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
    normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
    sess = tf.Session()
    result = sess.run(normalized)

    return result

How do I optimize this?

like image 689
Bupathi Sangeeth Avatar asked Jan 30 '23 12:01

Bupathi Sangeeth


1 Answers

The problem is almost certainly due to the use of the same default tf.Graph across many calls to your read_tensor_from_image_file() function. The easiest way to fix this is to add a with tf.Graph().as_default(): block around the function body, as follows:

def read_tensor_from_image_file(file_name, input_height=299, input_width=299, input_mean=0, input_std=255):
   with tf.Graph().as_default():
    input_name = "file_reader"
    output_name = "normalized"
    file_reader = tf.read_file(file_name, input_name)
    image_reader = tf.image.decode_jpeg(file_reader, channels = 3,
        name='jpeg_reader')
    float_caster = tf.cast(image_reader, tf.float32)
    dims_expander = tf.expand_dims(float_caster, 0)
    resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
    normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])
    sess = tf.Session()
    result = sess.run(normalized)
    return result

With this change, each call to the function will create a new graph, rather than adding nodes the default graph (which would then grow over time, leaking memory, and taking longer to start each time you use it).

A more efficient version would use a tf.placeholder() for the filename, construct a single graph, and move the for loop inside the TensorFlow session. Something like the following would work:

def read_tensors_from_image_files(file_names, input_height=299, input_width=299, input_mean=0, input_std=255):
   with tf.Graph().as_default():
    input_name = "file_reader"
    output_name = "normalized"
    file_name_placeholder = tf.placeholder(tf.string, shape=[])
    file_reader = tf.read_file(file_name_placeholder, input_name)
    image_reader = tf.image.decode_jpeg(file_reader, channels = 3,
        name='jpeg_reader')
    float_caster = tf.cast(image_reader, tf.float32)
    dims_expander = tf.expand_dims(float_caster, 0)
    resized = tf.image.resize_bilinear(dims_expander, [input_height, input_width])
    normalized = tf.divide(tf.subtract(resized, [input_mean]), [input_std])

    with tf.Session() as sess:
      for file_name in file_names:
        yield sess.run(normalized, {file_name_placeholder: file_name})
like image 80
mrry Avatar answered Feb 06 '23 14:02

mrry