Как надежно измерить время sess.run() в TensorFlow?

Моя проблема в том, что если аргументы операции постоянны, TF кэширует результаты:

a = tf.constant(np.random.randn(*(100, 101)))
b = tf.constant(np.random.randn(*(100, 102)))
c = tf.constant(np.random.randn(*(101, 102)))
# Some expensive operation.
res = tf.einsum('si,sj,ij->s', a, b, c)
%timeit sess.run(res)

Самый медленный пробег занял в 577,76 раз больше времени, чем самый быстрый. Это может означать, что промежуточный результат кэшируется. 10000 циклов, лучший из 3: 137 мкс на цикл

Если я генерирую тензоры с нуля при каждом запуске, то я также подсчитываю накладные расходы на генерацию тензора:

a = tf.random_normal((100, 101))
b = tf.random_normal((100, 102))
c = tf.random_normal((101, 102))
res = tf.einsum('si,sj,ij->s', a, b, c)
%timeit sess.run(res)

Самый медленный пробег занял в 4,07 раза больше времени, чем самый быстрый. Это может означать, что промежуточный результат кэшируется. 10 циклов, лучший из 3: 28 мс на цикл

Может быть, в этом конкретном примере накладные расходы невелики, но для более дешевых операций они могут быть значительными.

Есть ли способ заморозить аргументы, чтобы они не пересчитывались при каждом sess.run(), а подавляли все остальное кэширование?


person Bihaqo    schedule 11.04.2017    source источник


Ответы (1)


При каждом запуске (между сеансами) будут оцениваться любые тензорные объекты, которые вы передаете sess.run(). Из документов:

Объект Session инкапсулирует среду, в которой выполняются объекты Operation и оцениваются объекты Tensor.

Невозможно игнорировать оценку (вычисление значений) тензоров между сеансами, если это часть оцениваемого выражения.

В вашем примере тензорные объекты a, b, c всегда оцениваются в каждом сеансе, поскольку их значения необходимы для вычисления einsum. Но в рамках сеанса они вычисляются только один раз и кэшируются при выполнении.

Но в рамках сеанса вы можете сделать так, чтобы он оценивался только один раз и использовался в другом месте. Но опять же, это работает только в рамках сеанса.

person kmario23    schedule 11.04.2017
comment
То есть вы говорите, что мы ничего не можем сделать, чтобы надежно измерить время выполнения такой операции, как einsum? Что, если я как грязный хак аргументы исправлю, но умножу их на случайное число? Это заставит TF пересчитать все, не добавляя значительных накладных расходов... const = tf.random_normal((1,))[0] res = tf.einsum('si,sj,ij-›s', const * a , константа * б, константа * с) - person Bihaqo; 11.04.2017
comment
В рамках сеанса вы измеряете фактически время, затраченное на операцию, т. е. einsum. - person kmario23; 11.04.2017
comment
Но похоже, что промежуточные вычисления кэшируются при прогонах, см. первый пример в исходном вопросе. Время работы составляет 137 мкс, что намного быстрее, чем этот конкретный einsum принимает случайные входные данные (даже если исключить время для генерации этих входных данных). - person Bihaqo; 11.04.2017
comment
Это может помочь? tensorflow.org/api_docs/python/tf/ - person kmario23; 11.04.2017
comment
Может быть, использовать заполнители и кормить dict? - person Mad Wombat; 11.04.2017