word2vec模型案例

代碼實現:

import torch.optim as optim
from tqdm import tqdm, trange
import numpy as np
import torch
from torch import nn
import torch.nn.functional as FCONTEXT_SIZE = 2raw_text = """We are about to study the idea of a computational process. Computational processes are abstract beings that inhabit computers. 
As they evolve, processes manipulate other abstract things called data. The evolution of a process is directed by a pattern of rules called a program. 
People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.""" .split()vocab = set(raw_text)
vocab_size = len(vocab)word_to_idx = {word: i for i, word in enumerate(vocab)}
idx_to_word = {i: word for i, word in enumerate(vocab)}data = []
for i in range(CONTEXT_SIZE, len(raw_text) - CONTEXT_SIZE):  # (2, 60)context = ([raw_text[i - (2-j)] for j in range(CONTEXT_SIZE)]          # [we,are]+ [raw_text[i + j + 1] for j in range(CONTEXT_SIZE)]       # [to,study])target = raw_text[i]  # 目標詞data.append((context, target))def make_context_vector(context,word_to_idx):idxs = [word_to_idx[x] for x in context]return torch.tensor(idxs,dtype=torch.long)
print(make_context_vector(data[0][0],word_to_idx))device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
print(device)class CBOW(nn.Module):def __init__(self,vocab_size,embedding_dim):super(CBOW,self).__init__()self.embeddings = nn.Embedding(vocab_size,embedding_dim)self.proj = nn.Linear(embedding_dim,128)self.output = nn.Linear(128,vocab_size)def forward(self,inputs):embeds = sum(self.embeddings(inputs)).view(1,-1)out = F.relu(self.proj(embeds))out = self.output(out)null_plob = F.log_softmax(out,dim=-1)return null_plobmodel = CBOW(vocab_size,10).to(device)
optimizer = optim.Adam(model.parameters(),lr=0.001)
losses = []
loss_function = nn.NLLLoss()
model.train()
for epoch in tqdm(range(200)):total_loss = 0size = 0for context,target in data:context_vector = make_context_vector(context,word_to_idx).to(device)target = torch.tensor([word_to_idx[target]]).to(device)train_predict = model(context_vector)loss = loss_function(train_predict,target)optimizer.zero_grad()loss.backward()optimizer.step()total_loss += loss.item()size += 1avg_loss = total_loss / sizeprint(avg_loss)context = ['People', 'create', 'to', 'direct']  # People create programs to direct
context_vector = make_context_vector(context, word_to_idx).to(device)# 預測的值
model.eval()  # 進入到測試模式
predict = model(context_vector)
max_idx = predict.argmax(1)  # dim=1表示每一行中的最大值對應的索引號,dim=0表示每一列中的最大值對應的索引號# 獲取詞向量,這個Embedding就是我們需要的詞向量,他只是一個模型的一個中間過程
print("CBOW embedding weight=", model.embeddings.weight)  # GPU
W = model.embeddings.weight.cpu().detach().numpy()  # .detach(): 這個方法會創建一個新的Tensor,它和原來的Tensor共享# 這意味著這個新的Tensor不會參與梯度的反向傳播,這對于防止在計算梯度時意外修改某些參數很有用。
print(W)# 生成詞嵌入字典,即{單詞1:詞向量1,單詞2:詞向量2...}的格式
word_2_vec = {}
for word in word_to_idx.keys():# 詞向量矩陣中某個詞的索引所對應的那一列即為該詞的詞向量word_2_vec[word] = W[word_to_idx[word], :]
print('jiesu')# 保存訓練后的詞向量為npz文件,numpy處理矩陣的速度非常快,方便后期其他操作
np.savez('word2vec實現.npz', file_1=W)
data = np.load('word2vec實現.npz')
print(data.files)

這段代碼是一個基于 PyTorch 實現的CBOW(連續詞袋模型)?示例,用于訓練詞向量(類似 Word2Vec 的核心功能)。下面逐步分析代碼:

一、核心功能概述

代碼通過一段示例文本訓練 CBOW 模型,最終得到每個單詞的低維向量表示(詞嵌入)。CBOW 的核心思想是:用一個單詞的上下文(周圍單詞)預測該單詞本身,通過這個過程讓模型學習到單詞的語義向量。

