嵌入式學習入門
檢視此教程和配套的 Notebook:
理解嵌入
嵌入是對一段資訊的數值表示,例如文字、文件、影像、音訊等。這種表示捕獲了被嵌入內容的語義含義,使其在許多行業應用中具有魯棒性。
給定文字“投票的主要好處是什麼?”,該句子的嵌入可以表示在向量空間中,例如,一個包含 384 個數字的列表(例如,[0.84, 0.42, ..., 0.02])。由於這個列表捕獲了含義,我們可以做一些令人興奮的事情,例如計算不同嵌入之間的距離,以確定兩個句子的含義匹配程度。
嵌入不限於文字!您還可以建立影像的嵌入(例如,一個包含 384 個數字的列表),並將其與文字嵌入進行比較,以確定句子是否描述了影像。這個概念是影像搜尋、分類、描述等強大系統的基礎!
嵌入是如何生成的?一個名為 Sentence Transformers 的開源庫允許您免費從影像和文字建立最先進的嵌入。本部落格將展示一個使用此庫的示例。
嵌入的作用是什麼?
"[...] 一旦你理解了這個機器學習多功能工具(嵌入),你將能夠構建從搜尋引擎到推薦系統,再到聊天機器人等等。你不需要是具有機器學習專業知識的資料科學家才能使用它們,也不需要龐大的標註資料集。" - Dale Markowitz,Google Cloud。
一旦一段資訊(一個句子、一個文件、一張圖片)被嵌入,創造力就開始了;一些有趣的工業應用使用了嵌入。例如,Google 搜尋使用嵌入來匹配文字到文字和文字到圖片;Snapchat 使用它們來“在正確的時間向正確的使用者投放正確的廣告”;Meta(Facebook)使用它們進行社交搜尋。
在能夠從嵌入中獲取智慧之前,這些公司必須嵌入它們的資訊。一個嵌入式資料集允許演算法快速搜尋、排序、分組等等。然而,這可能很昂貴且技術複雜。在這篇文章中,我們使用簡單的開源工具來展示嵌入和分析資料集是多麼容易。
嵌入式學習入門
我們將建立一個小型常見問題解答(FAQs)引擎:接收使用者的查詢,並確定哪個常見問題最相似。我們將使用美國社會保障醫療保險常見問題解答。
但首先,我們需要嵌入我們的資料集(其他文字可互換使用編碼和嵌入這兩個術語)。Hugging Face 推理 API 允許我們透過簡單的 POST 呼叫輕鬆嵌入資料集。
由於嵌入捕獲了問題的語義含義,因此可以比較不同的嵌入並檢視它們之間的差異或相似程度。因此,您可以獲得與查詢最相似的嵌入,這相當於找到最相似的常見問題解答。檢視我們的語義搜尋教程,瞭解此機制如何工作的更詳細解釋。
簡而言之,我們將
- 使用推理 API 嵌入 Medicare 的常見問題。
- 將嵌入式問題上傳到 Hub 進行免費託管。
- 將客戶的查詢與嵌入式資料集進行比較,以確定哪個是與查詢最相似的常見問題。
1. 嵌入資料集
第一步是選擇一個現有的預訓練模型來建立嵌入。我們可以從 Sentence Transformers 庫中選擇一個模型。在這種情況下,讓我們使用 "sentence-transformers/all-MiniLM-L6-v2",因為它是一個小而強大的模型。在未來的文章中,我們將研究其他模型及其權衡。
登入到 Hub。您必須在賬戶設定中建立一個寫入令牌。我們將把寫入令牌儲存在 `hf_token` 中。
model_id = "sentence-transformers/all-MiniLM-L6-v2"
hf_token = "get your token in https://huggingface.co/settings/tokens"
要生成嵌入,您可以使用 `https://api-inference.huggingface.co/pipeline/feature-extraction/{model_id}` 端點,並帶有頭資訊 `{"Authorization": f"Bearer {hf_token}"}`。下面是一個接收包含文字的字典並返回包含嵌入列表的函式。
import requests
api_url = f"https://api-inference.huggingface.co/pipeline/feature-extraction/{model_id}"
headers = {"Authorization": f"Bearer {hf_token}"}
首次生成嵌入時,API 返回嵌入可能需要一段時間(大約 20 秒)。我們使用 `retry` 裝飾器(透過 `pip install retry` 安裝),這樣如果在第一次嘗試時 `output = query(dict(inputs = texts))` 不起作用,則等待 10 秒並再嘗試三次。發生這種情況是因為在第一次請求時,模型需要下載並安裝到伺服器上,但隨後的呼叫會快得多。
def query(texts):
response = requests.post(api_url, headers=headers, json={"inputs": texts, "options":{"wait_for_model":True}})
return response.json()
當前的 API 不強制執行嚴格的速率限制。相反,Hugging Face 會在所有可用資源之間均勻分配負載,並傾向於穩定的請求流。如果您需要嵌入多個文字或影像,Hugging Face 加速推理 API 將加快推理速度,並允許您選擇使用 CPU 或 GPU。
texts = ["How do I get a replacement Medicare card?",
"What is the monthly premium for Medicare Part B?",
"How do I terminate my Medicare Part B (medical insurance)?",
"How do I sign up for Medicare?",
"Can I sign up for Medicare Part B if I am working and have health insurance through an employer?",
"How do I sign up for Medicare Part B if I already have Part A?",
"What are Medicare late enrollment penalties?",
"What is Medicare and who can get it?",
"How can I get help with my Medicare Part A and Part B premiums?",
"What are the different parts of Medicare?",
"Will my Medicare premiums be higher because of my higher income?",
"What is TRICARE ?",
"Should I sign up for Medicare Part B if I have Veterans' Benefits?"]
output = query(texts)
作為響應,您將獲得一個列表的列表。每個列表都包含一個常見問題解答的嵌入。模型 "sentence-transformers/all-MiniLM-L6-v2" 將輸入問題編碼為 13 個大小為 384 的嵌入。讓我們將該列表轉換為一個形狀為 (13x384) 的 Pandas `DataFrame`。
import pandas as pd
embeddings = pd.DataFrame(output)
它類似於這個矩陣
[[-0.02388945 0.05525852 -0.01165488 ... 0.00577787 0.03409787 -0.0068891 ]
[-0.0126876 0.04687412 -0.01050217 ... -0.02310316 -0.00278466 0.01047371]
[ 0.00049438 0.11941205 0.00522949 ... 0.01687654 -0.02386115 0.00526433]
...
[-0.03900796 -0.01060951 -0.00738271 ... -0.08390449 0.03768405 0.00231361]
[-0.09598278 -0.06301168 -0.11690582 ... 0.00549841 0.1528919 0.02472013]
[-0.01162949 0.05961934 0.01650903 ... -0.02821241 -0.00116556 0.0010672 ]]
2. 在 Hugging Face Hub 上免費託管嵌入
🤗 Datasets 是一個用於快速訪問和共享資料集的庫。讓我們使用使用者介面(UI)在 Hub 中託管嵌入資料集。然後,任何人都可以用一行程式碼載入它。您還可以使用終端共享資料集;請參閱文件瞭解步驟。在本條目的配套筆記本中,您將能夠使用終端共享資料集。如果您想跳過本節,請檢視包含嵌入式常見問題的 `ITESM/embedded_faqs_medicare` 儲存庫。
首先,我們將嵌入從 Pandas `DataFrame` 匯出到 CSV。您可以以任何您喜歡的方式儲存資料集,例如 zip 或 pickle;您不需要使用 Pandas 或 CSV。由於我們的嵌入檔案不大,我們可以將其儲存在 CSV 中,`datasets.load_dataset()` 函式在下一節中將輕鬆推斷出它(請參閱資料集文件),即我們不需要建立載入指令碼。我們將把嵌入儲存為 `embeddings.csv`。
embeddings.to_csv("embeddings.csv", index=False)
按照以下步驟在 Hub 中託管 `embeddings.csv`。
- 點選 Hub UI 右上角的使用者圖示。
- 使用“新建資料集”建立資料集。
- 選擇資料集的所有者(組織或個人)、名稱和許可證。選擇您希望它是私有還是公開。建立資料集。
- 轉到“檔案”選項卡(如下圖所示),然後單擊“新增檔案”和“上傳檔案”。
- 最後,拖放或上傳資料集,並提交更改。
現在資料集已免費託管在 Hub 上。您(或任何您希望共享嵌入的人)都可以快速載入它們。讓我們看看如何操作。
3. 獲取與查詢最相似的常見問題
假設一位 Medicare 客戶詢問:“Medicare 如何幫助我?”。我們將**找到**我們的哪些常見問題最能回答使用者的查詢。我們將建立一個查詢的嵌入,它可以代表其語義含義。然後,我們將其與 FAQ 資料集中的每個嵌入進行比較,以確定在向量空間中哪個嵌入最接近查詢。
使用 `pip install datasets` 安裝 🤗 Datasets 庫。然後,從 Hub 載入嵌入式資料集並將其轉換為 PyTorch `FloatTensor`。請注意,這不是操作 `Dataset` 的唯一方法;例如,您可以使用 NumPy、Tensorflow 或 SciPy(請參閱文件)。如果您想使用真實資料集進行練習,`ITESM/embedded_faqs_medicare` 儲存庫包含嵌入式 FAQ,或者您可以使用本部落格的配套筆記本。
import torch
from datasets import load_dataset
faqs_embeddings = load_dataset('namespace/repo_name')
dataset_embeddings = torch.from_numpy(faqs_embeddings["train"].to_pandas().to_numpy()).to(torch.float)
我們使用之前定義的查詢函式來嵌入客戶的問題,並將其轉換為 PyTorch `FloatTensor` 以便高效操作。請注意,載入嵌入資料集後,我們可以使用 `Dataset` 的 `add_faiss_index` 和 `search` 方法,使用 faiss 庫來識別最接近嵌入查詢的常見問題。這裡有一個不錯的替代教程。
question = ["How can Medicare help me?"]
output = query(question)
query_embeddings = torch.FloatTensor(output)
您可以使用 Sentence Transformers 庫中的 `util.semantic_search` 函式來識別哪些常見問題(FAQs)與使用者的查詢最接近(最相似)。此函式預設使用餘弦相似度作為確定嵌入接近度的函式。但是,您也可以使用其他函式來測量向量空間中兩點之間的距離,例如點積。
使用 `pip install -U sentence-transformers` 安裝 `sentence-transformers`,並搜尋與查詢最相似的五個常見問題。
from sentence_transformers.util import semantic_search
hits = semantic_search(query_embeddings, dataset_embeddings, top_k=5)
`util.semantic_search` 識別 13 個常見問題中每個問題與客戶查詢的接近程度,並返回一個包含最靠前的 `top_k` 個常見問題的字典列表。`hits` 看起來像這樣
[{'corpus_id': 8, 'score': 0.75653076171875},
{'corpus_id': 7, 'score': 0.7418993711471558},
{'corpus_id': 3, 'score': 0.7252674102783203},
{'corpus_id': 9, 'score': 0.6735571622848511},
{'corpus_id': 10, 'score': 0.6505177617073059}]
`corpus_id` 中的值允許我們索引在第一部分中定義的 `texts` 列表,並獲得五個最相似的常見問題
print([texts[hits[0][i]['corpus_id']] for i in range(len(hits[0]))])
以下是與客戶查詢最接近的 5 個常見問題:
['How can I get help with my Medicare Part A and Part B premiums?',
'What is Medicare and who can get it?',
'How do I sign up for Medicare?',
'What are the different parts of Medicare?',
'Will my Medicare premiums be higher because of my higher income?']
此列表代表與客戶查詢最接近的 5 個常見問題。很棒!我們在這裡主要使用了 PyTorch 和 Sentence Transformers 作為數值工具。但是,我們也可以使用 NumPy 和 SciPy 等工具自行定義餘弦相似度和排名函式。
更多學習資源
如果您想了解更多關於 Sentence Transformers 庫的資訊
- Hub 組織,獲取所有新模型和下載模型的說明。
- Nils Reimers 的推文,比較了 Sentence Transformer 模型與 GPT-3 嵌入。劇透:Sentence Transformers 非常棒!
- Sentence Transformers 文件,
- Nima 的推文串,關於最近的研究。
感謝閱讀!