TensorFlow имеет два способа оценить часть графика: Session.run в списке переменных и Tensor.eval. Есть ли разница между этими двумя?
В TensorFlow, в чем разница между Session.run() и Tensor.eval()?
Ответ 1
Если у вас есть Tensor t, вызов t.eval() эквивалентен вызову tf.get_default_session().run(t).
Вы можете сделать сеанс по умолчанию следующим образом:
t = tf.constant(42.0)
sess = tf.Session()
with sess.as_default(): # or `with sess:` to close on exit
assert sess is tf.get_default_session()
assert t.eval() == sess.run(t)
Самое важное отличие состоит в том, что вы можете использовать sess.run() для извлечения значений многих тензоров на одном и том же шаге:
t = tf.constant(42.0)
u = tf.constant(37.0)
tu = tf.mul(t, u)
ut = tf.mul(u, t)
with sess.as_default():
tu.eval() # runs one step
ut.eval() # runs one step
sess.run([tu, ut]) # evaluates both tensors in a single step
Обратите внимание, что каждый вызов eval и run будет выполнять весь график с нуля. Чтобы кэшировать результат вычисления, назначьте его tf.Variable.
Ответ 2
Сеанс часто задаваемых вопросов о тензорном потоке отвечает на тот же вопрос. Я бы просто пошел и оставил его здесь:
Если t является объектом Tensor, t.eval() является сокращением для sess.run(t) (где sess - текущий сеанс по умолчанию. Два следующих фрагмента кода эквивалентны:
sess = tf.Session()
c = tf.constant(5.0)
print sess.run(c)
c = tf.constant(5.0)
with tf.Session():
print c.eval()
Во втором примере сеанс действует как диспетчер контекста, который приводит к его установке в качестве сеанса по умолчанию для времени жизни блока. Подход контекстного менеджера может привести к более сжатому коду для простых случаев использования (например, модульных тестов); если ваш код имеет дело с несколькими графиками и сеансами, может быть более прямым для явных вызовов Session.run().
Я бы порекомендовал вам, по крайней мере, пропустить все ответы на часто задаваемые вопросы, поскольку это может прояснить многое.
Ответ 3
eval() не может обработать объект списка
tf.reset_default_graph()
a = tf.Variable(0.2, name="a")
b = tf.Variable(0.3, name="b")
z = tf.constant(0.0, name="z0")
for i in range(100):
z = a * tf.cos(z + i) + z * tf.sin(b - i)
grad = tf.gradients(z, [a, b])
init = tf.global_variables_initializer()
with tf.Session() as sess:
init.run()
print("z:", z.eval())
print("grad", grad.eval())
но Session.run() может
print("grad", sess.run(grad))
поправь меня если я не прав
Ответ 4
В тензорном потоке вы создаете графики и передаете значения этому графику. Graph выполняет всю тяжелую работу и генерирует выходные данные на основе конфигурации, которую вы сделали в графике. Теперь, когда вы передаете значения в график, сначала вам нужно создать сеанс тензорного потока.
tf.Session()
После инициализации сеанса вы должны использовать этот сеанс, потому что все переменные и настройки теперь являются частью сеанса. Таким образом, существует два способа передачи внешних значений в граф, чтобы граф мог их принимать. Одним из них является вызов .run() во время использования выполняемого сеанса.
Другим способом, который по сути является ярлыком для этого, является использование .eval(). Я сказал ярлык, потому что полная форма .eval()
tf.get_default_session().run(values)
Вы можете проверить это сами. Вместо values.eval() запустите tf.get_default_session().run(values). Вы должны получить такое же поведение.
eval использует сессию по умолчанию, а затем выполняет run().
Ответ 5
Самое главное помнить:
Единственный способ получить константу, переменную (любой результат) из TenorFlow - это сеанс.
Зная это, все остальное легко:
И
tf.Session.run()иtf.Tensor.eval()получают результаты из сеанса, гдеtf.Tensor.eval()является ярлыком для вызоваtf.get_default_session().run(t)
Я также хотел бы описать метод tf.Operation.run() как здесь:
После того, как граф был запущен в сеансе, Операция может быть выполнена, передав ее в
tf.Session.run().op.run()является ярлыком для вызоваtf.get_default_session().run(op).