StringLookup
类keras.layers.StringLookup(
max_tokens=None,
num_oov_indices=1,
mask_token=None,
oov_token="[UNK]",
vocabulary=None,
idf_weights=None,
invert=False,
output_mode="int",
pad_to_max_tokens=False,
sparse=False,
encoding="utf-8",
name=None,
**kwargs
)
一个预处理层,用于将字符串映射到(可能已编码的)索引。
该层通过基于表格的词汇表查找,将一组任意字符串转换为整数输出。该层不会对输入字符串执行分割或转换。对于可以分割和标记自然语言的层,请参阅 keras.layers.TextVectorization
层。
该层的词汇表必须在构建时提供,或者通过 adapt()
学习。在 adapt()
期间,该层将分析数据集,确定各个字符串标记的频率,并从中创建词汇表。如果词汇表的大小受到限制,则将使用最频繁的标记来创建词汇表,所有其他标记将被视为词汇表外 (OOV)。
该层有两种可能的输出模式。当 output_mode
为 "int"
时,输入字符串将转换为它们在词汇表中的索引(整数)。当 output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时,输入字符串将被编码为一个数组,其中每个维度对应于词汇表中的一个元素。
词汇表可以选择性地包含一个掩码标记以及一个 OOV 标记(OOV 标记可以选择性地占据词汇表中的多个索引,由 num_oov_indices
设置)。这些标记在词汇表中的位置是固定的。当 output_mode
为 "int"
时,词汇表将以掩码标记(如果设置)开始,后跟 OOV 索引,然后是词汇表的其余部分。当 output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时,词汇表将以 OOV 索引开始,并且掩码标记的实例将被删除。
注意: 该层在内部使用 TensorFlow。它不能用作除 TensorFlow 之外的任何后端的模型的编译计算图的一部分。但是,在急切模式下运行时,它可以与任何后端一起使用。它也始终可以用作任何后端的输入预处理管道的一部分(模型本身之外),这是我们建议使用该层的方式。
注意: 该层可以安全地在 tf.data
管道中使用(与您使用的后端无关)。
参数
pad_to_max_tokens=True
时才应指定此项。如果为 None,则词汇表的大小没有上限。请注意,此大小包括 OOV 和掩码标记。默认为 None
。1
。output_mode
为 "int"
时,该标记包含在词汇表中并映射到索引 0。在其他输出模式下,该标记不会出现在词汇表中,并且输入中掩码标记的实例将被删除。如果设置为 None
,则不会添加掩码项。默认为 None
。invert
为 True 时使用。OOV 索引要返回的标记。默认为 "[UNK]"
。adapt()
该层。"int64"
或 "int32"
。默认为 "int64"
。output_mode
为 "tf_idf"
时有效。与词汇表长度相同的元组、列表、1D NumPy 数组或 1D 张量,其中包含浮点逆文档频率权重,该权重将乘以每个样本的术语计数以获得最终的 TF-IDF 权重。如果设置了 vocabulary
参数,并且 output_mode
为 "tf_idf"
,则必须提供此参数。output_mode
为 "int"
时有效。如果为 True
,则此层会将索引映射到词汇表项,而不是将词汇表项映射到索引。默认为 False
。"int"
、"one_hot"
、"multi_hot"
、"count"
或 "tf_idf"
,用于按如下方式配置层"int"
:返回输入标记的词汇表索引。"one_hot"
:将输入中的每个单独元素编码为一个与词汇表大小相同的数组,在该元素索引处包含 1。如果最后一个维度的大小为 1,则将在该维度上进行编码。如果最后一个维度的大小不是 1,则将为编码输出附加一个新维度。"multi_hot"
:将输入中的每个样本编码为一个与词汇表大小相同的数组,其中包含样本中存在的每个词汇表项的 1。将最后一个维度视为样本维度,如果输入形状为 (..., sample_length)
,则输出形状将为 (..., num_tokens)
。"count"
:与 "multi_hot"
相同,但 int 数组包含该索引处的标记在样本中出现的次数计数。"tf_idf"
:与 "multi_hot"
相同,但应用 TF-IDF 算法来查找每个标记槽中的值。对于 "int"
输出,支持任何形状的输入和输出。对于所有其他输出模式,目前仅支持最多 rank 2 的输出。默认为 "int"
。output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时适用。如果为 True
,则即使词汇表中唯一标记的数量少于 max_tokens
,输出的特征轴也将填充到 max_tokens
,从而生成形状为 (batch_size, max_tokens)
的张量,而与词汇表大小无关。默认为 False
。"multi_hot"
、"count"
和 "tf_idf"
输出模式。仅 TensorFlow 后端支持。如果为 True
,则返回 SparseTensor
而不是密集 Tensor
。默认为 False
。"utf-8"
。示例
使用已知词汇表创建查找层
此示例创建一个具有预先存在的词汇表的查找层。
>>> vocab = ["a", "b", "c", "d"]
>>> data = [["a", "c", "d"], ["d", "z", "b"]]
>>> layer = StringLookup(vocabulary=vocab)
>>> layer(data)
array([[1, 3, 4],
[4, 0, 2]])
使用自适应词汇表创建查找层
此示例创建一个查找层,并通过分析数据集生成词汇表。
>>> data = [["a", "c", "d"], ["d", "z", "b"]]
>>> layer = StringLookup()
>>> layer.adapt(data)
>>> layer.get_vocabulary()
['[UNK]', 'd', 'z', 'c', 'b', 'a']
请注意,OOV 标记 "[UNK]"
已添加到词汇表中。其余标记按频率("d"
出现 2 次,排在第一位),然后按反向排序顺序排序。
>>> data = [["a", "c", "d"], ["d", "z", "b"]]
>>> layer = StringLookup()
>>> layer.adapt(data)
>>> layer(data)
array([[5, 3, 1],
[1, 2, 4]])
具有多个 OOV 索引的查找
此示例演示如何使用具有多个 OOV 索引的查找层。当创建一个具有多个 OOV 索引的层时,任何 OOV 值都会被哈希到 OOV 桶的数量中,从而以确定性的方式跨集合分布 OOV 值。
>>> vocab = ["a", "b", "c", "d"]
>>> data = [["a", "c", "d"], ["m", "z", "b"]]
>>> layer = StringLookup(vocabulary=vocab, num_oov_indices=2)
>>> layer(data)
array([[2, 4, 5],
[0, 1, 3]])
请注意,OOV 值“m”的输出为 0,而 OOV 值 "z"
的输出为 1。为了给额外的 OOV 值腾出空间,词汇表内术语的输出索引比之前的示例增加了 1(a 映射到 2,等等)。
One-hot 输出
使用 output_mode='one_hot'
配置该层。请注意,one-hot 编码中的前 num_oov_indices
维度表示 OOV 值。
>>> vocab = ["a", "b", "c", "d"]
>>> data = ["a", "b", "c", "d", "z"]
>>> layer = StringLookup(vocabulary=vocab, output_mode='one_hot')
>>> layer(data)
array([[0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0.],
[0., 0., 0., 1., 0.],
[0., 0., 0., 0., 1.],
[1., 0., 0., 0., 0.]], dtype=int64)
Multi-hot 输出
使用 output_mode='multi_hot'
配置该层。请注意,multi-hot 编码中的前 num_oov_indices
维度表示 OOV 值。
>>> vocab = ["a", "b", "c", "d"]
>>> data = [["a", "c", "d", "d"], ["d", "z", "b", "z"]]
>>> layer = StringLookup(vocabulary=vocab, output_mode='multi_hot')
>>> layer(data)
array([[0., 1., 0., 1., 1.],
[1., 0., 1., 0., 1.]], dtype=int64)
标记计数输出
使用 output_mode='count'
配置该层。与 multi_hot 输出一样,输出中的前 num_oov_indices
维度表示 OOV 值。
>>> vocab = ["a", "b", "c", "d"]
>>> data = [["a", "c", "d", "d"], ["d", "z", "b", "z"]]
>>> layer = StringLookup(vocabulary=vocab, output_mode='count')
>>> layer(data)
array([[0., 1., 0., 1., 2.],
[2., 0., 1., 0., 1.]], dtype=int64)
TF-IDF 输出
使用 output_mode="tf_idf"
配置该层。与 multi_hot 输出一样,输出中的前 num_oov_indices
维度表示 OOV 值。
每个标记箱将输出 token_count * idf_weight
,其中 idf 权重是每个标记的逆文档频率权重。这些应与词汇表一起提供。请注意,OOV 值的 idf_weight
将默认为传入的所有 idf 权重的平均值。
>>> vocab = ["a", "b", "c", "d"]
>>> idf_weights = [0.25, 0.75, 0.6, 0.4]
>>> data = [["a", "c", "d", "d"], ["d", "z", "b", "z"]]
>>> layer = StringLookup(output_mode="tf_idf")
>>> layer.set_vocabulary(vocab, idf_weights=idf_weights)
>>> layer(data)
array([[0. , 0.25, 0. , 0.6 , 0.8 ],
[1.0 , 0. , 0.75, 0. , 0.4 ]], dtype=float32)
要指定 oov 值的 idf 权重,您需要传递整个词汇表,包括前导 oov 标记。
>>> vocab = ["[UNK]", "a", "b", "c", "d"]
>>> idf_weights = [0.9, 0.25, 0.75, 0.6, 0.4]
>>> data = [["a", "c", "d", "d"], ["d", "z", "b", "z"]]
>>> layer = StringLookup(output_mode="tf_idf")
>>> layer.set_vocabulary(vocab, idf_weights=idf_weights)
>>> layer(data)
array([[0. , 0.25, 0. , 0.6 , 0.8 ],
[1.8 , 0. , 0.75, 0. , 0.4 ]], dtype=float32)
当在 "tf_idf"
模式下调整层时,每个输入样本将被视为一个文档,并且每个标记的 IDF 权重将计算为 log(1 + num_documents / (1 + token_document_count))
。
反向查找
此示例演示如何使用此层将索引映射到字符串。(您也可以将 adapt()
与 inverse=True
一起使用,但为了简单起见,我们在此示例中传递词汇表。)
>>> vocab = ["a", "b", "c", "d"]
>>> data = [[1, 3, 4], [4, 0, 2]]
>>> layer = StringLookup(vocabulary=vocab, invert=True)
>>> layer(data)
array([[b'a', b'c', b'd'],
[b'd', b'[UNK]', b'b']], dtype=object)
请注意,默认情况下,第一个索引对应于 oov 标记。
正向和反向查找对
此示例演示如何使用标准查找层的词汇表来创建反向查找层。
>>> vocab = ["a", "b", "c", "d"]
>>> data = [["a", "c", "d"], ["d", "z", "b"]]
>>> layer = StringLookup(vocabulary=vocab)
>>> i_layer = StringLookup(vocabulary=vocab, invert=True)
>>> int_data = layer(data)
>>> i_layer(int_data)
array([[b'a', b'c', b'd'],
[b'd', b'[UNK]', b'b']], dtype=object)
在此示例中,输入值 "z"
导致输出 "[UNK]"
,因为 1000 不在词汇表中 - 它被表示为 OOV,并且所有 OOV 值在反向层中都作为 "[UNK]"
返回。此外,请注意,为了使反向查找工作,您必须在调用 get_vocabulary()
之前直接或通过 adapt()
设置正向层词汇表。