[英]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.