二、代碼分步解析

1. 導入依賴庫
import torch.optim as optim  # PyTorch優化器
from tqdm import tqdm, trange  # 進度條工具
import numpy as np  # 數值計算
import torch
from torch import nn  # 神經網絡模塊
import torch.nn.functional as F  # 神經網絡函數(如激活函數、softmax等)

這些是 PyTorch 深度學習和數據處理的基礎庫,tqdm用于顯示訓練進度,提高可視化體驗。

2. 數據預處理
(1)定義超參數和原始文本
CONTEXT_SIZE = 2  # 上下文窗口大小:每個目標詞的前后各取2個詞作為上下文# 原始文本(分割成單詞列表)
raw_text = """We are about to study the idea of a computational process. Computational processes are abstract beings that inhabit computers. 
As they evolve, processes manipulate other abstract things called data. The evolution of a process is directed by a pattern of rules called a program. 
People create programs to direct processes. In effect, we conjure the spirits of the computer with our spells.""" .split()

CONTEXT_SIZE=2表示:對于每個目標詞,取其前面 2 個詞 + 后面 2 個詞作為上下文(共 4 個詞)。

(2)構建詞匯表
vocab = set(raw_text)  # 去重,得到所有唯一單詞
vocab_size = len(vocab)  # 詞匯表大小# 單詞→索引映射(用于將單詞轉為數字)
word_to_idx = {word: i for i, word in enumerate(vocab)}
# 索引→單詞映射(用于將數字轉回單詞)
idx_to_word = {i: word for i, word in enumerate(vocab)}

計算機無法直接處理文本,需將單詞轉為數字索引。這里通過兩個字典實現單詞和索引的雙向映射。

(3)構建訓練數據(上下文→目標詞)
data = []
# 遍歷文本,為每個位置的詞構建上下文和目標
for i in range(CONTEXT_SIZE, len(raw_text) - CONTEXT_SIZE):# 上下文 = 目標詞前面2個詞 + 后面2個詞context = ([raw_text[i - (2-j)] for j in range(CONTEXT_SIZE)]  # 前面2個詞(如i=2時,取i-2, i-1)+ [raw_text[i + j + 1] for j in range(CONTEXT_SIZE)]  # 后面2個詞(如i=2時,取i+1, i+2))target = raw_text[i]  # 目標詞(當前位置的詞)data.append((context, target))

例如,對于句子片段We are about to study

  • 當目標詞是about(索引 = 2)時,上下文是前面的We, are和后面的to, study,即(["We", "are", "to", "study"], "about")

data最終是一個列表,每個元素是(上下文單詞列表, 目標詞)的元組,用于模型訓練。

(4)上下文轉向量函數
def make_context_vector(context, word_to_idx):# 將上下文單詞轉為對應的索引,再封裝成PyTorch張量idxs = [word_to_idx[x] for x in context]return torch.tensor(idxs, dtype=torch.long)

將上下文的單詞列表(如["We", "are", "to", "study"])轉為索引張量(如[10, 5, 3, 8]),作為模型的輸入。

3. 設備配置
device = 'cuda' if torch.cuda.is_available() else 'mps' if torch.backends.mps.is_available() else 'cpu'
print(device)

自動選擇訓練設備:優先用 NVIDIA GPU(cuda),其次 Apple GPU(mps),最后用 CPU,以加速訓練。

4. CBOW 模型定義
class CBOW(nn.Module):def __init__(self, vocab_size, embedding_dim):super(CBOW, self).__init__()# 嵌入層:將單詞索引轉為低維向量(vocab_size→embedding_dim)self.embeddings = nn.Embedding(vocab_size, embedding_dim)# 投影層:將嵌入向量映射到128維self.proj = nn.Linear(embedding_dim, 128)# 輸出層:將128維向量映射到詞匯表大小(預測目標詞)self.output = nn.Linear(128, vocab_size)def forward(self, inputs):# 1. 上下文嵌入:獲取輸入的每個單詞的嵌入向量,求和(上下文向量的平均/求和代表上下文語義)embeds = sum(self.embeddings(inputs)).view(1, -1)  # 形狀:(1, embedding_dim)# 2. 投影層+激活函數out = F.relu(self.proj(embeds))  # 形狀:(1, 128)# 3. 輸出層+log_softmax(將輸出轉為概率分布的對數)out = self.output(out)  # 形狀:(1, vocab_size)log_probs = F.log_softmax(out, dim=-1)  # 沿最后一維計算softmax并取對數return log_probs

