IntegerLookup
类tf_keras.layers.IntegerLookup(
max_tokens=None,
num_oov_indices=1,
mask_token=None,
oov_token=-1,
vocabulary=None,
vocabulary_dtype="int64",
idf_weights=None,
invert=False,
output_mode="int",
sparse=False,
pad_to_max_tokens=False,
**kwargs
)
一个预处理层,用于将整数特征映射到连续范围。
此层通过基于表的词汇表查找,将一组任意的整数输入标记映射到索引化的整数输出。即使输入标记不连续或无界,该层的输出索引也将连续排列,直至达到最大词汇表大小。该层通过 output_mode
支持多种输出编码选项,并可选择支持词汇表外 (OOV) 标记和掩码。
该层的词汇表必须在构造时提供或通过 adapt()
学习。在 adapt()
期间,该层将分析数据集,确定单个整数标记的频率,并从中创建词汇表。如果词汇表大小有上限,则将使用最频繁的标记创建词汇表,其余标记将被视为 OOV。
该层有两种可能的输出模式。当 output_mode
为 "int"
时,输入整数会转换为其在词汇表中的索引(一个整数)。当 output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时,输入整数被编码成一个数组,其中每个维度对应于词汇表中的一个元素。
词汇表可选择包含一个掩码标记以及一个 OOV 标记(根据 num_oov_indices
的设置,OOV 标记可选择占用词汇表中的多个索引)。这些标记在词汇表中的位置是固定的。当 output_mode
为 "int"
时,词汇表将以索引 0 处的掩码标记开始,后跟 OOV 索引,再后跟词汇表的其余部分。当 output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时,词汇表将以 OOV 索引开始,输入中的掩码标记实例将被丢弃。
有关预处理层的概述和完整列表,请参阅预处理指南。
参数
pad_to_max_tokens=True
时指定。如果为 None,则词汇表大小没有上限。请注意,此大小包含 OOV 和掩码标记。默认为 None
。1
。output_mode
为 "int"
时,该标记包含在词汇表中并映射到索引 0。在其他输出模式下,该标记不会出现在词汇表中,输入中的掩码标记实例将被丢弃。如果设置为 None,则不会添加掩码项。默认为 None
。invert
为 True 时使用。用于 OOV 索引返回的标记。默认为 -1
。adapt()
。"int64"
或 "int32"
。默认为 "int64"
。output_mode
为 "tf_idf"
时有效。与词汇表长度相同的元组、列表、一维 numpy 数组或一维张量,包含浮点逆文档频率权重,这些权重将与每个样本的项计数相乘,得到最终的 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"
类似,但整数数组包含该索引处的标记在样本中出现的次数计数。"tf_idf"
: 与 "multi_hot"
类似,但应用 TF-IDF 算法来查找每个标记槽中的值。对于 "int"
输出,支持任何形状的输入和输出。对于所有其他输出模式,目前仅支持秩为 2 的输出。默认为 "int"
。output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时适用。如果为 True,即使词汇表中的唯一标记数量少于 max_tokens,输出的特征轴也会填充到 max_tokens
,从而无论词汇表大小如何,都会得到形状为 [batch_size, max_tokens] 的张量。默认为 False。output_mode
为 "multi_hot"
、"count"
或 "tf_idf"
时适用。如果为 True,则返回 SparseTensor
而不是密集 Tensor
。默认为 False
。示例
使用已知词汇表创建查找层
此示例使用预先存在的词汇表创建一个查找层。
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([[12, 1138, 42], [42, 1000, 36]]) # Note OOV tokens
>>> layer = tf.keras.layers.IntegerLookup(vocabulary=vocab)
>>> layer(data)
<tf.Tensor: shape=(2, 3), dtype=int64, numpy=
array([[1, 3, 4],
[4, 0, 2]])>
使用适应性词汇表创建查找层
此示例创建一个查找层,并通过分析数据集生成词汇表。
>>> data = tf.constant([[12, 1138, 42], [42, 1000, 36]])
>>> layer = tf.keras.layers.IntegerLookup()
>>> layer.adapt(data)
>>> layer.get_vocabulary()
[-1, 42, 1138, 1000, 36, 12]
注意,OOV 标记 -1 已添加到词汇表中。其余标记按频率排序(出现 2 次的 42 在前),然后按逆序排序。
>>> data = tf.constant([[12, 1138, 42], [42, 1000, 36]])
>>> layer = tf.keras.layers.IntegerLookup()
>>> layer.adapt(data)
>>> layer(data)
<tf.Tensor: shape=(2, 3), dtype=int64, numpy=
array([[5, 2, 1],
[1, 3, 4]])>
使用多个 OOV 索引进行查找
此示例演示如何使用具有多个 OOV 索引的查找层。当创建一个具有多个 OOV 索引的层时,任何 OOV 标记都会被哈希到相应数量的 OOV 桶中,以确定性的方式在集合中分布 OOV 标记。
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([[12, 1138, 42], [37, 1000, 36]])
>>> layer = tf.keras.layers.IntegerLookup(
... vocabulary=vocab, num_oov_indices=2)
>>> layer(data)
<tf.Tensor: shape=(2, 3), dtype=int64, numpy=
array([[2, 4, 5],
[1, 0, 3]])>
请注意,OOV 标记 37 的输出为 1,而 OOV 标记 1000 的输出为 0。词汇表中的项的输出索引比前面的示例增加了 1(12 映射到 2 等),以便为额外的 OOV 标记腾出空间。
独热(One-hot)输出
使用 output_mode='one_hot'
配置层。注意,独热编码中的前 num_oov_indices
个维度表示 OOV 值。
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([12, 36, 1138, 42, 7]) # Note OOV tokens
>>> layer = tf.keras.layers.IntegerLookup(
... vocabulary=vocab, output_mode='one_hot')
>>> layer(data)
<tf.Tensor: shape=(5, 5), dtype=float32, numpy=
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=float32)>
多热(Multi-hot)输出
使用 output_mode='multi_hot'
配置层。注意,多热编码中的前 num_oov_indices
个维度表示 OOV 标记。
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # Note OOV tokens
>>> layer = tf.keras.layers.IntegerLookup(
... vocabulary=vocab, output_mode='multi_hot')
>>> layer(data)
<tf.Tensor: shape=(2, 5), dtype=float32, numpy=
array([[0., 1., 0., 1., 1.],
[1., 0., 1., 0., 1.]], dtype=float32)>
标记计数输出
使用 output_mode='count'
配置层。与多热输出一样,输出中的前 num_oov_indices
个维度表示 OOV 标记。
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # Note OOV tokens
>>> layer = tf.keras.layers.IntegerLookup(
... vocabulary=vocab, output_mode='count')
>>> layer(data)
<tf.Tensor: shape=(2, 5), dtype=float32, numpy=
array([[0., 1., 0., 1., 2.],
[2., 0., 1., 0., 1.]], dtype=float32)>
TF-IDF 输出
使用 output_mode='tf_idf'
配置层。与多热输出一样,输出中的前 num_oov_indices
个维度表示 OOV 标记。
每个标记箱(bin)将输出 token_count * idf_weight
,其中 idf 权重是每个标记的逆文档频率权重。这些权重应与词汇表一起提供。请注意,OOV 标记的 idf_weight
默认为传入的所有 idf 权重的平均值。
>>> vocab = [12, 36, 1138, 42]
>>> idf_weights = [0.25, 0.75, 0.6, 0.4]
>>> data = tf.constant([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # Note OOV tokens
>>> layer = tf.keras.layers.IntegerLookup(
... output_mode='tf_idf', vocabulary=vocab, idf_weights=idf_weights)
>>> layer(data)
<tf.Tensor: shape=(2, 5), dtype=float32, numpy=
array([[0. , 0.25, 0. , 0.6 , 0.8 ],
[1.0 , 0. , 0.75, 0. , 0.4 ]], dtype=float32)>
要为 OOV 标记指定 idf 权重,您需要传递完整的词汇表,包括开头的 OOV 标记。
>>> vocab = [-1, 12, 36, 1138, 42]
>>> idf_weights = [0.9, 0.25, 0.75, 0.6, 0.4]
>>> data = tf.constant([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # Note OOV tokens
>>> layer = tf.keras.layers.IntegerLookup(
... output_mode='tf_idf', vocabulary=vocab, idf_weights=idf_weights)
>>> layer(data)
<tf.Tensor: shape=(2, 5), dtype=float32, numpy=
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))
。
反向查找
此示例演示如何使用此层将索引映射到标记。(您也可以使用带有 inverse=True
的 adapt()
,但为简单起见,在此示例中我们将直接传递词汇表。)
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([[1, 3, 4], [4, 0, 2]])
>>> layer = tf.keras.layers.IntegerLookup(vocabulary=vocab, invert=True)
>>> layer(data)
<tf.Tensor: shape=(2, 3), dtype=int64, numpy=
array([[ 12, 1138, 42],
[ 42, -1, 36]])>
注意,默认情况下,第一个索引对应于 oov 标记。
正向和反向查找对
此示例演示如何使用标准查找层的词汇表来创建反向查找层。
>>> vocab = [12, 36, 1138, 42]
>>> data = tf.constant([[12, 1138, 42], [42, 1000, 36]])
>>> layer = tf.keras.layers.IntegerLookup(vocabulary=vocab)
>>> i_layer = tf.keras.layers.IntegerLookup(
... vocabulary=layer.get_vocabulary(), invert=True)
>>> int_data = layer(data)
>>> i_layer(int_data)
<tf.Tensor: shape=(2, 3), dtype=int64, numpy=
array([[ 12, 1138, 42],
[ 42, -1, 36]])>
在此示例中,输入标记 1000 的输出为 -1,因为 1000 不在词汇表中 - 它被表示为 OOV,并且所有 OOV 标记在反向层中都返回 -1。此外,请注意,要使反向查找起作用,您必须在调用 get_vocabulary()
之前直接或通过 adapt()
设置正向层的词汇表。