IntegerLookup 層

[原始碼]

IntegerLookup 類別

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。但是,在 eager 模式下執行時,它可以與任何後端一起使用。它也始終可以用作任何後端的輸入預處理管線的一部分(在模型本身之外),這是我們建議使用此層的方式。

注意: 此層可以安全地在 tf.data 管線內使用(與您使用的後端無關)。

引數

  • max_tokens:此層詞彙的最大大小。這應該僅在調整詞彙或設定 pad_to_max_tokens=True 時指定。如果為 None,則詞彙大小沒有上限。請注意,此大小包含 OOV 和遮罩符記。預設值為 None
  • num_oov_indices:要使用的詞彙外 (OOV) 符記的數量。如果此值大於 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:詞彙詞彙的 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" 輸出,支援任何形狀的輸入和輸出。對於所有其他輸出模式,目前僅支援最多 rank 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]])  # Note OOV tokens
>>> 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])  # Note OOV tokens
>>> 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]])  # Note OOV tokens
>>> layer = IntegerLookup(vocabulary=vocab, output_mode='multi_hot')
>>> layer(data)
array([[0., 1., 0., 1., 1.],
       [1., 0., 1., 0., 1.]], dtype=float32)

符記計數輸出

使用 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]])  # Note OOV tokens
>>> 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]])  # Note OOV tokens
>>> 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]])  # Note OOV tokens
>>> 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。此外,請注意,為了使反向查找工作,您必須已直接或透過在呼叫 get_vocabulary() 之前設定正向層詞彙。