“嵌入”在大語言模型中是解決把句子轉換成向量表示的技術

果冻人工智能發表於2024-11-13

上一篇:《人工智慧是這樣理解“情緒”的》

序言:這段話要最佳化嗎?““嵌入”是一種將句子、單詞或其他語言單位轉換為向量表示的技術。這個向量通常位於高維空間中,它以一種能夠表達相似性的方式編碼出文字的含義或上下文。嵌入層的作用就在於把離散的語言符號(如單詞或句子)轉換成連續的向量,使得模型能更好地理解和處理語言之間的關係。其實我們人類的大腦也是這樣乾的,只是我們自己無法感知而已,我們最終得到的就是某個“記憶”,可以供人類隨時使用的“記憶”也就是特徵,所以讓人工智慧來識別人類說話中包含的情緒也只是將整句話轉換成了向量後才能透過計算得到結論。

在 TensorFlow 人工智慧開發框架中使用“嵌入”層

正如你在 Dense 和 Conv2D 中所見,tf.keras 使用嵌入層來實現嵌入。這會建立一個查詢表,將一個整數對映到一個嵌入表,其中的內容是表示該整數對應單詞的向量係數。例如,在上個章節的《傲慢與偏見》示例中,x 和 y 座標會為我們提供某個書中人物的嵌入。當然,在實際的 NLP 問題中,我們會使用遠多於兩個維度。因此,向量空間中的向量方向可以視為編碼了單詞的“含義”,而那些指向大致相同方向的相似向量所代表的單詞則可以被認為是與該單詞相關的。

嵌入層將被隨機初始化——也就是說,向量的座標一開始是完全隨機的,在訓練過程中透過反向傳播學習得到。當訓練完成時,嵌入會粗略編碼出單詞之間的相似性,使我們可以基於這些單詞的向量方向識別出某種程度上相似的單詞。

這些內容相當抽象,所以我認為理解嵌入的最佳方式是動手實踐。讓我們從使用第五章的諷刺資料集來構建一個諷刺檢測器開始。

使用”嵌入”技術設計一個諷刺情緒檢測器

在第五章中,你載入並對一個名為《諷刺檢測新聞標題資料集》的 JSON 資料集(簡稱諷刺資料集)進行了預處理。處理完成後,你會得到訓練和測試資料及標籤的列表。這些列表可以使用以下程式碼轉換為 TensorFlow 訓練所用的 Numpy 格式:

import numpy as np

training_padded = np.array(training_padded)

training_labels = np.array(training_labels)

testing_padded = np.array(testing_padded)

testing_labels = np.array(testing_labels)

這些資料是透過一個指定了最大詞彙量和詞彙外(OOV)標記的分詞器生成的:

tokenizer = Tokenizer(num_words=vocab_size, oov_token=oov_tok)

要初始化嵌入層,你需要詞彙量大小和指定的嵌入維度:

tf.keras.layers.Embedding(vocab_size, embedding_dim),

這將為每個單詞初始化一個具有 embedding_dim 個點的陣列。比如,如果 embedding_dim 為 16,那麼詞彙表中的每個單詞都會被分配一個 16 維的向量。

隨著時間推移,這些維度將透過反向傳播學習得到,因為網路在學習如何將訓練資料與標籤匹配。

接下來一個重要步驟是將嵌入層的輸出傳遞到一個全連線層。最簡單的方法是像在卷積神經網路中一樣使用池化。在這種情況下,嵌入的維度會被平均化,以產生一個固定長度的輸出向量。

例如,考慮以下模型架構:

model = tf.keras.Sequential([

tf.keras.layers.Embedding(10000, 16),

tf.keras.layers.GlobalAveragePooling1D(),

tf.keras.layers.Dense(24, activation='relu'),

tf.keras.layers.Dense(1, activation='sigmoid')

])

model.compile(loss='binary_crossentropy',

optimizer='adam', metrics=['accuracy'])

這裡定義了一個嵌入層,給定詞彙量大小(10000)和一個 16 維的嵌入。讓我們使用 model.summary 檢視網路中的可訓練引數數量:

Model: "sequential_2"


Layer (type) Output Shape Param #

=================================================================

embedding_2 (Embedding) (None, None, 16) 160000


global_average_pooling1d_2 ( (None, 16) 0


dense_4 (Dense) (None, 24) 408


dense_5 (Dense) (None, 1) 25

=================================================================

Total params: 160,433

Trainable params: 160,433

Non-trainable params: 0


由於嵌入層有一個 10,000 個單詞的詞彙表,且每個單詞將是 16 維的向量,因此總的可訓練引數數將為 160,000。平均池化層的可訓練引數為 0,因為它只是將嵌入層中的引數平均,以獲得一個 16 值的向量。

該向量隨後被輸入到 24 個神經元的全連線層。請記住,一個全連線神經元實際上是透過權重和偏置計算的,因此它將需要學習 (24 × 16) + 16 = 408 個引數。

該層的輸出隨後傳遞到最終的單神經元層,其中將有 (1 × 24) + 1 = 25 個引數需要學習。

如果我們訓練該模型,在 30 個訓練週期(epoch)後,我們可以獲得 99%以上的訓練準確率,但驗證準確率僅為約 81%(圖 6-2)。

這看起來似乎是合理的曲線,因為驗證資料可能包含許多訓練資料中不存在的單詞。然而,如果你檢查 30 個訓練週期中訓練和驗證的損失曲線,就會發現一個問題。儘管你預期訓練準確率高於驗證準確率,但一個明顯的過擬合指標是驗證準確率隨著時間略微下降(在圖 6-2 中),而驗證損失卻急劇增加,如圖 6-3 所示。

像這樣的過擬合在 NLP 模型中很常見,因為語言具有某種不可預測的特性。在接下來的章節中,我們將探討如何使用一些技術來減輕這一影響。

總結:嵌入技術透過將句子或單詞轉化為高維空間中的向量,使模型能更好地理解文字含義和上下文。在 TensorFlow 中,嵌入層透過查詢表實現詞向量表示,並在訓練中逐漸學習文字之間的相似性。本書將透過諷刺情緒檢測器的構建例項,演示嵌入層如何應用在 NLP 任務中,並揭示如何利用模型架構和訓練技巧來最佳化文字分析效果。

相關文章