неожиданный тенорфул (1.12) эффективность вещания - PullRequest
1 голос
/ 26 апреля 2020

При реализации такой модели, как FM с скрытым вектором, используя тензор потока, я получил неожиданное умножение эффективность вещания проблема: одинаковые массивы умножаются после того, как diff транспонирует затраты совсем по-разному.

Однако при использовании numpy эффективность отличается не так значительно.

Итак, Есть ли некоторые различия правил вещания между tenorflow 1.12 и numpy?
PS: tf1.14 & tf2, работает нормально, кто-нибудь знает, какое важное обновление исправит эту проблему ?

Просто код:

[b, d, n, 1] * [n, k]     # ok
[b, n, d, 1] * [n, 1, k]  # slow
[b, n, 1, d] * [n, k, 1]  # very very slow

Весь код:

import  tensorflow as tf
import numpy as np
from time import time
import timeit
sess = tf.InteractiveSession()

batch_size = 1024
k = 8
d = 32 # emb_size
n = 20 # slot count
input_var = np.random.randn(batch_size, n, d, 1)

v_nk = np.random.randn(n, k)
v_nkd = np.random.randn(n, k, d)
v_nk1 = np.reshape(v_nk, [n, k, 1])
v_n1k = np.reshape(v_nk, [n, 1, k])

input_var_bdn1 = np.transpose(input_var, [0, 2, 1, 3]).copy() # [b, d, n, 1]
input_var_bn1d = np.transpose(input_var, [0, 1, 3, 2]).copy() # [b, n, 1, d]
input_var_b1nd = np.transpose(input_var, [0, 3, 1, 2]).copy() # [b, 1, n, d]


# numpy
print('with numpy: ')

print ("X_nk COST: ",timeit.timeit(lambda: input_var_bdn1 * v_nk, number=100 )) # 3.1s
print ("X_nk1 COST: ",timeit.timeit(lambda: input_var_bn1d * v_nk1, number=100 )) # 2.5s
print ("X_n1k COST: ",timeit.timeit(lambda: input_var * v_n1k, number=100 )) # 3.0s
print ("X_nkd COST: ",timeit.timeit(lambda: input_var_bn1d * v_nkd, number=100 )) # 2.5s


input_var = tf.constant(input_var)
input_var_bdn1 = tf.constant(input_var_bdn1)
input_var_bn1d = tf.constant(input_var_bn1d)
input_var_b1nd = tf.constant(input_var_b1nd)

v_nk = tf.constant(v_nk)
v_nk1 = tf.constant(v_nk1)
v_n1k = tf.constant(v_n1k)
v_nkd = tf.constant(v_nkd)

input_X_nk = input_var_bdn1 * v_nk
input_X_n1k = input_var * v_n1k
input_X_nk1 = input_var_bn1d * v_nk1
input_X_nkd = input_var_bn1d * v_nkd

print()
print('with tf: ')

print ("X_nk COST: ",timeit.timeit(lambda: sess.run(input_X_nk), number=100 )) # 0.2s
print ("X_nk1 COST: ",timeit.timeit(lambda: sess.run(input_X_nk1), number=100 )) # 2.2s
print ("X_n1k COST: ",timeit.timeit(lambda: sess.run(input_X_n1k), number=100 ))  # 0.6s
print ("X_nkd COST: ",timeit.timeit(lambda: sess.run(input_X_nkd), number=100 ))  # 0.55s


for _ in range(10):
    input_X_nk += input_var_bdn1 * v_nk
    input_X_n1k += input_var * v_n1k
    input_X_nk1 += input_var_bn1d * v_nk1
    input_X_nkd += input_var_bn1d * v_nkd

print()
print('with tf straightly: ')

print ("X_nk COST: ",timeit.timeit(lambda: sess.run(input_X_nk), number=1 )) # 0.8s
print ("X_nk1 COST: ",timeit.timeit(lambda: sess.run(input_X_nk1), number=1 ))  # 6.1s
print ("X_n1k COST: ",timeit.timeit(lambda: sess.run(input_X_n1k), number=1 )) # 1.7s
print ("X_nkd COST: ",timeit.timeit(lambda: sess.run(input_X_nkd), number=1 )) # 1.6s

Протестированные среды:
tenenflow 1.12.0 ( tf1.14 / tf2 работает штраф )
python 3.6.9 && py 2.7.18
Centos 7.4 && Ma c 10.14

...