IntegerLookup 層

[原始碼]

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 設定)。這些標記在詞彙表中的位置是固定的。當 output_mode"int" 時,詞彙表將以索引 0 處的遮罩標記開始,接著是 OOV 索引,然後是詞彙表的其餘部分。當 output_mode"multi_hot""count""tf_idf" 時,詞彙表將以 OOV 索引開始,並且將刪除遮罩標記的實例。

有關預處理層的概述和完整列表,請參閱預處理指南

參數

  • 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:可選。整數陣列或文字檔案的字串路徑。如果傳遞陣列,可以傳遞包含整數詞彙表的元組、列表、一維 numpy 陣列或一維張量。如果傳遞檔案路徑,則檔案每行應包含一個詞彙表項。如果設定此引數,則無需 adapt() 此層。
  • vocabulary_dtype:詞彙表項的 dtype,例如 "int64""int32"。預設值為 "int64"
  • idf_weights:僅當 output_mode"tf_idf" 時有效。與詞彙表長度相同的元組、列表、一維 numpy 陣列或一維張量,其中包含浮點數反向文件頻率權重,該權重將乘以每個樣本詞頻計數,以得到最終的 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:布林值。僅當 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。為了為額外的 OOV 標記騰出空間,詞彙表內的標記的輸出索引從先前的範例中增加了 1(12 映射到 2 等)。

單熱編碼輸出

使用 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)>

多熱編碼輸出

使用 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 標記。

每個標記儲存桶將輸出 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 + 文件總數 / (1 + 詞元文件數))

反向查找

這個範例示範如何使用此圖層將索引映射到詞元。(您也可以使用 adapt() 並設定 inverse=True,但為了簡化,我們將在此範例中直接傳遞詞彙表。)

>>> 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() 設定正向圖層的詞彙表。