整数查找层

[source]

IntegerLookup class

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,
    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: 仅在invertTrue时使用.用于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().