Reputation: 7273
I have written a program and trying to write it with Tensorflow so that I can use the GPU.
Please let me know what I can do to convert it into tensorflow.
Here is the code for Normal Execution:
def function(array,position,times):
o = []
for loop in range(position,30):
result = 0.0
for k in range(times):
result += array[loop-k]
result /= times
o.append(result)
return o
q = [i for i in range(30)]
output = function(q,10,5)
print(output)
Using the Tensorflow I have tried this:
import tensorflow as tf
tf.enable_eager_execution()
def function_tf(array,position,times):
o = tf.TensorArray(tf.float32,(30-position))
index = tf.Variable(0)
for loop in range(position,30):
result = tf.Variable(0.0)
for k in range(times):
result.assign_add(array[loop-k].numpy())
# print(result)
result = tf.divide(result,times)
o = o.write(index.numpy(),result.numpy())
index.assign_add(1)
return o.stack().numpy()
q = [i for i in range(30)]
q = tf.convert_to_tensor(q)
output = function_tf(q,tf.constant(10),tf.constant(5.0))
print(output)
The output is same:
[ 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
26. 27.]
But the only fact is the loops in the Tensorflow code still are the Python loop so it will work with CPU and not with GPU. I want everything to happen inside the GPU. Only assignment could be through the CPU.
Please help me convert the loop.
Upvotes: 1
Views: 566
Reputation: 59681
You can actually write that function more simply without loops as the following convolution:
import tensorflow as tf
tf.enable_eager_execution()
def function(array, position, times):
array = tf.convert_to_tensor(array)
array = array[tf.newaxis, tf.maximum(position - times + 1, 0):, tf.newaxis]
filter = tf.fill([times, 1, 1], tf.dtypes.cast(1 / times, array.dtype))
return tf.nn.conv1d(array, filter, stride=1, padding='VALID')[0, :, 0]
print(function(tf.range(30.), 10, 5).numpy())
# [ 8.000001 9. 10. 11. 12. 13. 14.
# 15. 16. 17. 18. 19. 20. 21.
# 21.999998 23. 24.000002 25. 26. 26.999998]
EDIT: If you want to explicitly recreate the loop in the original code (although it will probably be slower), you can do it with tf.while_loop
as follows:
import tensorflow as tf
tf.enable_eager_execution()
def function(array, position, times):
array = tf.convert_to_tensor(array)
dt = array.dtype
ta = tf.TensorArray(dt, size=tf.size(array) - position, element_shape=())
ta, _ = tf.while_loop(
lambda ta, i: i < tf.size(array),
lambda ta, i: (ta.write(i - position, tf.reduce_sum(array[i - times + 1:i + 1]) / times), i + 1),
[ta, position])
return ta.stack()
print(function(tf.range(30.), 10, 5).numpy())
# [ 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
# 26. 27.]
Or, even further, writing both loops instead of using tf.reduce_sum
:
import tensorflow as tf
tf.enable_eager_execution()
def function(array, position, times):
array = tf.convert_to_tensor(array)
dt = array.dtype
ta = tf.TensorArray(dt, size=tf.size(array) - position, element_shape=())
ta, _ = tf.while_loop(
lambda ta, i: i < tf.size(array),
lambda ta, i: (ta.write(i - position,
tf.while_loop(lambda s, j: j < times,
lambda s, j: (s + array[i - j], j + 1),
[tf.zeros((), dt), 0])[0] / times),
i + 1),
[ta, position])
return ta.stack()
print(function(tf.range(30.), 10, 5).numpy())
# [ 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
# 26. 27.]
Since you are using eager execution, you could also directly use Python loops like this:
import tensorflow as tf
tf.enable_eager_execution()
def function(array, position, times):
array = tf.convert_to_tensor(array)
o = []
for loop in range(position, tf.size(array)):
result = 0
for k in range(times):
result += array[loop-k]
result /= times
o.append(result)
return tf.stack(o)
print(function(tf.range(30.), 10, 5).numpy())
# [ 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25.
# 26. 27.]
Upvotes: 1