Python 如何在TensorFlow数据集上正确使用tf.function

Python 如何在TensorFlow数据集上正确使用tf.function,python,tensorflow,tensorflow2.0,Python,Tensorflow,Tensorflow2.0,我试图使用带有@TF.function的TF数据集对图像目录执行一些预处理。在tf函数中,图像文件被读取为原始字符串张量,我试图从该张量中获取一个切片。前13个字符表示关于.ppm图像的信息(标题)。我得到一个错误:ValueError:Shape必须是秩1,但对于输入形状为[]、[1]、[1]的“切片”(op:'Slice'),它的秩0。起初,我试图直接切分tensor的.numpy()属性(filepathtf函数的输入参数),但我认为在tf函数中这样做在语义上是错误的。它也不起作用,因为文

我试图使用带有@TF.function的TF数据集对图像目录执行一些预处理。在tf函数中,图像文件被读取为原始字符串张量,我试图从该张量中获取一个切片。前13个字符表示关于.ppm图像的信息(标题)。我得到一个错误:
ValueError:Shape必须是秩1,但对于输入形状为[]、[1]、[1]
的“切片”(op:'Slice'),它的秩0。起初,我试图直接切分tensor的.numpy()属性(
filepath
tf函数的输入参数),但我认为在tf函数中这样做在语义上是错误的。它也不起作用,因为
文件路径
输入张量没有numpy()属性(我不明白为什么??)。在tf函数之外,例如在jupyter笔记本单元中,我可以迭代数据集,获取具有numpy属性的单个项目,并对其执行切片和所有后续处理。我确实意识到我对TF工作原理的理解可能存在差距(我正在使用TF2.0),因此我希望有人能澄清我在阅读中遗漏的内容。tf函数的目的是将ppm图像转换为png,因此该函数有一个副作用,但我没有深入了解这是否可行

代码如下:

@tf.function
def ppm_to_png(filepath):
    ppm_bytes = tf.io.read_file(filepath) #.numpy()
    bytes_header = tf.slice(ppm_bytes, [0], [13])
    # bytes_header = ppm_bytes[:13].eval()  # this did not work either with similar error msg
    .
    .
    .

要在TF中操作字符串值,请查看

在这种情况下,可以使用
tf.strings.substr

@tf.function
def ppm_to_png(filepath):
  ppm_bytes = tf.io.read_file(filepath)
  bytes_header = tf.strings.substr(ppm_bytes, 0, 13)
  tf.print(bytes_header)

tf.slice
仅对张量对象进行操作,而不对其元素进行操作。这里,
ppm_bytes
是一个标量张量,包含类型为
tf.string
的单个元素,其值是文件的整个字符串内容。因此,当您调用
tf.slice
时,它只查看标量位,并没有足够聪明地意识到您实际上想要获取该元素的切片。

substr工作了,但我仍然得到一个没有numpy属性的张量。我需要标题张量的内容,这样我才能解码它。标题包含字符和整数。如何从张量(bytes\u头)中获取这些值?另外,为什么代码在python中工作,而在我将其用于TF数据集时不工作?我认为现在默认使用的是急切执行,所以TF代码更像Python。。。我不明白为什么ppm_to_png()中的张量没有我可以在函数中使用的numpy属性??numpy()在tf.function中不可用。这并不明显,但数据集总是使用tf.function,即使在急切的执行中也是如此。要获取numpy值并运行任意python,您应该使用-也就是说,编写一个单独的函数,用py_函数包装该函数,并从提供给数据集的函数调用该函数。也就是说,我建议您单独将图像转换为png,然后使用
@tf.function
def ppm_to_png(filepath):
  ppm_bytes = tf.io.read_file(filepath)
  bytes_header = tf.strings.substr(ppm_bytes, 0, 13)
  tf.print(bytes_header)