Both eager and graph execution in tensorflow tests

Refresh

November 2018

Views

348 time

5

I have some tests that work with graph and sessions. I also want to write some small tests with eager mode to test easily some functionalities. For example:

def test_normal_execution():
    matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
    dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
    iterator = dataset.make_one_shot_iterator()
    first_elem = iterator.get_next()
    with tf.Session() as sess:
        result = sess.run(first_elem)
        assert (result == [1, 2, 3, 4]).all()
    sess.close()

In another file:

def test_eager_execution():
    matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
    tf.enable_eager_execution()
    dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
    iterator = dataset.__iter__()
    first_elem = iterator.next()
    assert (first_elem.numpy() == [1, 2, 3, 4]).all() 

Is there a way to to this? I get ValueError: tf.enable_eager_execution must be called at program startup. when I try to run the test executed eagerly. I am using pytest to run my tests.

edit:

With little assistance from the accepted response I created a decorator, that works nicely with eager mode and pytest's fixtures:

def run_eagerly(func):
    @functools.wraps(func)
    def eager_fun(*args, **kwargs):
        with tf.Session() as sess:
            sess.run(tfe.py_func(func, inp=list(kwargs.values()), Tout=[]))

    return eager_fun

2 answers

7

С оговоркой , что все в tf.contribпространстве имен является предметом для изменения между выпусками , вы можете украсить свой тест с @tf.contrib.eager.run_test_in_graph_and_eager_modes. Некоторые другие проекты, такие как TensorFlow вероятность , кажется, используют это .

Для не-тестов, некоторые вещи, чтобы посмотреть в являются:

  • tf.contrib.eager.defun: Это полезно, когда вы включили нетерпеливое выполнение, но хотите «собрать» некоторые вычисления в виде график, чтобы извлечь выгоду из памяти и / или оптимизации производительности.
  • tf.contrib.eager.py_func: Это полезно, когда не включено нетерпеливое выполнение, но хотят, чтобы выполнить некоторые вычисления в графике, как функции Python.

Можно спросить рассуждение за не позволяя вызов tf.enable_eager_execution()быть отменено. Идея заключается в том , что библиотека авторы не должны ссылаться на него, только конечный пользователь должен вызвать его main(). Уменьшает вероятность того, что библиотеки написаны несовместимые пути (где говорят функции в одной библиотеке отключить нетерпеливое выполнение и вернуть символические тензоры в то время как функции другой библиотеки позволяют нетерпеливое выполнению и ожидают конкретные значные тензоры. Это сделало бы смешивание библиотек проблематичны).

надеюсь, это поможет

ash
1

Существует официальный способ использовать нетерпеливое исполнение в среде графа . Но я не уверен , если это хорошо и достаточно удобно для вас , потому что вам нужно написать достаточно некоторый код , чтобы обернуть и запустить тестовую функцию. Во всяком случае, вот ваш пример , который должен по крайней мере работы:

import numpy as np
import tensorflow as tf

def test_normal_execution():
    matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
    dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
    iterator = dataset.make_one_shot_iterator()
    first_elem = iterator.get_next()
    with tf.Session() as sess:
        result = sess.run(first_elem)
        assert (result == [1, 2, 3, 4]).all()
    sess.close()

def test_eager_execution():
    matrix_2x4 = np.array([[1, 2, 3, 4], [6, 7, 8, 9]])
    dataset = tf.data.Dataset.from_tensor_slices(matrix_2x4)
    iterator = dataset.__iter__()
    first_elem = iterator.next()
    assert (first_elem.numpy() == [1, 2, 3, 4]).all()

test_normal_execution()
# test_eager_execution() # Instead, you have to use the following three lines.
with tf.Session() as sess:
    tfe = tf.contrib.eager
    sess.run(tfe.py_func(test_eager_execution, [], []))