Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is random number generator tf.random_uniform in tensorflow much faster than the numpy equivalent

The following code is what I used to test the performance:

import time
import numpy as np
import tensorflow as tf

t = time.time()
for i in range(400):
    a = np.random.uniform(0,1,(1000,2000))
print("np.random.uniform: {} seconds".format(time.time() - t))

t = time.time()
for i in range(400):
    a = np.random.random((1000,2000))
print("np.random.random:  {} seconds".format(time.time() - t))

t = time.time()
for i in range(400):
    a = tf.random_uniform((1000,2000),dtype=tf.float64);
print("tf.random_uniform: {} seconds".format(time.time() - t))

All the three segments generate a uniformly random 1000*2000 matrix in double precision 400 times. The timing differences are striking. On my Mac,

np.random.uniform: 10.4318959713 seconds
np.random.random:  8.76161003113 seconds
tf.random_uniform: 1.21312117577 seconds

Why is tensorflow much faster than numpy?

like image 822
Jie Avatar asked Oct 29 '18 22:10

Jie


2 Answers

tf.random_uniform in this case is returning an unevaluated Tensor type, tensorflow.python.framework.ops.Tensor, and if you setup a session context in which to evaluate a in the tf.random_uniform case, you'll see that it takes a while too.

For example, here in the tf case I added sess.run (on a CPU-only machine), and it takes ~16 seconds to evaluate and materialize, which makes sense given some overhead to marshal into the numpy data type on output.

In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:import time
import numpy as np
import tensorflow as tf

t = time.time()
for i in range(400):
    a = np.random.uniform(0,1,(1000,2000))
print("np.random.uniform: {} seconds".format(time.time() - t))

t = time.time()
for i in range(400):
    a = np.random.random((1000,2000))
print("np.random.random:  {} seconds".format(time.time() - t))

sess = tf.Session()
t = time.time()
for i in range(400):
    a = sess.run(tf.random_uniform((1000,2000),dtype=tf.float64))
print("tf.random_uniform: {} seconds".format(time.time() - t))::::::::::::::::::
:--
np.random.uniform: 11.066569805145264 seconds
np.random.random:  9.299575090408325 seconds
2018-10-29 18:34:58.612160: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.1 instructions, but these are available on your machine and could speed up CPU computations.
2018-10-29 18:34:58.612191: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use SSE4.2 instructions, but these are available on your machine and could speed up CPU computations.
2018-10-29 18:34:58.612210: W tensorflow/core/platform/cpu_feature_guard.cc:45] The TensorFlow library wasn't compiled to use AVX instructions, but these are available on your machine and could speed up CPU computations.
tf.random_uniform: 16.619441747665405 seconds
like image 160
ely Avatar answered Oct 12 '22 10:10

ely


You've just created a computational graph that generates an operation to output random numbers. For the values to be calculated, you must execute the graph in a tf.Session.

// build the graph
a = tf.random_uniform((1000,2000))

// run the graph
with tf.Session() as sess:
    t = time.time()
    for i in range(400):
        computed_rand_values = sess.run(a)
    //print(...)

I did not tested it, but I'm sure that the calculation time will be longer than the result before

like image 38
J.E.K Avatar answered Oct 12 '22 11:10

J.E.K