简体   繁体   English

使用 `tf.Tensor` 作为 Python `bool` 在使用 `tf.data.Dataset` 的图形执行中是不允许的

[英]using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution with `tf.data.Dataset`

I'm trying to make this function accept a single element tensor.我试图让这个 function 接受单元素张量。

def classi(i):
    out = np.zeros((1, 49), np.uint8)
    for j in range(len(classcount)):
        i -= classcount[j]
        if i<0:
            break
    out[0][j] += 1
    return tf.convert_to_tensor(out)
    #basically the error seems to be related to the if i<0 line

This function will be called by another function here这个 function 将在这里被另一个 function 调用

def formatcars(elem):
    return (elem['image'], tf.function(classi(elem['label'])))
    #note elem['label'] is just a single element tensor of integer.

Which in turn is mapped to the cars dataset.依次映射到汽车数据集。

dataset.map(formatcars)

And I keep getting the error:我不断收到错误:

OperatorNotAllowedInGraphError: using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function.

I've tried enabling eager execution.我试过启用急切的执行。 I've tried using tf.function, using tf.cond, tf.greater, .tonumpy(), .eval(), etc. to no avail.我尝试过使用 tf.function,使用 tf.cond、tf.greater、.tonumpy()、.eval() 等都无济于事。 It keeps giving the same error.它不断给出同样的错误。 I'm out of ideas now.我现在没有主意了。

The classcount list is defined as follow: classcount 列表定义如下:

classcount = [ 1,  6,  4, 14, 13,  6,  2,  4,  3, 22,  6,  1, 15,  1,  2,  4,  1,
       12,  5,  1,  2,  4, 11,  2,  1,  1,  5,  4,  2,  1,  1,  1,  1,  1,
        6,  1,  4,  1,  1,  1,  3,  1,  2,  4,  1,  4,  3,  3,  1]

it's simply a list of integers created from它只是一个从创建的整数列表

import scipy
import tensorflow_datasets as tfds

dataset = tfds.load('cars196', split = 'train')
mat = scipy.io.loadmat('cars_annos.mat')
classcount = []
starti = 0
curmake = ''
for i in range(len(mat['class_names'][0])):
    print(mat['class_names'][0][i][0].split(' ', 1)[0])
    if mat['class_names'][0][i][0].split(' ', 1)[0] != curmake:
        print(i-starti)
        if i-starti != 0:
            classcount.append(i-starti)
        starti = i
    curmake = mat['class_names'][0][i][0].split(' ', 1)[0]
classcount.append(1)

cars_annos.mat is from http://imagenet.stanford.edu/internal/car196/cars_annos.mat cars_annos.mat来自http://imagenet.stanford.edu/internal/car196/cars_annos.mat

As the error states, you can't use a tensor as a boolean value in a python conditional statement outside of eager execution, and the tf.data.Dataset will force you to use graph mode (for performances reason).如错误所述,您不能在急切执行之外的 python 条件语句中将张量用作 boolean 值,并且tf.data.Dataset将强制您使用图形模式(出于性能原因)。 You can't simply decorate the function with the @tf.function decorator either, because Autograph is not able to convert a code where a tensor is used as a python bool (in a condition statement for example).您也不能简单地使用@tf.function装饰器装饰 function,因为 Autograph 无法转换将张量用作 Z23EEEB4347BDD26BFC6B7EE9A3B7 示例的代码。

The best way of handling that is to rewrite the function using TF ops.最好的处理方法是使用 TF 操作重写 function。 One way of doing it could be the following:一种方法可能如下:

def graphmode_classi(i):
    """ 
    performs a cumulative sum on classcount and substract that sum from i
    the first negative value will give us the value to one hot encode
    """  
    cumsum = tf.math.cumsum(classcount)
    first_neg = tf.where((i - cumsum)<0)[0]
    return tf.one_hot(first_neg, 49)

We can compare if my rewritten function is equivalent:我们可以比较我重写的 function 是否等效:

# random data
data = tf.cast(tf.random.normal((200, 1))**2 * 10, tf.int32)
for d in data:
    assert (classi(d).numpy() == graphmode_classi(d).numpy()).all()

Now you should be able to use the function written with only tf ops with the tf.data.Dataset API:现在您应该可以使用仅使用 tf ops 编写的 function 和tf.data.Dataset API:

data = tf.cast(tf.random.normal((200, 1))**2 * 10, tf.int32)
ds = tf.data.Dataset.from_tensor_slices(data)
ds.map(graphmode_classi)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 OperatorNotAllowedInGraphError:在图形执行中不允许使用 tf.Tensor 作为 Python bool - OperatorNotAllowedInGraphError: using a tf.Tensor as a Python bool is not allowed in Graph execution OperatorNotAllowedInGraphError:在图形执行中不允许使用 `tf.Tensor` 作为 Python `bool` - OperatorNotAllowedInGraphError: using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution 在图形执行中不允许使用 `tf.Tensor` 作为 Python `bool` - 当我不将它用作 bool 时 - Using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution - when I do not use it as a bool OperatorNotAllowedInGraphError:在图形执行中不允许使用 `tf.Tensor` 作为 Python `bool`。 添加 Metrics 编译 function - OperatorNotAllowedInGraphError: using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution. Add Metrics to compile function Graph 执行中不允许使用 `tf.Tensor` 作为 Python `bool`。 使用 Eager execution 或使用 @tf.function 装饰此函数 - using a `tf.Tensor` as a Python `bool` is not allowed in Graph execution. Use Eager execution or decorate this function with @tf.function Tensorflow 类型错误:不允许将 `tf.Tensor` 用作 Python `bool`。 - Tensorflow Typeerror: Using a `tf.Tensor` as a Python `bool` is not allowed. TensorFlow:TypeError:不允许使用`tf.Tensor`作为Python`bool` - TensorFlow: TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed TypeError(&quot;不允许使用 `tf.Tensor` 作为 Python `bool`。&quot; - TypeError("Using a `tf.Tensor` as a Python `bool` is not allowed. " 不允许将“ tf.Tensor”用作Python“ bool”。 - Using a `tf.Tensor` as a Python `bool` is not allowed. 在数据集上调用地图函数时,“ TypeError:不允许将tf.Tensor作为Python bool使用。” - “TypeError: Using a `tf.Tensor` as a Python `bool` is not allowed.” when calling map function on dataset
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM