【问题标题】:How to make an if statement using a boolean Tensor如何使用布尔张量制作 if 语句
【发布时间】:2016-01-23 05:08:17
【问题描述】:

如何使用布尔张量创建 if 语句?更准确地说,我试图将大小为 1 的张量与常数进行比较,检查张量中的值是否小于常数。我发现我必须将常量设为自己的大小 1 张量并使用 this 方法检查第一个张量是否小于第二个张量,但我不确定如何使生成的布尔张量正确适合if 语句。只需将其作为 if 语句的查询放入 if 语句总是返回 true。

编辑:这或多或少是代码的样子。但是,无论是否有参数,我都会收到错误 'bool' object has no attribute 'name',这让我认为问题在于它没有返回 TensorFlow 对象。

pred = tf.placeholder(tf.bool)

def if_true(x, y, z):
  #act on x, y, and z
  return True

def if_false():
  return False

# Will be `tf.cond()` in the next release.
from tensorflow.python.ops import control_flow_ops
from functools import partial
x = ...
y = ...
z = ...

result = control_flow_ops.cond(pred, partial(if_true, x, y, z), if_false)

【问题讨论】:

  • 我认为您需要从 if_trueif_false 函数返回 Tensor 对象。这些可以分别是tf.constant(True)tf.constant(False)。如果您对xyz 的操作有副作用,请务必在返回的张量中添加对它们的控制依赖,否则它们可能无法执行。
  • 这违背了原始条件的目的。不过,对于我的特定变量,我可能已经找到了解决方法。
  • 嗯,如果将输出作为 Tensor 不满足您的需求,那么我认为您没有将结果提供给进一步的 TensorFlow 子图。在这种情况下,使用 sess.run() 和简单的 Python if 语句可能是最简单的。

标签: tensorflow


【解决方案1】:

TL;DR:您需要使用 Session.run() 来获取 Python 布尔值,但还有其他方法可以更有效地实现相同的结果。

看起来您已经知道如何从您的值中获取布尔张量,但为了其他读者的利益,它看起来像这样:

computed_val = ...
constant_val = tf.constant(37.0)
pred = tf.less(computed_val, constant_val)  # N.B. Types of the two args must match

下一部分是如何将其用作条件。最简单的做法是使用 Python if 语句,但要做到这一点,您必须使用 Session.run()评估张量 pred

sess = tf.Session()

if sess.run(pred):
  # Do something.
else:
  # Do something else.

关于使用 Python if 语句的一个警告是,您必须将整个表达式求值到 pred,这使得重用已经计算的中间值变得很棘手。我想提请您注意使用 TensorFlow 计算条件表达式的另外两种方法,它们不需要您评估谓词并返回 Python 值。

第一种方法使用tf.select() 操作来有条件地传递来自作为参数传递的两个张量的值:

pred = tf.placeholder(tf.bool)  # Can be any computed boolean expression.
val_if_true = tf.constant(28.0)
val_if_false = tf.constant(12.0)
result = tf.select(pred, val_if_true, val_if_false)

sess = tf.Session()
sess.run(result, feed_dict={pred: True})   # ==> 28.0
sess.run(result, feed_dict={pred: False})  # ==> 12.0

tf.select() 操作在其所有参数上按元素工作,这允许您组合来自两个输入张量的值。有关详细信息,请参阅its documentationtf.select() 的缺点是它会在计算结果之前同时计算 val_if_trueval_if_false,如果它们是复杂的表达式,这可能会很昂贵。

第二种方法使用tf.cond() 操作,它有条件地计算两个表达式之一。如果表达式很昂贵,这是特别有用的,如果它们have side effects 是必不可少的。基本模式是指定两个 Python 函数(或 lambda 表达式)来构建将在真或假分支上执行的子图:

# Define some large matrices
a = ...
b = ...
c = ...

pred = tf.placeholder(tf.bool)

def if_true():
  return tf.matmul(a, b)

def if_false():
  return tf.matmul(b, c)

# Will be `tf.cond()` in the next release.
from tensorflow.python.ops import control_flow_ops

result = tf.cond(pred, if_true, if_false)

sess = tf.Session()
sess.run(result, feed_dict={pred: True})   # ==> executes only (a x b)
sess.run(result, feed_dict={pred: False})  # ==> executes only (b x c)

【讨论】:

  • 有没有办法让 .cond 中的这些函数之一具有参数?我希望 if_true 有 3 个参数,但我不知道如何通过。如果我使用部分或 lambda,它会告诉我 bool 对象没有属性名称,我怀疑这是来自 Tensorflow 试图创建图形。哦,我的 if_true 和 if_false 返回一个布尔值,这就是为什么它是一个布尔对象。
  • if_true/if_false 函数本身不应有参数,但您可以从封闭范围捕获值。我不确定我是否从您的评论中对您的代码有一个很好的了解,所以也许最好用当前版本更新您的问题。
  • 用新代码编辑。尝试将涉及参数的信息移出函数并在正常的 if 语句中,我得到了同样的错误,所以问题一定是因为我没有返回 TensorFlow 对象。问题是,依赖于这个布尔值的信息不在 TensorFlow 对象中。
  • 不需要使用 control_flow_ops.cond。 tf.cond 现在扮演同样的角色。
  • @mrry,这里tf.cond(pred, if_true, if_false)tf.cond(pred, if_true(), if_false()) 有什么区别,为什么我使用tf.cond(pred, if_true(), if_false()) 它会出现错误fn1 must be callable?谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-03-26
  • 2020-08-20
  • 1970-01-01
  • 2023-01-19
  • 1970-01-01
  • 2018-04-17
  • 2012-02-09
相关资源
最近更新 更多