Tensorflow: воспроизводимые результаты Tensordot - PullRequest
1 голос
/ 11 мая 2019

Я играю с tf.tensordot в Tensorflow. Однако я испытываю некоторые несоответствия, которые меня беспокоят. Ниже приведен воспроизводимый пример:

tf.reset_default_graph()
tf.set_random_seed(42)
np.random.seed(42)
X = np.random.rand(150, 196, 268).astype(np.float32)
W = tf.Variable(initial_value=tf.random_normal([268, 22], stddev=0.1))
dotted_150 = tf.tensordot(X, W, axes=[[2], [0]])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    output_150 = sess.run(dotted_150)

Возвращает тензор с размерами (150, 196, 22)

tf.reset_default_graph()
tf.set_random_seed(42)
np.random.seed(42)
X = np.random.rand(1, 196, 268).astype(np.float32)
W = tf.Variable(initial_value=tf.random_normal([268, 22], stddev=0.1))
dotted_1 = tf.tensordot(X, W, axes=[[2], [0]])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    output_1 = sess.run(dotted_1)

Возвращает тензор с размерами (1, 196, 22)

Теперь, если мы проверим, является ли первый элемент из output_150 почти равным первому и единственному элементу из output_1, результатом будет несоответствие между двумя массивами.

np.testing.assert_allclose(output_1[0], output_150[0])

С другой стороны, если мы сделаем:

np.random.seed(42)
input_150 = np.random.rand(150, 196, 268).astype(np.float32)
np.random.seed(42)
input_1 = np.random.rand(1, 196, 268).astype(np.float32)
np.testing.assert_equal(input_150[0], input_1[0])

Мы видим, что входные данные точно такие же. С учетом вышесказанного, я ожидаю, что выходы tf.tensordot будут одинаковыми, а они - нет.


На той же ноте приведен tf.tensordot эквивалент с использованием tf.reshape и tf.matmul:

tf.reset_default_graph()
tf.set_random_seed(42)
np.random.seed(42)
X = np.random.rand(150, 196, 268).astype(np.float32)
W = tf.Variable(initial_value=tf.random_normal([268, 22], stddev=0.1))
reshaped = tf.reshape(X, [-1, 268])
mulled_150 = tf.reshape(tf.matmul(reshaped, W), [-1, 196, 22])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    output_150 = sess.run(mulled_150)


tf.reset_default_graph()
tf.set_random_seed(42)
np.random.seed(42)
X = np.random.rand(1, 196, 268).astype(np.float32)
W = tf.Variable(initial_value=tf.random_normal([268, 22], stddev=0.1))
reshaped = tf.reshape(X, [-1, 268])
mulled_1 = tf.reshape(tf.matmul(reshaped, W), [-1, 196, 22])
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    output_1 = sess.run(mulled_1)

np.testing.assert_allclose(output_1[0], output_150[0])

Результат точно такой же, несоответствие между выходными массивами. Как это может быть?

1 Ответ

0 голосов
/ 11 мая 2019

Очевидно, что если я использую tf.float64 точность вместо tf.float32, результаты будут идентичны.

...