Keras 2 API文档 / Layers API / 预处理 Layer / 文本预处理 / TextVectorization layer

TextVectorization 层

[源代码]

TextVectorization

tf_keras.layers.TextVectorization(
    max_tokens=None,
    standardize="lower_and_strip_punctuation",
    split="whitespace",
    ngrams=None,
    output_mode="int",
    output_sequence_length=None,
    pad_to_max_tokens=False,
    vocabulary=None,
    idf_weights=None,
    sparse=False,
    ragged=False,
    encoding="utf-8",
    **kwargs
)

一个预处理层,将文本特征映射到整数序列。

该层提供了管理 TF-Keras 模型中文本的基本选项。它将一批字符串(一个示例 = 一个字符串)转换为一个令牌索引列表(一个示例 = 整数令牌索引的一维张量)或一个密集表示(一个示例 = 代表示例令牌数据的浮点值的一维张量)。该层旨在处理自然语言输入。要处理简单的字符串输入(分类字符串或预分词字符串),请参阅 tf.keras.layers.StringLookup

该层的词汇表必须在构造时提供,或者通过 adapt() 学习。当该层被适配时,它将分析数据集,确定单个字符串值的频率,并从中创建词汇表。根据该层的配置选项,此词汇表的大小可以是无限的,也可以是有限制的;如果输入中的唯一值多于最大词汇表大小,则将使用最频繁的术语来创建词汇表。

每个示例的处理包含以下步骤:

  1. 标准化每个示例(通常是转换为小写 + 剥离标点符号)
  2. 将每个示例拆分为子字符串(通常是单词)
  3. 将子字符串重组为令牌(通常是 ngrams)
  4. 为令牌建立索引(为每个令牌关联一个唯一的整数值)
  5. 使用此索引转换每个示例,将其转换为整数向量或密集浮点向量。

关于将可调用对象传递给此层以自定义拆分和标准化的注意事项

  1. 任何可调用对象都可以传递给此层,但如果您想序列化此对象,则只能传递已注册为 Keras 可序列化对象的可调用对象(有关更多详细信息,请参阅 tf.keras.saving.register_keras_serializable)。
  2. 当使用自定义可调用对象进行 standardize 时,可调用对象接收的数据将与传递给此层的完全相同。可调用对象应返回与输入形状相同的张量。
  3. 当使用自定义可调用对象进行 split 时,可调用对象接收的数据将去除第一个维度——而不是 [["string to split"], ["another string to split"]],可调用对象将看到 ["string to split", "another string to split"]。可调用对象应返回一个张量,其第一个维度包含拆分后的令牌——在此示例中,我们应该看到类似 [["string", "to", "split"], ["another", "string", "to", "split"]] 的内容。这使得该可调用对象在本地与 tf.strings.split() 兼容。

有关预处理层的概述和完整列表,请参阅预处理 指南