模型核心邏輯:

嵌入層(embeddings):是訓練的核心,其權重就是最終的詞向量(每個單詞對應一行向量)。

前向傳播:將上下文單詞的嵌入向量求和(代表上下文的整體語義),通過兩層線性網絡,最終輸出對目標詞的概率分布(對數形式)。

5. 模型訓練
# 初始化模型(詞匯表大小,嵌入維度10),并移動到指定設備
model = CBOW(vocab_size, 10).to(device)
# 優化器:Adam(常用的自適應學習率優化器)
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 損失函數:NLLLoss(負對數似然損失,配合log_softmax使用,等價于交叉熵損失)
loss_function = nn.NLLLoss()losses = []  # 記錄損失
model.train()  # 切換到訓練模式# 訓練200個epoch
for epoch in tqdm(range(200)):total_loss = 0  # 總損失size = 0  # 樣本數for context, target in data:# 1. 準備數據:上下文向量和目標詞索引(均移動到設備)context_vector = make_context_vector(context, word_to_idx).to(device)target = torch.tensor([word_to_idx[target]]).to(device)  # 目標詞的索引# 2. 模型預測predict = model(context_vector)# 3. 計算損失loss = loss_function(predict, target)# 4. 反向傳播+參數更新optimizer.zero_grad()  # 清空梯度loss.backward()  # 計算梯度optimizer.step()  # 更新參數total_loss += loss.item()  # 累加損失(轉為Python數值)size += 1# 計算并打印每個epoch的平均損失avg_loss = total_loss / sizeprint(f"Epoch {epoch+1}, Average Loss: {avg_loss}")losses.append(avg_loss)

訓練過程流程:

每個 epoch 遍歷所有訓練樣本(上下文 - 目標詞對)。

對每個樣本,模型根據上下文預測目標詞,計算預測值與真實值的損失。

通過反向傳播更新模型參數(尤其是嵌入層的權重,即詞向量)。

隨著訓練進行,損失逐漸下降,說明模型越來越能通過上下文準確預測目標詞。

6. 模型預測與詞向量提取
(1)測試預測效果
# 測試上下文:"People", "create", "to", "direct"(對應原句"People create programs to direct processes")
context = ['People', 'create', 'to', 'direct']
context_vector = make_context_vector(context, word_to_idx).to(device)model.eval()  # 切換到評估模式(關閉 dropout 等訓練特有的操作)
predict = model(context_vector)
max_idx = predict.argmax(1)  # 取概率最大的索引(預測的目標詞)
print("預測的目標詞:", idx_to_word[max_idx.item()])  # 理論上應輸出"programs"

用訓練好的模型測試:給定上下文People create ... to direct,模型應能預測出中間的目標詞programs

(2)提取詞向量
# 嵌入層的權重就是詞向量(vocab_size × embedding_dim 的矩陣)
print("CBOW嵌入層權重(詞向量矩陣):", model.embeddings.weight)# 將詞向量矩陣從GPU移到CPU,并轉為numpy數組(脫離計算圖,不參與梯度計算)
W = model.embeddings.weight.cpu().detach().numpy()

CBOW 模型的核心輸出是嵌入層的權重,每個單詞對應的行向量就是該單詞的語義向量(維度為 10,在初始化時指定)。

(3)構建詞 - 向量字典并保存
# 構建{單詞: 詞向量}字典
word_2_vec = {}
for word in word_to_idx.keys():# 詞向量矩陣中,單詞索引對應的行即為該詞的向量word_2_vec[word] = W[word_to_idx[word], :]# 保存詞向量為npz文件(方便后續復用)
np.savez('word2vec實現.npz', word_vectors=W)
# 測試加載
data = np.load('word2vec實現.npz')
print("保存的詞向量鍵名:", data.files)  # 輸出 ['word_vectors']

將詞向量整理為字典,并保存為 numpy 格式,方便后續用于語義相似度計算、文本分類等任務。

