模型预处理层介绍(1) - Discretization

时间:2023-02-14 17:09:03

预处理的作用主要在于将难以表达的string或者数组转换成模型容易训练的向量表示,其中转化过程大多是形成一张查询表用来查询。

常见的预处理方式包括:

  • class Discretization: Buckets data into discrete ranges.

  • class Hashing: Implements categorical feature hashing, also known as "hashing trick".

  • class IntegerLookup: Maps integers from a vocabulary to integer indices.

  • class Normalization: Feature-wise normalization of the data.

  • class StringLookup: Maps strings from a vocabulary to integer indices.

接下来,本文将介绍下这些常用的预处理方式的作用和内容

Discretization

离散化层。该层将其输入数据的每个元素放入几个连续的范围之一,并输出一个整数索引,指示每个元素位于哪个范围。这个索引也就是索引编号,通过分桶边界值判断输入的数字属于哪个分桶,以此给出桶号。

换句话说,它的作用在于将连续的数值特征转换为整数分类特征。

在2.5版本的tf当中,该层的入参只有一个分桶边界bins,用法为:

tf.keras.layers.experimental.preprocessing.Discretization(
    bins, **kwargs
)

在2.11版本的tf当中,Discretization层被定义为

tf.keras.layers.Discretization(
    bin_boundaries=None,
    num_bins=None,
    epsilon=0.01,
    output_mode='int',
    sparse=False,
    **kwargs
)

其中多了一个epsilon,用来作为误差容忍度,通常是一个接近于零的小分数(例如0.01)。较大的epsilon值会增加分位数近似,从而导致更多不相等的桶,但可以提高性能和资源消耗。

另外还多了一个output_mode:

  • "int":直接返回离散化的bin索引。

  • "one_hot":将输入中的每个元素编码到与num_bins大小相同的数组中,在输入的bin索引处包含一个1。如果最后一个维度的大小为1,则对该维度进行编码。如果最后一个维度的大小不是1,则将为编码后的输出追加一个新维度。

  • "multi_hot":将输入中的每个样本编码到与num_bins大小相同的单个数组中,为样本中出现的每个bin索引索引包含一个1。将最后一个维度作为样本维度,如果输入形状为(…, sample_length),输出形状将是(…, num_tokens)。

  • "count":作为"multi_hot",但int数组包含bin索引在示例中出现次数的计数。

举一个现有的官方的例子:

>>> input = np.array([[-1.5, 1.0, 3.4, .5], [0.0, 3.0, 1.3, 0.0]])
>>> layer = tf.keras.layers.experimental.preprocessing.Discretization(
...          bins=[0., 1., 2.])
>>> layer(input)
<tf.Tensor: shape=(2, 4), dtype=int32, numpy=
array([[0, 1, 3, 1],
       [0, 3, 2, 0]], dtype=int32)>

在这个例子中,传入的参数 bins=[0., 1., 2.] 代表着该层以0、1、2 作为数值边界进行分桶,所以整体的查询表大概如下所示:

bin <0 0~1 1~2 >2
index 0 1 2 3

结合着官方的例子,处于边界值上的数值,会被归于前一个桶。比如第一行第二个数字数值为1,会被分桶成编号为1。

其中Discretization层调用了bucket进行分桶

要注意的是,这些层是不可训练的。它们的状态在训练期间没有设置;它必须在训练之前设置,或者通过从预先计算的常数初始化它们,或者通过在数据上“调整”它们。