Simon Rühle
Simon Rühle

Reputation: 229

Tensorflow avoid shape information with crop

again I have some issue with Tensorflow. I am using a FCN model and need to apply a random crop due to memory usage.

tf.random_crop(combined, size=[512, 512, 4])

unfortunately now the new size "sticks" to the tensor and I can not get rid of it. The issue caused by this is, that the resulting model only accepts input of size 512x512, which cannot be worked around in a nice way, as far as I know. Is there any solution to either remove the shape information caused by random_crop or to easily adapt the size afterwards after obtaining a trained model? Thank you in advance.

Upvotes: 1

Views: 190

Answers (1)

benjaminplanche
benjaminplanche

Reputation: 15139

I don't know if it will completely suit your use-case, but the size parameter of tf.random_crop() can be a tensor, so you can for instance use a placeholder as shown in the example below.

import tensorflow as tf
import numpy as np

image = tf.placeholder(tf.float64, [None, None, 4])

cropped_size = tf.placeholder(tf.int32, [2])    
cropped_image = tf.random_crop(image, size=[cropped_size[0], cropped_size[1], 4])

print(cropped_image.get_shape().as_list())
# [None, None, 4]

with tf.Session() as sess:
    res = sess.run(cropped_image, 
                   feed_dict={image: np.random.rand(900, 600, 4), cropped_size: [512, 512]})
    print(res.shape)
    # (512, 512, 4)

EDIT:

There may be different solutions to have the value of cropped_size assigned without using a feed_dict, depending how the crop dimensions are stored ; e.g. using TF file readers (the values would stay unknown till read).

Another simple hack otherwise: take advantage of tf.placeholder_with_default(default_val, shape) (doc), providing default_val with the crop dimensions acquired anyhow. As tf.placeholder_with_default() value isn't actually assigned until runtime (in case you you want to feed this placeholder with a different value), your dimensions would stay None in the graph:

import tensorflow as tf

image = tf.random_uniform((900, 600, 4))    # image tensor, acquired anyhow e.g. from tf.data
cropped_size_for_this_run = [512, 512]      # crop dimensions, acquired anyhow

cropped_size = tf.placeholder_with_default(cropped_size_for_this_run, shape=[2])
cropped_image = tf.random_crop(image, size=[cropped_size[0], cropped_size[1], 4])

print(cropped_image.get_shape().as_list())
# [None, None, 4]

with tf.Session() as sess:
    # You can leave cropped_size with its default value assigned at runtime:
    res = sess.run(cropped_image)
    print(res.shape)
    # (512, 512, 4)

    # ... or you can specify a new one if you wish so:
    res = sess.run(cropped_image, feed_dict={cropped_size: [256, 256]})
    print(res.shape)
    # (256, 256, 4)

    # ... It would switch back to the default value if you don't feed one:
    res = sess.run(cropped_image)
    print(res.shape)
    # (512, 512, 4)

Upvotes: 1

Related Questions