三、核心總結

  1. 數據層面:通過滑動窗口從文本中提取 “上下文 - 目標詞” 對,作為訓練樣本。
  2. 模型層面:CBOW 模型通過嵌入層將單詞轉為向量,用上下文向量的總和預測目標詞,最終學習到的嵌入層權重就是詞向量。
  3. 訓練目標:通過優化預測損失,讓語義相近的詞(如 “process” 和 “processes”)的向量更接近。
  4. 輸出:得到每個單詞的低維向量表示,可用于后續 NLP 任務(如語義相似度計算、文本分類等)。

這段代碼是 Word2Vec 中 CBOW 模型的簡化實現,核心思想與原始 Word2Vec 一致,適合理解詞向量的訓練原理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/96082.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/96082.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/96082.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

< 自用文 OS 有關 > (續)發現正在被攻擊 后的自救 Fail2ban + IPset + UFW 工作流程詳解

繼上編:< 自用文 主機 USC 記錄:> 發現正在被攻擊 后的自救-CSDN博客 環境: 改進: 以下是把代碼,懶得寫,扔給了 AI ,讓它出的: Fail2ban IPset UFW 工作…

Linux —— 虛擬進程地址空間

🎁個人主頁:工藤新一 🔍系列專欄:C面向對象(類和對象篇) 🌟心中的天空之城,終會照亮我前方的路 🎉歡迎大家點贊👍評論📝收藏?文章 文章目錄虛…

簡單聊一聊js

