Tensorflow 2 - 如何将适配的 TextVectorization 应用于文本数据集

Tensorflow 2 - How to apply adapted TextVectorization to a text dataset

问题

请帮助理解将改编后的 TextVectorization 应用于文本数据集时出现错误的原因。

背景

Introduction to Keras for Engineers 有一部分将经过调整的 TextVectorization 层应用于文本数据集。

from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
training_data = np.array([["This is the 1st sample."], ["And here's the 2nd sample."]])
vectorizer = TextVectorization(output_mode="int")
vectorizer.adapt(training_data)

integer_data = vectorizer(training_data)  # <----- Apply the adapted TextVectorization

问题

尝试通过首先将 TextVectorization 层调整为 PTB 文本,然后将其应用于莎士比亚文本来执行相同的操作。

使 TextVectorization 适应 PTB

f = "ptb.train.txt"
path_to_ptb = tf.keras.utils.get_file(
    str(pathlib.Path().absolute()) + '/' + f,
    f'https://raw.githubusercontent.com/tomsercu/lstm/master/data/{f}'
)

ptb_ds = tf.data.TextLineDataset(
    filenames=path_to_file, compression_type=None, buffer_size=None, num_parallel_reads=True
)\
.filter(lambda x: tf.cast(tf.strings.length(x), bool))\
.shuffle(10000)

from tensorflow.keras.layers.experimental.preprocessing import TextVectorization
vectorizer = TextVectorization(output_mode="int", ngrams=None)
vectorizer.adapt(ptb_ds)

将 TextVectorization 图层应用于莎士比亚文本并出现错误

path_to_shakespeare = tf.keras.utils.get_file(
    'shakespeare.txt', 
    'https://storage.googleapis.com/download.tensorflow.org/data/shakespeare.txt'
)

shakespeare_ds = tf.data.TextLineDataset(path_to_shakespeare)\
    .filter(lambda x: tf.cast(tf.strings.length(x), bool))

shakespeare_vector_ds =\
    vectorizer(shakespeare_ds.batch(128).prefetch(tf.data.AUTOTUNE))  <----- Error

错误

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-48-216442e69438> in <module>
----> 1 shakespeare_vector_ds = vectorizer(shakespeare_ds.batch(128).prefetch(tf.data.AUTOTUNE))
...
alueError: Attempt to convert a value (<PrefetchDataset shapes: (None,), types: tf.string>) with an unsupported type (<class 'tensorflow.python.data.ops.dataset_ops.PrefetchDataset'>) to a Tensor.

解决方案

这有效,但不清楚为什么上面会导致错误,尽管它似乎在做同样的事情。

shakespeare_vector_ds =\
   shakespeare_ds.batch(1024).prefetch(tf.data.AUTOTUNE).map(vectorizer).unbatch()

tf.data.Dataset.map 将函数应用于数据集的每个元素(张量)。 TextVectorization 对象的 __call__ 方法需要一个 Tensor,而不是 tf.data.Dataset 对象。每当您想将函数应用于 tf.data.Dataset 的元素时,您应该使用 map.