如何在TensorFlow图中添加if条件?

71

假设我有以下代码:

x = tf.placeholder("float32", shape=[None, ins_size**2*3], name = "x_input")
condition = tf.placeholder("int32", shape=[1, 1], name = "condition")
W = tf.Variable(tf.zeros([ins_size**2*3,label_option]), name = "weights")
b = tf.Variable(tf.zeros([label_option]), name = "bias")

if condition > 0:
    y = tf.nn.softmax(tf.matmul(x, W) + b)
else:
    y = tf.nn.softmax(tf.matmul(x, W) - b)  

if 语句能在计算中使用吗(我认为不行)?如果不能,那该如何将一个 if 语句添加到 TensorFlow 的计算图中呢?

2个回答

108

你说得对,if语句在这里不起作用,因为该条件在图构建时被评估,而你想要的是条件取决于在运行时提供给占位符的值。(实际上,它总是会执行第一个分支,因为condition > 0会求值为一个Python中的真值的张量。)

为了支持条件控制流,TensorFlow提供了tf.cond()操作符,该操作符根据布尔条件评估两个分支中的一个。为了向你展示如何使用它,我将重写你的程序,使condition成为一个标量tf.int32值,以简化问题:

x = tf.placeholder(tf.float32, shape=[None, ins_size**2*3], name="x_input")
condition = tf.placeholder(tf.int32, shape=[], name="condition")
W = tf.Variable(tf.zeros([ins_size**2 * 3, label_option]), name="weights")
b = tf.Variable(tf.zeros([label_option]), name="bias")

y = tf.cond(condition > 0, lambda: tf.matmul(x, W) + b, lambda: tf.matmul(x, W) - b)

1
@mrry 默认情况下两个分支都会被执行吗?我有tf.cond(c,lambda x:train_op1,lambda x:train_op2),并且在每次执行cond时都会独立执行两个train_ops,无论c的值如何。我做错了什么吗? - Piotr Dabkowski
12
这是tf.cond()有时会出人意料的行为,相关文档已经涉及(请参见https://www.tensorflow.org/api_docs/python/tf/cond)。简而言之,您需要在各自的lambda函数内创建您想要有条件地运行的操作。您在lambda函数外面创建但在任一分支中引用的所有内容都将在两种情况下执行。 - mrry
@mrry 哇,这真是出乎意料 :) 谢谢您的答案,将操作定义在函数内部解决了问题。 - Piotr Dabkowski
逻辑条件是否逐个元素应用? - ABIM

10

TensorFlow 2.0

TF 2.0引入了一个名为AutoGraph的功能,它可以将Python代码JIT编译为图执行。这意味着您可以使用Python控制流语句(是的,包括if语句)。从文档中可以看到:

AutoGraph支持常见的Python语句,如whileforifbreakcontinuereturn,并支持嵌套。这意味着您可以在whileif语句的条件中使用张量表达式,或在for循环中迭代张量。

您需要定义一个实现逻辑的函数,并用tf.function进行注释。下面是来自文档的示例:

import tensorflow as tf

@tf.function
def sum_even(items):
  s = 0
  for c in items:
    if tf.equal(c % 2, 0): 
        s += c
  return s

sum_even(tf.constant([10, 12, 15, 20]))
#  <tf.Tensor: id=1146, shape=(), dtype=int32, numpy=42>

1
你为什么要使用 tf.equal()?难道不能使用 == 并让AutoGraph自动编译吗? - problemofficer - n.f. Monica
2
@problemofficer 这是一个非常好的问题。我也曾经像你一样假设,但却被咬了一口。这里有一个我提出的问题,讨论了这种行为:https://dev59.com/VrTma4cB1Zd3GeqP74Y- - cs95

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接