Is there any similar funtion as list.append() in tensorflow?

Viewed 2820

Recently I encountered a problem, which preprocesses each image binary code(tf.string type) one by one in a placeholder with shape

[batch_size] = [None]

Then I need to concat each result after preprocessed.

Obviously I can't create a FOR sentence to tackle this problem.

So, I used tf.while_loop to do that. It looks like:

in_ph = tf.placeholder(shape=[None], dtype=tf.string)
i = tf.constant(0)
imgs_combined = tf.zeros([1, 224, 224, 3], dtype=tf.float32)

def body(i, in_ph, imgs_combined):
    img_content = tf.image.decode_jpeg(in_ph[i], channels=3)
    c_image = some_preprocess_fn(img_content)
    c_image = tf.expand_dims(c_image, axis=0)
    # c_image shape [1, 224, 224, 3]
    return [tf.add(i, 1), in_ph, tf.concat([imgs_combined, c_image], axis=0)]

def condition(i, in_ph, imgs_combined):
    return tf.less(i, tf.shape(in_ph)[0])

_, _, image_4d = tf.while_loop(condition,
          body,
          [i, in_ph, imgs_combined],
          shape_invariants=[i.get_shape(), in_ph.get_shape(), tf.TensorShape([None, 224, 224, 3])])

image_4d = image_4d[1:, ...]

This code runs ok without any problems. But here, I use imgs_combined to iteratively concat each image one by one. imgs_combined is initialized with imgs_combined = tf.zeros([1, 224, 224, 3], dtype=tf.float32), in such case I can use tf.concat to do this operation, and in the final result I removed the first element.

But in a normally thinking, this function just like a list.append() operation.

X = []
for i, datum in enumerate(data):
    x.append(datum)

Note that here I only initialize X with an empty list.

I want to know is there any similar function as list.append() in tensorflow?

Or.. Is there any better implementation for this code? I feel so strange for initializing imgs_combined.

1 Answers

You can try tf.TensorArray()(link), which supports dynamic length and can write or read
values to the specified index.

import tensorflow as tf

def condition(i, imgs_combined):
    return tf.less(i, 5)
def body(i, imgs_combined):
    c_image = tf.zeros(shape=(224, 224, 3),dtype=tf.float32)
    imgs_combined = imgs_combined.write(i, c_image)
    return [tf.add(i, 1), imgs_combined]

i = tf.constant(0)
imgs_combined = tf.TensorArray(dtype=tf.float32,size=1,dynamic_size=True,clear_after_read=False)

_, image_4d = tf.while_loop(condition,body,[i, imgs_combined])
image_4d = image_4d.stack()

with tf.Session() as sess:
    image_4d_value = sess.run(image_4d)
    print(image_4d_value.shape)

#print
(5, 224, 224, 3)
Related