参数

  • max_tokens:此层的词汇表的最大大小。仅当适配词汇表或设置 pad_to_max_tokens=True 时才应指定此参数。请注意,此词汇表包含 1 个 OOV 令牌,因此有效令牌数为 (max_tokens - 1 - (1 if output_mode == "int" else 0))
  • standardize:可选的标准化规范,将应用于输入文本。值可以是:
    • None:不进行标准化。
    • "lower_and_strip_punctuation":文本将被转换为小写并去除所有标点符号。
    • "lower":文本将被转换为小写。
    • "strip_punctuation":所有标点符号将被去除。
    • Callable:输入将被传递给可调用函数,该函数应进行标准化并返回。
  • split:可选的拆分输入文本的规范。值可以是:
    • None:不进行拆分。
    • "whitespace":按空格拆分。
    • "character":按每个 Unicode 字符拆分。
    • Callable:标准化后的输入将被传递给可调用函数,该函数应进行拆分并返回。
  • ngrams:可选的 ngrams 规范,用于从可能已拆分的输入文本创建。值可以是 None、一个整数或整数元组;传递一个整数将创建高达该整数的 ngrams,传递一个整数元组将为元组中指定的 ngrams 值创建 ngrams。传递 None 表示不创建 ngrams。
  • output_mode:可选的输出模式规范,值为 "int""multi_hot""count""tf_idf",将层配置为如下:
    • "int":输出整数索引,每个拆分字符串令牌一个整数索引。当 output_mode == "int" 时,0 保留用于掩码位置;这会将词汇表大小减少到 max_tokens - 2,而不是 max_tokens - 1
    • "multi_hot":为每个批次输出一个单一的整数数组,大小为 vocab_size 或 max_tokens,包含令牌映射到该索引的元素中的 1(只要该令牌在批次项中至少出现一次)。
    • "count":类似于 "multi_hot",但整数数组包含该索引处的令牌在批次项中出现的次数。
    • "tf_idf":类似于 "multi_hot",但 TF-IDF 算法用于查找每个令牌槽中的值。对于 "int" 输出,支持任何形状的输入和输出。对于所有其他输出模式,目前仅支持秩为 1 的输入(拆分后支持秩为 2 的输出)。
  • output_sequence_length:仅在 INT 模式下有效。如果设置,输出的时间维度将被填充或截断为恰好 output_sequence_length 个值,导致张量的形状为 (batch_size, output_sequence_length),无论拆分步骤产生了多少令牌。默认为 None
  • pad_to_max_tokens:仅在 "multi_hot""count""tf_idf" 模式下有效。如果为 True,则即使词汇表中唯一令牌的数量小于 max_tokens,输出的特征轴也将被填充到 max_tokens,导致张量的形状为 (batch_size, max_tokens),而与词汇表大小无关。默认为 False
  • vocabulary:可选。可以是字符串数组或指向文本文件的字符串路径。如果传递数组,可以传递元组、列表、一维 numpy 数组或包含字符串词汇表术语的一维张量。如果传递文件路径,文件应包含词汇表中每行的术语。如果设置了此参数,则无需 adapt() 该层。
  • idf_weights:仅当 output_mode"tf_idf" 时有效。一个元组、列表、一维 numpy 数组或与词汇表长度相同的 1D 张量,包含浮点逆文档频率权重,这些权重将与每个样本的词项计数相乘以获得最终的 tf_idf 权重。如果设置了 vocabulary 参数,并且 output_mode"tf_idf",则必须提供此参数。
  • ragged:布尔值。仅适用于 "int" 输出模式。如果为 True,则返回 RaggedTensor 而不是密集 Tensor,其中每个序列在字符串拆分后可能具有不同的长度。默认为 False
  • sparse:布尔值。仅适用于 "multi_hot""count""tf_idf" 输出模式。如果为 True,则返回 SparseTensor 而不是密集 Tensor。默认为 False
  • encoding:可选。用于解释输入字符串的文本编码。默认为 "utf-8"

示例

此示例实例化了一个 TextVectorization 层,该层将文本转换为小写、按空格拆分、去除标点符号,并输出整数词汇表索引。

>>> text_dataset = tf.data.Dataset.from_tensor_slices(["foo", "bar", "baz"])
>>> max_features = 5000  # Maximum vocab size.
>>> max_len = 4  # Sequence length to pad the outputs to.
>>>
>>> # Create the layer.
>>> vectorize_layer = tf.keras.layers.TextVectorization(
...  max_tokens=max_features,
...  output_mode='int',
...  output_sequence_length=max_len)
>>>
>>> # Now that the vocab layer has been created, call `adapt` on the
>>> # text-only dataset to create the vocabulary. You don't have to batch,
>>> # but for large datasets this means we're not keeping spare copies of
>>> # the dataset.
>>> vectorize_layer.adapt(text_dataset.batch(64))
>>>
>>> # Create the model that uses the vectorize text layer
>>> model = tf.keras.models.Sequential()
>>>
>>> # Start by creating an explicit input layer. It needs to have a shape of
>>> # (1,) (because we need to guarantee that there is exactly one string
>>> # input per batch), and the dtype needs to be 'string'.
>>> model.add(tf.keras.Input(shape=(1,), dtype=tf.string))
>>>
>>> # The first layer in our model is the vectorization layer. After this
>>> # layer, we have a tensor of shape (batch_size, max_len) containing
>>> # vocab indices.
>>> model.add(vectorize_layer)
>>>
>>> # Now, the model can map strings to integers, and you can add an
>>> # embedding layer to map these integers to learned embeddings.
>>> input_data = [["foo qux bar"], ["qux baz"]]
>>> model.predict(input_data)
array([[2, 1, 4, 0],
       [1, 3, 0, 0]])

示例

此示例通过将词汇表术语列表传递给该层的 __init__() 方法来实例化一个 TextVectorization 层。

>>> vocab_data = ["earth", "wind", "and", "fire"]
>>> max_len = 4  # Sequence length to pad the outputs to.
>>>
>>> # Create the layer, passing the vocab directly. You can also pass the
>>> # vocabulary arg a path to a file containing one vocabulary word per
>>> # line.
>>> vectorize_layer = tf.keras.layers.TextVectorization(
...  max_tokens=max_features,
...  output_mode='int',
...  output_sequence_length=max_len,
...  vocabulary=vocab_data)
>>>
>>> # Because we've passed the vocabulary directly, we don't need to adapt
>>> # the layer - the vocabulary is already set. The vocabulary contains the
>>> # padding token ('') and OOV token ('[UNK]') as well as the passed
>>> # tokens.
>>> vectorize_layer.get_vocabulary()
['', '[UNK]', 'earth', 'wind', 'and', 'fire']