JavaScript 是一種高級的、解釋型的編程語言。它是現代 Web 開發的三大核心基石之一,與 HTML 和 CSS 并列。?HTML?:負責網頁的結構和內容?(如標題、段落、圖片)。?CSS?:負責網頁的樣式和布局?(如顏色…

造粒機cad+設計說明書

摘要 隨著現代化工業的快速發展,生產出大量的固體廢棄物。這些廢棄物對環境造成了很大的污染,因此需要采取有效的措施進行處理。機械強壓式造粒機就是一種非常有效的處理工具,它可以將廢渣、廢料、飼料和化肥等材料通過機械強力擠壓&#xff…

第五課 C#語言基本元素概覽,初始類型,變量與方法,算法簡介

熟悉C#語言要求:對構成C#語言的基本元素,隨便拿出一個你都認識,對于常見基本元素,都能正確使用它 精通C#語言要求:對于構成C#語言的基本元素,隨便拿出一個都會使用,對于常用基本元素&#xff0…

LLM學習:大模型基礎——視覺大模型以及autodl使用

1、常見的VLM 在大模型中,VLM 是視覺語言模型(Vision-Language Model)的縮寫,是一種多模態、生成式 AI 模型,能夠理解和處理視頻、圖像和文本。 VLM 通過將大語言模型(LLM)與視覺編碼器相結合構建而成,使 LLM 具有 “看” 的能力,從而可以處理并提供對提示中的…

Vue—路由配置中設置了meta.title,但頁面標題仍然顯示為“Vite App“?【讓我來看看~】

路由配置中明明設置了meta.title,但是頁面標題仍然顯示為"Vite App"?這是因為僅僅在路由配置中設置meta.title是不夠的,還需要在路由守衛中動態設置頁面標題。需要做以下幾件事來正確設置頁面標題:1.首先更新HTML文件的…

【機器學習】綜合實訓(二)

項目五 電影評分預測【教學內容】使用 MovieLens 數據集,訓練一個模型預測用戶對電影的評分。主要有以下幾個知識點:(1)數據加載與探索性分析(EDA)。(2)處理稀疏數據(如用…

STM32 UART + DMA + 空閑中斷使用中的幀錯誤(FE)問題及解決方案

STM32 UART + DMA + IDLE中斷使用中的幀錯誤(FE)問題及解決方案 在我調試STM32H7串口空閑中斷DMA接受時遇到了一個bug,這個現象發生在系統剛上電時,有個串口由于幀錯誤FE掛起了中斷,之后在HAL_UART_IRQHandler這個全局中斷處理函數結束后,所有的中斷使能標志位都被清除了,經過…

TDengine 選擇函數 BOTTOM() 用戶手冊

BOTTOM() 函數用戶手冊 函數定義 BOTTOM(expr, k)功能說明 BOTTOM() 函數統計表/超級表中某列的值最小 k 個非 NULL 值。如果多條數據取值一樣,全部取用又會超出 k 條限制時,系統會從相同值中隨機選取符合要求的數量返回。 返回值 數據類型: 同應用…

西門子 S7-200 SMART PLC 實現星三角降壓啟動控制:原理、案例與完整程序

在工業控制場景中,中型異步電機直接啟動時會產生遠超額定電流的沖擊電流(通常為額定電流的 5-7 倍),不僅會影響電網穩定性,還可能對機械設備造成損傷。星三角(Y-Δ)降壓啟動是解決這一問題的經典…

【Android】View 的基礎知識

【Android】View 的基礎知識 1. 什么是 View? View 是 Android 中所有UI組件的基礎類。它表示屏幕上的一個矩形區域,負責繪制內容和處理用戶交互事件。所有的 UI 組件(如按鈕、文本框等)都是 View 的子類,而 ViewGroup…

西門子 S7-200 SMART PLC 實現電機點動與連續運行綜合控制

在工業生產中,電機控制并非單一模式:調試設備時需要 “按動即轉、松開即停” 的點動功能,正常生產時則需要 “一鍵啟動、持續運行” 的連續控制。本文以西門子 S7-200 SMART PLC 為載體,詳細講解電機點動控制原理,并設…

如何解決pip安裝報錯ModuleNotFoundError: No module named ‘sphinx-rtd-theme’問題

【Python系列Bug修復PyCharm控制臺pip install報錯】如何解決pip安裝報錯ModuleNotFoundError: No module named ‘sphinx-rtd-theme’問題 摘要 在使用 PyCharm 開發 Python 項目時,pip install 報錯是常見痛點。特別是在構建文檔或引入第三方庫時,開…

HakcMyVM-Literal

目錄信息搜集漏洞利用權限提升信息搜集 主機發現 ┌──(kali?kali)-[~] └─$ nmap -sn 192.168.21.0/24 Nmap scan report for 192.168.21.5端口掃描 ┌──(kali?kali)-[~] └─$ nmap -sS -sV -O -p- 192.168.21.5 Starting Nmap 7.95 ( https://nmap.org ) a…

0904 類的繼承

Part 1.梳理思維導圖一.繼承中的特殊成員函數1.構造函數父類的構造函數會被繼承到子類中&#xff0c;在構造的順序中&#xff0c;是先構造父類&#xff0c;再構造子類#include <iostream>using namespace std;class Father { public:string name; protected:int *age; pr…

PDF教程|如何把想要的網頁保存下來?

前段時間有個小伙伴咨詢了小白&#xff1a;領導想要某個網頁的整個頁面&#xff0c;有沒有比較好的方法把它保存下來&#xff1f; 在他找到小白之前&#xff0c;這種事情他已經接到好幾次了&#xff0c;每次都是怎么解決的呢&#xff1f;其實很簡單&#xff0c;就是打開Word&a…

【bash】命令查看當前目錄下文件個數

要用 ls 查看當前目錄下的文件個數&#xff0c;可以結合 wc -l 來統計行數&#xff1a; ls -1 | wc -l說明&#xff1a; ls -1&#xff1a;以一行一個文件的方式列出。wc -l&#xff1a;統計行數&#xff0c;也就是文件/目錄的數量。 ?? 需要注意&#xff1a; 這個方法會把文…

「日拱一碼」081 機器學習——梯度增強特征選擇GBFS

目錄 什么是梯度增強特征選擇&#xff08;GBFS&#xff09; 為什么 GBM 適合做特征選擇 GBFS 的一般步驟 代碼示例 什么是梯度增強特征選擇&#xff08;GBFS&#xff09; GBFS 并非一個像 Lasso 或隨機森林那樣有嚴格標準定義的獨立算法&#xff0c;而是一種基于梯度提升機…

解構匯編, 萬物起源

匯編的誕生匯編全景圖核心主干: CPU架構主要分支: 語法和工具共同的地貌: 核心概念延伸: 跨平臺 & 跨架構跨平臺跨架構總結以 GAS vs. NASM 為例NASM 不支持跨架構 ≠ 無法在ARM架構上的系統安裝匯編的誕生 機器語言的困境 早期的程序員直接使用機器語言進行編程機器語言由…