0

I'm trying to parallelize this chunk of code using Tensorflow -

import numpy as np
import tensorflow as tf
import time
#Importing a generic dataset from Keras
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    path='mnist.npz'
)

#I would like to compare a reference image to a bunch of images

#This is my reference image
x_reference = np.expand_dims(x_train[0],axis = 2)

start = time.time()
for index, image in enumerate(x_train):
    # The tf.image.ssim is a similarity metric
    tf.image.ssim(np.expand_dims(x_train[index],axis = 2), x_reference, 255)
print("Total Time=", time.time() - start)

I've decided to use tf.while_loop for parallelization -

import numpy as np
import tensorflow as tf
#Importing a generic dataset from Keras
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    path='mnist.npz'
)

#This is my reference image
x_reference = np.expand_dims(x_train[0],axis = 2)
t1 = tf.constant(x_train)
t2 = tf.constant(x_reference)
iters = tf.constant(60000)
def cond(t1, t2, i, iters):
  return tf.less(i, iters)

def body(t1, t2, i, iters):
  return [tf.image.ssim(np.expand_dims(t1[i],axis = 2), t2, 255), t2, tf.add(i,1), iters]

res = tf.while_loop(cond, body, [t1, t2, 0 , iters], parallel_iterations=60000)

However, I am running into errors. I'm quite new with tensorflow and therefore I understand that this code is going to be broken at a range of points. All forms of guidance (even through comments) are highly appreciated!

5
  • your second version is not working, index in np.expand_dims(t1[index],axis = 2) has not been defined. Please fix the code Commented Jan 1, 2021 at 0:54
  • @CrazyBrazilian Thank you for catching it. It has been changed. Commented Jan 1, 2021 at 3:41
  • 1
    Just one extra comment which I forgot in the answer. I assume that you are doing this just for learning how to use tf.while_loop. You don't need all that. Your code could be 2 lines. As I mentioned takes a batch of images. So you could calculate the ssim for all images in just one single line. No need for a loop Commented Jan 1, 2021 at 15:52
  • @CrazyBrazilian The reason I was doing this was to reduce computation time by trying to parallelize the looping process. I did not know that ssim can take image batches. Thank you for that valuable information. Commented Jan 1, 2021 at 20:42
  • 1
    Great ! i guess you can make it faster by passing the entire batch ! I'm glad it helped a little bit and thanks for accepting the answer Commented Jan 1, 2021 at 21:52

1 Answer 1

1

I have fixed your code.

There were 2 issues. The main one was your return from the body function. You need to understand that at every iteration of the "loop", the output of the previous iteration while be inject to the body function. In your code, you were return the sim value as the first column in the tupple. So, in the second "iteration", you don't have t1 there anymore. You have just a single value. That was the reason why you were getting that error. You were trying to index the "sim" value and not t1.

The other issue was when calling tf.image.ssim. It expects a batch of images, it basically needs [1,64,64,1] but you were passing [64,64,1]

def body(t1, t2, i, iters, sim):
  a = np.expand_dims(t1[i],axis = 2)
  a = tf.expand_dims(a, axis=0)   #make a batch
  b = tf.expand_dims(t2, axis=0)  #make a batch
  sim = tf.image.ssim(a, b, 255)
  return [t1, t2, tf.add(i,1), iters, sim]

Here is the whole code:

import numpy as np
import tensorflow as tf


#Importing a generic dataset from Keras
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(
    path='mnist.npz'
)

#This is my reference image
x_reference = np.expand_dims(x_train[0],axis = 2)
t1 = tf.constant(x_train)

t2 = tf.constant(x_reference)
iters = tf.constant(60000)

def cond(t1, t2, i, iters, sim):
  return tf.less(i, iters)

def body(t1, t2, i, iters, sim):
  a = np.expand_dims(t1[i],axis = 2)
  a = tf.expand_dims(a, axis=0)   #make is a batch
  b = tf.expand_dims(t2, axis=0)  #make is a batch
  sim = tf.image.ssim(a, b, 255)
  return [t1, t2, tf.add(i,1), iters, sim]

res = tf.while_loop(cond, body, [t1, t2, 0 , iters, 0], parallel_iterations=60000)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I am not sure if the answer (res) is correct though, as the values don't seem to be similarity measures. However, I got what I was looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.