IntegerLookup
classkeras.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,
name=None,
**kwargs
)
一个预处理层,将整数映射到(可能编码的)索引.
该层通过基于表格的词汇表查找,将一组任意的整数输入标记映射到索引化的整数输出.层的输出索引将连续排列到最大词汇表大小,即使输入标记是非连续或无界的.该层支持多种输出编码选项,通过output_mode
,并可选支持词汇表外的(OOV)标记和掩码.
层的词汇表必须在构造时提供或在adapt()
时学习.在adapt()
期间,层将分析数据集,确定单个整数标记的频率,并从中创建词汇表.如果词汇表大小受限,最频繁的标记将被用于创建词汇表,所有其他标记将被视为OOV.
层有两种可能的输出模式.当output_mode
为"int"
时,输入整数被转换为词汇表中的索引(一个整数).当output_mode
为"multi_hot"
、"count"
或"tf_idf"
时,输入整数被编码到一个数组中,每个维度对应词汇表中的一个元素.
词汇表可以选择包含一个掩码标记和一个OOV标记(可以可选地占据词汇表中的多个索引,如num_oov_indices
所设置).这些标记在词汇表中的位置是固定的.当output_mode
为"int"
时,词汇表将以掩码标记在索引0开始,接着是OOV索引,然后是其余的词汇表.当output_mode
为"multi_hot"
、"count"
或"tf_idf"
时,词汇表将以OOV索引开始,掩码标记的实例将被丢弃.
注意: 该层在内部使用TensorFlow.它不能用作任何后端而不是TensorFlow的模型编译计算图的一部分.然而,当运行 eagerly 时,它可以与任何后端一起使用.它也可以始终作为输入预处理管道的一部分与任何后端一起使用(在模型本身之外),这是我们推荐使用此层的方式.
注意: 该层在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索引的标记.默认为-1
.
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
.
示例:
使用已知词汇表创建查找层
此示例创建一个具有预先存在词汇表的查找层.
>>> vocab = [12, 36, 1138, 42]
>>> data = np.array([[12, 1138, 42], [42, 1000, 36]]) # 注意OOV标记
>>> layer = IntegerLookup(vocabulary=vocab)
>>> layer(data)
array([[1, 3, 4],
[4, 0, 2]])
使用适应的词汇表创建查找层
此示例创建一个查找层并通过分析数据集生成词汇表.
>>> data = np.array([[12, 1138, 42], [42, 1000, 36]])
>>> layer = IntegerLookup()
>>> layer.adapt(data)
>>> layer.get_vocabulary()
[-1, 42, 1138, 1000, 36, 12]
注意,OOV标记-1已添加到词汇表中.剩余的标记按频率排序(出现2次的42排在第一位)然后按逆序排序.
>>> data = np.array([[12, 1138, 42], [42, 1000, 36]])
>>> layer = IntegerLookup()
>>> layer.adapt(data)
>>> layer(data)
array([[5, 2, 1],
[1, 3, 4]])
使用多个OOV索引的查找
此示例演示如何使用具有多个OOV索引的查找层.当一个层创建时具有多个OOV索引,任何OOV标记将被哈希到多个OOV桶中,以确定性地分布OOV标记.
>>> vocab = [12, 36, 1138, 42]
>>> data = np.array([[12, 1138, 42], [37, 1000, 36]])
>>> layer = IntegerLookup(vocabulary=vocab, num_oov_indices=2)
>>> layer(data)
array([[2, 4, 5],
[1, 0, 3]])
注意,OOV标记37的输出为1,而OOV标记1000的输出为0.词汇表中的术语输出索引比前面的示例增加了1(12映射到2等),以便为额外的OOV标记腾出空间.
One-hot输出
使用output_mode='one_hot'
配置层.注意,one_hot编码中的前num_oov_indices
维度表示OOV值.
>>> vocab = [12, 36, 1138, 42]
>>> data = np.array([12, 36, 1138, 42, 7]) # 注意OOV标记
>>> layer = IntegerLookup(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=float32)
Multi-hot输出
使用output_mode='multi_hot'
配置层.注意,multi_hot编码中的前num_oov_indices
维度表示OOV标记.
>>> vocab = [12, 36, 1138, 42]
>>> data = np.array([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # 注意OOV标记
>>> layer = IntegerLookup(vocabulary=vocab, output_mode='multi_hot')
>>> layer(data)
array([[0., 1., 0., 1., 1.],
[1., 0., 1., 0., 1.]], dtype=float32)
Token计数输出
使用output_mode='count'
配置层.与multi_hot输出一样,输出的前num_oov_indices
维度表示OOV标记.
>>> vocab = [12, 36, 1138, 42]
>>> data = np.array([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # 注意OOV标记
>>> layer = IntegerLookup(vocabulary=vocab, output_mode='count')
>>> layer(data)
array([[0., 1., 0., 1., 2.],
[2., 0., 1., 0., 1.]], dtype=float32)
TF-IDF输出
使用output_mode='tf_idf'
配置层.与multi_hot输出一样,输出的前num_oov_indices
维度表示OOV标记.
每个标记箱将输出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 = np.array([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # 注意OOV标记
>>> layer = IntegerLookup(
... output_mode='tf_idf', 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 = [-1, 12, 36, 1138, 42]
>>> idf_weights = [0.9, 0.25, 0.75, 0.6, 0.4]
>>> data = np.array([[12, 1138, 42, 42],
... [42, 7, 36, 7]]) # 注意OOV标记
>>> layer = IntegerLookup(
... output_mode='tf_idf', 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 = [12, 36, 1138, 42]
>>> data = np.array([[1, 3, 4], [4, 0, 2]])
>>> layer = IntegerLookup(vocabulary=vocab, invert=True)
>>> layer(data)
array([[ 12, 1138, 42],
[ 42, -1, 36]])
注意,第一个索引默认对应OOV标记.
正向和逆向查找对
此示例演示如何使用标准查找层的词汇表创建逆向查找层.
>>> vocab = [12, 36, 1138, 42]
>>> data = np.array([[12, 1138, 42], [42, 1000, 36]])
>>> layer = IntegerLookup(vocabulary=vocab)
>>> i_layer = IntegerLookup(
... vocabulary=layer.get_vocabulary(), invert=True)
>>> int_data = layer(data)
>>> i_layer(int_data)
array([[ 12, 1138, 42],
[ 42, -1, 36]])
在此示例中,输入标记1000的输出为-1,因为1000不在词汇表中——它被表示为OOV,所有OOV标记在逆向层中返回为-1.还要注意,为了逆向工作,您必须已经直接或通过adapt()
设置了正向层的词汇表,然后调用get_vocabulary()
.