StringLookup
classkeras.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 标记(该标记可以可选地占据词汇表中的多个索引,如 num_oov_indices
所设置).这些标记在词汇表中的位置是固定的.当 output_mode
为 "int"
时,词汇表将以掩码标记(如果设置)开始,接着是 OOV 索引,然后是其余的词汇表.当 output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时,词汇表将以 OOV 索引开始,掩码标记的实例将被丢弃.
注意: 该层在内部使用 TensorFlow.它不能用于任何后端而不是 TensorFlow 的编译计算图模型的部分.然而,它可以在任何后端运行时使用.它也可以始终作为输入预处理管道的一部分与任何后端一起使用(在模型本身之外),这是我们推荐使用该层的方式.
注意: 该层在 tf.data
管道中使用是安全的(与您使用的后端无关).
参数:
max_tokens: 该层词汇表的最大大小.这仅在适应词汇表或设置 pad_to_max_tokens=True
时指定.如果为 None,则词汇表的大小没有上限.请注意,此大小包括 OOV 和掩码标记.默认为 None
.
num_oov_indices: 要使用的词汇表外标记的数量.如果此值大于 1,OOV 输入将被调制以确定其 OOV 值.如果此值为 0,调用层时 OOV 输入将导致错误.默认为 1
.
mask_token: 表示掩码输入的标记.当 output_mode
为 "int"
时,标记包含在词汇表中并映射到索引 0.在其他输出模式中,标记不会出现在词汇表中,输入中的掩码标记实例将被丢弃.如果设置为 None
,则不会添加掩码项.默认为 None
.
oov_token: 仅在 invert
为 True 时使用.用于 OOV 索引的标记.默认为 "[UNK]"
.
vocabulary: 可选.可以是整数数组或文本文件的路径.如果传递数组,可以传递元组、列表、1D NumPy 数组或 1D 张量,包含整数词汇表项.如果传递文件路径,文件应每行包含一个词汇表项.如果设置了此参数,则无需 adapt()
层.
vocabulary_dtype: 词汇表项的数据类型,例如 "int64"
或 "int32"
.默认为 "int64"
.
idf_weights: 仅在 output_mode
为 "tf_idf"
时有效.一个元组、列表、1D NumPy 数组或 1D 张量,长度与词汇表相同,包含浮点逆文档频率权重,这些权重将与每个样本项计数相乘以获得最终的 TF-IDF 权重.如果设置了 vocabulary
参数且 output_mode
为 "tf_idf"
,则必须提供此参数.
invert: 仅在 output_mode
为 "int"
时有效.如果为 True
,该层将映射索引到词汇表项,而不是映射词汇表项到索引.默认为 False
.
output_mode: 层的输出规范.值可以是 "int"
、"one_hot"
、"multi_hot"
、"count"
或 "tf_idf"
,配置层如下:
- "int"
:返回输入标记的词汇表索引.
- "one_hot"
:将输入中的每个单独元素编码为与词汇表大小相同的数组,包含元素索引处的 1.如果最后一个维度大小为 1,将在该维度上编码.如果最后一个维度不是大小 1,将追加一个新维度以进行编码输出.
- "multi_hot"
:将输入中的每个样本编码为单个与词汇表大小相同的数组,包含样本中每个词汇表项存在的 1.将最后一个维度视为样本维度,如果输入形状为 (..., sample_length)
,输出形状将为 (..., num_tokens)
.
- "count"
:与 "multi_hot"
类似,但整数数组包含标记在该索引处出现的次数.
- "tf_idf"
:与 "multi_hot"
类似,但应用 TF-IDF 算法以找到每个标记槽中的值.
对于 "int"
输出,支持任何形状的输入和输出.对于所有其他输出模式,目前仅支持最多秩为 2 的输出.默认为 "int"
.
pad_to_max_tokens: 仅在 output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时适用.如果为 True
,输出将在特征轴上填充到 max_tokens
,即使词汇表中唯一标记的数量少于 max_tokens
,结果张量形状为 (batch_size, max_tokens)
,与词汇表大小无关.默认为 False
.
sparse: 布尔值.仅适用于 "multi_hot"
、"count"
和 "tf_idf"
输出模式.仅支持 TensorFlow 后端.如果为 True
,返回 SparseTensor
而不是密集 Tensor
.默认为 False
.
encoding: 可选.用于解释输入字符串的文本编码.默认为 "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]"
已添加到词汇表中.剩余的标记按频率排序(出现 2 次的 "d"
排在第一位),然后按逆序排序.
>>> 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.在词汇表中的项的输出索引比前面的示例增加了 1(a 映射到 2 等),以便为额外的 OOV 值腾出空间.
独热输出
使用 output_mode='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)
多热输出
使用 output_mode='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'
配置层.与多热输出一样,输出的前 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"
配置层.与多热输出一样,输出的前 num_oov_indices
维度表示 OOV 值.
每个标记 bin 将输出 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]"
.另请注意,为了逆向工作,您必须已经设置了正向层词汇表,无论是直接设置还是通过 adapt()
设置,然后再调用 get_vocabulary()
.