自然處理語言NLP:One-Hot編碼、TF-IDF、詞向量、NLP特征輸入、EmbeddingLayer實現、word2vec

文章目錄

  • 自然語言處理(NLP)
    • 一、什么是自然語言處理(NLP)?
    • 二、NLP 的核心目標
    • 三、NLP 的主要應用方向(應用場景)
    • 四、NLP 的基本概念
    • 五、NLP 的基本處理流程
      • 1. 文本預處理
      • 2. 特征表示
      • 3. 模型選擇與訓練
      • 4. 模型評估
      • 5. 部署與應用
    • 六、NLP 的關鍵技術演進
  • NLP 特征工程詳解
    • 一、傳統 NLP 中的特征工程
      • 1. 獨熱編碼(One-Hot Encoding)
      • 2. TF-IDF
      • 3. N-Grams 特征
    • 二、詞向量
    • 三、深度學習中的 NLP 特征輸入

自然語言處理(NLP)

一、什么是自然語言處理(NLP)?

自然語言處理(Natural Language Processing,簡稱 NLP)是人工智能(AI)的一個分支,致力于讓計算機能夠理解、生成、分析和處理人類語言(如中文、英文等)。

簡單說:讓機器“聽懂”和“會說”人話。


二、NLP 的核心目標

目標說明
理解語言從文本中提取語義、情感、意圖等信息
生成語言讓機器寫出通順、有邏輯的句子或文章
語言轉換如機器翻譯、語音識別與合成
交互能力實現人機對話,如智能客服、語音助手

三、NLP 的主要應用方向(應用場景)

應用說明實例
文本分類判斷文本屬于哪一類垃圾郵件識別、新聞分類
情感分析分析文本的情感傾向商品評論是好評還是差評
命名實體識別(NER)識別文本中的人名、地名、組織等“馬云在杭州創立阿里巴巴” → 馬云(人名)、杭州(地名)、阿里巴巴(組織)
機器翻譯將一種語言自動翻譯成另一種谷歌翻譯、DeepL
問答系統根據問題給出答案智能客服、Siri、ChatGPT
文本生成自動生成文章、摘要、對話寫作助手、AI寫詩、新聞摘要
語音識別與合成語音轉文字 / 文字轉語音語音輸入法、智能音箱
信息抽取從文本中提取結構化信息從簡歷中提取姓名、學歷、工作經驗
文本摘要將長文本壓縮為短摘要新聞摘要、論文摘要
對話系統實現人機對話智能客服、聊天機器人

四、NLP 的基本概念

概念解釋
分詞(Tokenization)將句子切分成詞語或子詞(中文需分詞,英文按空格)
詞性標注(POS)標注每個詞的詞性(名詞、動詞、形容詞等)
句法分析分析句子的語法結構(主謂賓)
語義分析理解詞語和句子的含義
停用詞(Stop Words)無實際意義的詞(如“的”、“了”、“is”、“the”),常被過濾
詞向量(Word Embedding)將詞語表示為向量,使語義相近的詞向量也相近(如 Word2Vec、GloVe)
上下文表示考慮詞語在句子中的上下文(如 BERT、Transformer)
預訓練模型先在大規模語料上訓練,再在具體任務上微調(如 BERT、RoBERTa、ChatGLM)

五、NLP 的基本處理流程

一個典型的 NLP 任務處理流程如下:

1. 文本預處理

  • 分詞(中文用 jieba、英文用 split/spaCy)
  • 去除標點、停用詞、數字等
  • 轉小寫(英文)
  • 詞干提取 / 詞形還原(英文)

2. 特征表示

  • One-Hot 編碼:簡單但稀疏
  • 詞袋模型(Bag of Words, BoW)
  • TF-IDF:衡量詞的重要性
  • 詞向量(Word2Vec、FastText)
  • 上下文向量(BERT、Transformer)

3. 模型選擇與訓練

  • 傳統方法:樸素貝葉斯、SVM、CRF
  • 深度學習:RNN、LSTM、GRU、Transformer、BERT
  • 預訓練 + 微調(主流范式)

4. 模型評估

  • 分類任務:準確率、精確率、召回率、F1
  • 生成任務:BLEU、ROUGE、METEOR
  • 語義任務:相似度、人工評估

5. 部署與應用

  • 導出模型(ONNX、TorchScript)
  • 集成到 Web、App、API 服務中

六、NLP 的關鍵技術演進

階段技術特點
1990s規則 + 統計方法依賴人工規則和特征工程
2000s機器學習(SVM、CRF)使用 TF-IDF 等特征
2013~2018深度學習(RNN、CNN)自動學習特征,但難處理長依賴
2018~至今預訓練模型(BERT、GPT)基于 Transformer,上下文理解強,效果卓越

🔥 當前主流:Transformer + 預訓練 + 微調

NLP 特征工程詳解

特征工程是指將原始文本轉換為機器學習模型可理解的數值型輸入的過程。在 NLP 中,特征工程是模型性能的關鍵。

一、傳統 NLP 中的特征工程

1. 獨熱編碼(One-Hot Encoding)

每個詞被映射為一個二進制向量,向量長度等于類別總數,僅有一個位置為1(對應詞的索引),其余為0。

示例

詞表:["我", "愛", "學習", "AI"] → 大小為 4

  • “我” → [1, 0, 0, 0]
  • “愛” → [0, 1, 0, 0]

優點:

  • 消除順序偏差:避免整數編碼(如 0、1、2)引入的虛假順序關系。
  • 簡單直觀:易于實現,適用于線性模型、樹模型等。

缺點:

  • 維度爆炸:類別多時會導致高維稀疏向量(如詞匯表有10萬詞時,向量長度為10萬)。
  • 稀疏性:大部分位置為0,計算和存儲效率低。
  • 忽略語義:無法捕捉詞與詞之間的關聯(如“北京”和“天安門”可能相關)。

2. TF-IDF

改進版詞袋模型,衡量一個詞對文檔的重要性。

  • TF:詞在文檔中出現的頻率

    TF(t,d)=詞?t在文檔?d中出現的次數文檔?d的總詞數\text{TF}(t, d) = \frac{\text{詞 } t \text{ 在文檔 } d \text{ 中出現的次數}}{\text{文檔 } d \text{ 的總詞數}} TF(t,d)=文檔?d?的總詞數?t?在文檔?d?中出現的次數?

  • IDF:log(總文檔數 / 包含該詞的文檔數),越少見的詞,IDF 越高

    IDF(t,D)=log?(N1+包含詞?t的文檔數)\text{IDF}(t, D) = \log \left( \frac{N}{1 + \text{包含詞 } t \text{ 的文檔數}} \right) IDF(t,D)=log(1+包含詞?t?的文檔數N?)

  • 權重 = TF × IDF

【示例】

假設我們有一個小型語料庫,包含 3 個文檔(比如 3 篇新聞):

  • D1: the cat sat on the mat
  • D2: the dog ran on the road
  • D3: the cat and the dog are friends

我們的目標是:計算每個詞在每篇文檔中的 TF-IDF 值,以衡量其重要性。

第一步:構建詞表

將所有文檔中的詞提取出來,去重后得到詞表:

{the, cat, sat, on, mat, dog, ran, road, and, are, friends}

共 11 個詞。

第二步:計算 TF(詞頻)

公式:
TF(t,d)=詞?t在文檔?d中出現的次數文檔?d的總詞數\text{TF}(t, d) = \frac{\text{詞 } t \text{ 在文檔 } d \text{ 中出現的次數}}{\text{文檔 } d \text{ 的總詞數}} TF(t,d)=文檔?d?的總詞數?t?在文檔?d?中出現的次數?
我們先統計每個文檔的總詞數:

  • D1: 6 個詞
  • D2: 6 個詞
  • D3: 7 個詞

計算部分詞的 TF(只展示關鍵詞)

D1D2D3
the2/6 = 0.3332/6 = 0.3332/7 = 0.286
cat1/6 = 0.16701/7 = 0.143
dog01/6 = 0.1671/7 = 0.143
mat1/6 = 0.16700
road01/6 = 0.1670

其他詞類似計算(如 sat, ran 等)


第三步:計算 IDF(逆文檔頻率)

公式:
IDF(t,D)=log?(N1+包含詞?t的文檔數)\text{IDF}(t, D) = \log \left( \frac{N}{1 + \text{包含詞 } t \text{ 的文檔數}} \right) IDF(t,D)=log(1+包含詞?t?的文檔數N?)

  • N=3(總文檔數)
  • 加 1 是為了防止分母為 0(拉普拉斯平滑)

我們計算每個詞的 IDF:

包含該詞的文檔數IDF 計算IDF 值(保留3位)
the3log?(3/(1+3))=log?(0.75)log(3/(1+3))=log(0.75)-0.288
cat2log?(3/(1+2))=log?(1.0)log(3/(1+2))=log(1.0)0.000
dog2log?(3/3)=log?(1.0)log(3/3)=log(1.0)0.000
sat1log?(3/2)=log?(1.5)log(3/2)=log(1.5)0.405
mat1log?(3/2)=log?(1.5)log(3/2)=log(1.5)0.405
ran1log?(3/2)log(3/2)0.405
road1log?(3/2)log(3/2)0.405
and1log?(3/2)log(3/2)0.405
are1log?(3/2)log(3/2)0.405
friends1log?(3/2)log(3/2)0.405
on2log?(3/3)=log?(1.0)log(3/3)=log(1.0)0.000

注意:the 出現在所有文檔中,IDF 為負,說明它不具區分性,反而可能應被降權。

簡單說:

  • 一個詞出現的文檔越多 → 越常見 → 越不重要 → IDF 值越低
  • 一個詞出現的文檔越少 → 越稀有 → 越可能具有區分性 → IDF 值越高

第四步:計算 TF-IDF

公式:

TF-IDF(t,d)=TF(t,d)×IDF(t)

我們以 D1 為例,計算其中幾個詞的 TF-IDF:

文檔 D1: the cat sat on the mat

TF (D1)IDFTF-IDF (D1)
the0.333-0.2880.333 × (-0.288) ≈ -0.096
cat0.1670.0000.167 × 0.000 = 0.000
sat0.1670.4050.167 × 0.405 ≈ 0.068
on0.1670.0000.167 × 0.000 = 0.000
mat0.1670.4050.167 × 0.405 ≈ 0.068

解讀:

  • the 雖然出現頻繁,但 IDF 為負,整體貢獻為負,說明它不重要。
  • cat 出現一次,但出現在 2 篇文檔中,IDF=0,重要性被中和
  • satmat 只在 D1 中出現,IDF > 0,因此 TF-IDF 值較高,說明它們是 D1 的“關鍵詞”。

結論:

  • 文檔頻率和樣本語義貢獻程度呈反相關
  • 文檔頻率和逆文檔頻率呈反相關
  • 逆文檔頻率和樣本語義貢獻度呈正相關

3. N-Grams 特征

N-Grams 是指文本中連續出現的 N 個詞(或字符)的組合,是自然語言處理(NLP)中一種重要的特征表示方法。

簡單理解:將句子切分為長度為 N 的“滑動窗口”片段。

【示例】

句子:“我愛機器學習”

根據 N 的取值不同,N-Grams 可分為:

類型名稱示例(句子:“我愛機器學習”)
1-GramUnigram(一元語法)我,愛,機器,學習
2-GramBigram(二元語法)我愛,愛機器,機器學習
3-GramTrigram(三元語法)我愛機器,愛機器學習
4-GramFour-gram(更長的組合,依此類推)

通常 N 不會太大(一般 ≤ 5),否則特征數量爆炸。

N-Grams 的作用:

  1. 捕捉局部詞序信息
  • 傳統詞袋模型(Bag of Words)完全忽略詞序。
  • N-Grams 保留了詞語的相鄰關系,能區分:“貓怕狗” vs “狗怕貓”
  1. 提升模型對語言結構的理解
  • Bigram 可以學習“通常哪些詞會連在一起”
  • 例如:“深度學習”比“學習深度”更常見
  1. 用于語言模型(Language Model)
  • 預測下一個詞的概率
  • 廣泛應用于拼寫糾錯、語音識別、機器翻譯等。

通常情況下,可以將n-gramsTF-IDF 相結合,在保留詞語搭配和詞序信息的同時,通過 TF-IDF 權重突出關鍵短語、抑制常見無意義組合。結合的過程基本上是先生成 n-grams,然后對這些 n-grams 計算 TF-IDF 權重。

  • n-grams:提供結構信息(詞序、搭配)
  • TF-IDF:提供重要性權重(突出關鍵詞,抑制常見組合)

【示例】

文檔1(正面):這部電影真的很棒
文檔2(負面):這部電影并不棒

僅用 unigram + TF-IDF 的問題:

  • 兩篇都包含:“這”、“部”、“電影”、“很”、“棒”
  • “并不” vs “真的” 差異被忽略 → 模型難區分情感

加入 bigram 后:

文檔Bigrams
正面這部, 部電, 電影, 影真, 真的, 的很, 很棒
負面這部, 部電, 電影, 影并, 并不, 不棒

→ “真的很棒” vs “并不棒” 被區分開!

再用 TF-IDF 加權后,“很棒”可能在語料中少見 → IDF 高 → 權重高,“的”等常見組合權重低。

傳統特征工程手工成本高、語義表達弱、泛化能力差,難以應對復雜的語言理解任務。

因此現代 NLP 轉向 詞向量深度學習(如 BERT)


二、詞向量

詞向量(Word Embedding)是將自然語言中的詞語映射為一個低維、稠密的實數向量的技術。
它使得語義相近的詞在向量空間中距離也相近。

在自然語言處理(NLP)中,計算機無法直接理解文字。為了讓機器能處理“貓”、“喜歡”、“跑步”這樣的詞,我們需要把它們轉換成數字形式。這就是詞向量)的作用。

簡單說:
詞向量就是把一個詞變成一串數字(向量),讓計算機能進行數學計算,同時保留詞語的語義信息。

單個詞在預定義的向量空間中被表示為實數向量,每個單詞都映射到一個向量。舉個例子,比如在一個文本中包含“貓”“狗”“愛情”等若干單詞,而這若干單詞映射到向量空間中,“貓”對應的向量為(0.1 0.2 0.3)“狗”對應的向量為(0.2 0.2 0.4),“愛情”對應的映射為(-0.4 -0.5 -0.2)(本數據僅為示意)。像這種將文本X{x1,x2,x3,x4,x5……xn}映射到多維向量空間Y{y1,y2,y3,y4,y5……yn },這個映射的過程就叫做詞嵌入

我們計算“貓”和“狗”的余弦相似度,發現它們很接近;而“貓”和“愛情”距離較遠。

? 此外,詞嵌入還可以做類比,比如:

vec("國王") - vec("男人") + vec("女人") ≈ vec("女王")

這說明詞向量不僅能表示詞義,還能捕捉語法和語義關系

再比如:

  • “北京” - “中國” + “法國” ≈ “巴黎”
  • “跑步” - “走” + “飛” ≈ “飛行”

三、深度學習中的 NLP 特征輸入

1. 詞嵌入與分布式表示

1.1 傳統編碼的局限性
  • 獨熱編碼(One-Hot)
    每個詞表示為高維稀疏向量(如10000維詞表中,每個詞僅一個維度為1,其余為0)。
    缺陷
    • 維度災難:10000詞表需10000維向量,計算成本高。
    • 無法捕捉語義關系(如"king"和"queen"的距離與其他詞無區別)。
  • N-gram與TF-IDF
    通過統計局部共現詞或詞頻構建特征,但無法解決語義相似性和動態上下文感知問題。
1.2 分布式表示
  • 核心思想
    將離散詞映射到低維連續向量空間(如300維),通過上下文學習詞的語義關系。
    優勢
    • 低維度(如300維 vs 10000維獨熱編碼)。
    • 語義相似性(如"king - man + woman ≈ queen")。
    • 可微學習(通過反向傳播優化向量表示)。
  • 典型應用
    • Word2Vec(CBOW/Skip-gram)捕捉類比關系。
    • GloVe 利用全局共現矩陣生成詞向量。

2. 稠密編碼(特征嵌入)

將離散特征(詞、標簽、位置等)映射到低維稠密向量,通過神經網絡參數化學習。

特點:

  • 低維度:將高維稀疏表示(如 10,000 維)壓縮到低維(如 100 維)。
  • 語義相似性:向量距離反映對象間的語義關系(如 “king” 和 “queen” 的距離較近)。
  • 可微學習:通過神經網絡參數化學習,支持反向傳播優化。

在這里插入圖片描述

3. 詞嵌入算法

計算機無法直接處理文字,比如:

句子:"我 愛 學習"

如果我們用 One-Hot 編碼

  • “我” → [1, 0, 0]
  • “愛” → [0, 1, 0]
  • “學習” → [0, 0, 1]

問題來了:

  • 向量維度等于詞表大小,高維稀疏
  • 所有詞之間“距離相等”,沒有語義信息
  • “我” 和 “學習” 完全無關,但模型不知道它們常一起出現

所以我們需要更聰明的方式 —— Embedding Layer

3.1 EmbeddingLayer

Embedding Layer 是一個可訓練的神經網絡層,它將詞的索引(ID) 映射為一個固定維度的稠密向量

本質是一個可訓練的矩陣 E∈RV×d,其中 V 是詞表大小,d是嵌入維度。

怎么得到詞向量?

比如我們的目標是希望神經網絡發現如下這樣的規律:已知一句話的前幾個字,預測下一個字是什么,于是有了NNLM 語言模型搭建的網絡結構圖:

在這里插入圖片描述

具體怎么實施呢?先用最簡單的方法來表示每個詞,one-hot 表示為︰

dog=(0,0,0,0,1,0,0,0,0,…);

cat=(0,0,0,0,0,0,0,1,0,…) ;

eat=(0,1,0,0,0,0,0,0,0,…)

在這里插入圖片描述

可是 one-hot 表示法有諸多的缺陷,還是稠密的向量表示更好一些,那么怎么轉換呢?加一個矩陣映射一下就好!

在這里插入圖片描述

映射之后的向量層如果單獨拿出來看,還有辦法找到原本的詞是什么嗎?

One-hot表示法這時候就作為一個索引字典了,可以通過映射矩陣對應到具體的詞向量。

在這里插入圖片描述

這個層內部維護一個矩陣:E∈RV×d

一、詞表(V)

  • 詞表就是你模型認識的所有詞的集合。

  • 比如你的語料中只出現過這些詞:

    ["我", "愛", "學習", "AI", "今天", "天氣", "好"]
    

    那么詞表大小 V = 7 。

  • 每個詞會被分配一個唯一的編號(索引):

    我   → 0
    愛   → 1
    學習 → 2
    AI   → 3
    今天 → 4
    天氣 → 5
    好   → 6
    

二、嵌入維度(d)

  • 嵌入維度 d 是指每個詞要用多少個數字(即向量的長度)來表示。

  • 比如 d = 4 ,那么每個詞會被表示成一個 4 維的向量,像這樣:

    "我"   → [0.2, -0.5, 0.8, 0.1]
    "愛"   → [0.6,  0.3, 0.4, -0.2]
    ...
    

三、嵌入矩陣 E

  • 為了高效存儲和計算,我們把所有詞的向量堆在一起,形成一個大矩陣,叫做 嵌入矩陣 E。它的形狀是 V×d:
    • 有 V 行(每行對應一個詞)
    • 有 d 列(每列對應向量的一個維度)

【示例】

V = 3 (詞表:[“貓”, “狗”, “牛奶”])

d = 4 (每個詞用 4 個數字表示)

嵌入矩陣 E 長這樣:

E=[0.1?0.30.80.5←“貓”的向量0.20.40.70.6←“狗”的向量?0.10.90.20.3←“牛奶”的向量]∈R3×4E = \begin{bmatrix} 0.1 & -0.3 & 0.8 & 0.5 \\ \leftarrow \text{“貓”的向量} \\ 0.2 & 0.4 & 0.7 & 0.6 \\ \leftarrow \text{“狗”的向量} \\ -0.1 & 0.9 & 0.2 & 0.3 \\ \leftarrow \text{“牛奶”的向量} \end{bmatrix} \in \mathbb{R}^{3 \times 4} E=?0.1的向量0.2的向量?0.1牛奶的向量??0.30.40.9?0.80.70.2?0.50.60.3??R3×4

所以:

  • 第 0 行:是 “貓” 的詞向量
  • 第 1 行:是 “狗” 的詞向量
  • 第 2 行:是 “牛奶” 的詞向量

當你輸入一個詞,比如 “狗”,它的編號是 1,模型就會去嵌入矩陣 E 中查找第 1 行,取出對應的向量 [0.2, 0.4, 0.7, 0.6],作為這個詞的表示。

這個過程叫做 查表(lookup),也叫 嵌入查找(embedding lookup)

# 偽代碼
E = [[0.1, -0.3, 0.8, 0.5],   # 貓[0.2,  0.4, 0.7, 0.6],   # 狗[-0.1, 0.9, 0.2, 0.3]]   # 牛奶word_id = 1  # “狗”
word_vector = E[word_id]  # 取出第二行 → [0.2, 0.4, 0.7, 0.6]
實現步驟

在 PyTorch 中,我們可以使用 nn.Embedding 詞嵌入層來實現輸入詞的向量化。接下來,我們將會學習如何將詞轉換為詞向量,其步驟如下:

  1. 先將語料進行分詞,構建詞與索引的映射,我們可以把這個映射叫做詞表,詞表中每個詞都對應了一個唯一的索引;
  2. 然后使用 nn.Embedding 構建詞嵌入矩陣,詞索引對應的向量即為該詞對應的數值化后的向量表示。

【示例】文本數據為: “北京冬奧的進度條已經過半,不少外國運動員在完成自己的比賽后踏上歸途。”

  1. 首先,將文本進行分詞;
  2. 然后,根據詞構建詞表;
  3. 最后,使用嵌入層將文本轉換為向量表示。

步驟 1:首先使用 jieba 對文本進行分詞操作,將連續的文本切分為詞語列表。

import jiebatext = '北京冬奧的進度條已經過半,不少外國運動員在完成自己的比賽后踏上歸途。'
words = jieba.lcut(text)  # 使用精確模式分詞
print("分詞結果:", words)

輸出示例

分詞結果: ['北京', '冬奧', '的', '進度', '條', '已經', '過半', ',', '不少', '外國', '運動員', '在', '完成', '自己', '的', '比賽', '后', '踏上', '歸途', '。']

步驟 2: 將分詞后的詞語去重,并為每個詞分配唯一的索引(ID),構建詞表(vocabulary)。

# 去重并保留順序
unique_words = list(set(words))  
word_to_index = {word: idx for idx, word in enumerate(unique_words)}
index_to_word = {idx: word for idx, word in enumerate(unique_words)}print("詞表大小:", len(unique_words))
print("詞到索引的映射示例:", {k: v for k, v in list(word_to_index.items())[:5]})

輸出示例

詞表大小: 20
詞到索引的映射示例: {'北京': 0, '冬奧': 1, '的': 2, '進度': 3, '條': 4...}

步驟 3:使用 nn.Embedding 構建詞嵌入矩陣。

需要指定兩個關鍵參數:

  • num_embeddings: 詞表大小(即 len(unique_words)
  • embedding_dim: 每個詞的向量維度(例如 128)
import torch
import torch.nn as nn# 設置嵌入維度
embedding_dim = 128# 初始化嵌入層
embedding_layer = nn.Embedding(num_embeddings=len(unique_words), embedding_dim=embedding_dim)

步驟 4: 將文本轉換為索引序列

將分詞后的詞語轉換為對應的索引,并封裝為 PyTorch 張量作為輸入。

# 將分詞后的詞語轉換為索引序列
input_indices = [word_to_index[word] for word in words]
input_tensor = torch.tensor(input_indices)print("輸入索引序列:", input_indices)
print("輸入張量形狀:", input_tensor.shape)

輸出示例

輸入索引序列: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 2, 14, 15, 16, 17, 18]
輸入張量形狀: torch.Size([20])

步驟 5: 獲取詞向量

將索引序列輸入嵌入層,得到對應的詞向量表示。

# 獲取詞向量
embedded_vectors = embedding_layer(input_tensor)print("詞向量形狀:", embedded_vectors.shape)
print("第一個詞的向量示例:", embedded_vectors[0].detach().numpy()[:5])  # 顯示前5個維度

輸出示例

詞向量形狀: torch.Size([20, 128])
第一個詞的向量示例: [ 0.012  -0.034   0.045  -0.067   0.023]

完整代碼整合

import jieba
import torch
import torch.nn as nn# 1. 分詞
text = '北京冬奧的進度條已經過半,不少外國運動員在完成自己的比賽后踏上歸途。'
words = jieba.lcut(text)# 2. 構建詞表
unique_words = list(set(words))
word_to_index = {word: idx for idx, word in enumerate(unique_words)}
index_to_word = {idx: word for idx, word in enumerate(unique_words)}# 3. 初始化嵌入層
embedding_dim = 128
embedding_layer = nn.Embedding(num_embeddings=len(unique_words), embedding_dim=embedding_dim)# 4. 轉換為索引序列
input_indices = [word_to_index[word] for word in words]
input_tensor = torch.tensor(input_indices)# 5. 獲取詞向量
embedded_vectors = embedding_layer(input_tensor)# 6. 輸出結果
print("分詞結果:", words)
print("詞表大小:", len(unique_words))
print("詞向量形狀:", embedded_vectors.shape)
print("第一個詞的向量示例:", embedded_vectors[0].detach().numpy()[:5])
3.2 word2vec

Word2Vec 是一種高效學習詞向量(Word Embedding)的神經網絡模型,由 Google 的 Tomas Mikolov 團隊于 2013 年提出。它通過捕捉詞語的上下文關系,將詞語映射到低維連續向量空間中,使得語義相似的詞在向量空間中距離更近。Word2Vec 的提出標志著自然語言處理(NLP)從傳統基于規則和統計的方法轉向基于深度學習的分布式表示方法。


Word2Vec 的核心思想

1. 分布式表示

  • 傳統方法:將詞語表示為獨熱編碼(One-Hot),例如詞匯表大小為 V 時,每個詞的向量維度為 V × 1,且只有一個位置為 1,其余為 0。這種表示方式稀疏且無法捕捉語義關系。
  • Word2Vec:通過神經網絡將詞語映射到低維稠密向量(例如 100 維、300 維),這些向量能夠捕捉語義和句法關系。例如:
    • 語義相似性:king - man + woman ≈ queen
    • 句法關系:Paris - France + Italy ≈ Rome

2. Word2Vec 的兩種模型架構

左邊CBOW,右邊skip-gram

在這里插入圖片描述

CBOW 連續詞袋模型

目標:根據上下文詞預測中心詞。

  • 輸入:多個上下文詞的 One-Hot 向量(平均后作為隱藏層輸入)。

  • 輸出:中心詞的概率分布。
    P(wt∣wt?1,wt?2,…,wt+n)P(w_t \mid w_{t-1}, w_{t-2}, \dots, w_{t+n}) P(wt?wt?1?,wt?2?,,wt+n?)

模型結構

  1. 輸入層:上下文詞的 One-Hot 向量(維度 C×V,其中 C 是窗口大小)。
  2. 投影層:
    • 通過嵌入矩陣 W*(維度 V×N*),將每個上下文詞的 One-Hot 向量轉換為嵌入向量(維度 N×1)。
    • 對所有上下文詞的嵌入向量求平均,得到隱藏層向量 h(維度 N×1)。
  3. 輸出層:
    • 通過嵌入矩陣 W′(維度 N×V),將隱藏層向量 hh 轉換為輸出層的得分(維度 1×V)。
    • 使用 Softmax 將得分轉換為概率分布

在這里插入圖片描述

在這里插入圖片描述

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim# 設置張量數據類型為 32 位浮點數
dtype = torch.FloatTensor# 1. 準備語料庫
sentences = ["i like dog","i like cat","i like animal","dog cat animal","apple cat dog like","cat like fish","dog like meat","i like apple","i hate apple","i like movie book music apple","dog like bark","dog friend cat"
]# 2. 構建詞匯表及詞典
# 將所有句子合并為一個詞列表,并去重
word_list = list(set(" ".join(sentences).split()))
print("詞匯表:", word_list)# 構建詞 → ID 和 ID → 詞 的雙向映射
word2id = {word: i for i, word in enumerate(word_list)}
id2word = {i: word for i, word in enumerate(word_list)}
print("詞 → ID 映射:", word2id)# 3. 構建 CBOW 訓練數據
# 目標:根據上下文詞預測中心詞
cbow_data = []
for sentence in sentences:words = sentence.split()for i in range(1, len(words) - 1):  # 跳過首尾詞,只處理中間詞context = [word2id[words[i - 1]], word2id[words[i + 1]]]  # 上下文詞(前后各1個)target = word2id[words[i]]  # 中心詞cbow_data.append([context, target])print("示例訓練數據 (上下文詞索引, 中心詞索引):")
print(cbow_data[:5])  # 打印前5個樣本# 4. 隨機批次生成函數
def random_batch(data, batch_size=3):"""從訓練數據中隨機抽取 batch_size 個樣本參數:data: 訓練數據,格式為 [[上下文詞索引], 中心詞索引]batch_size: 批次大小返回:input_batch: 上下文詞索引組成的張量 [batch_size, 2]label_batch: 中心詞索引組成的張量 [batch_size]"""random_inputs = []random_labels = []# 隨機選擇 batch_size 個樣本的索引random_index = np.random.choice(range(len(data)), batch_size, replace=False)for i in random_index:random_inputs.append(data[i][0])  # 上下文詞random_labels.append(data[i][1])  # 中心詞return torch.LongTensor(random_inputs), torch.LongTensor(random_labels)# 5. 模型參數
vocab_size = len(word_list)  # 詞匯表大小
embedding_size = 2  # 詞向量維度(可調,此處設為2便于可視化)# 6. 定義 CBOW 模型
class CBOW(nn.Module):def __init__(self):super(CBOW, self).__init__()# 嵌入層:將詞索引轉換為低維稠密向量self.embed = nn.Embedding(vocab_size, embedding_size)# 輸出層:將上下文詞向量的平均值映射到詞匯表大小self.output = nn.Linear(embedding_size, vocab_size)def forward(self, input_batch):"""前向傳播邏輯參數:input_batch: [batch_size, 2],每個樣本包含兩個上下文詞的索引返回:output: [batch_size, vocab_size],每個詞的概率分布"""# 1. 嵌入層:將上下文詞索引轉換為嵌入向量 [batch_size, 2, embedding_size]x = self.embed(input_batch)# 2. 取上下文詞向量的平均值 [batch_size, embedding_size]x = torch.mean(x, dim=1)# 3. 輸出層:線性變換到詞匯表大小 [batch_size, vocab_size]x = self.output(x)return x# 7. 實例化模型、損失函數和優化器
model = CBOW()
criterion = nn.CrossEntropyLoss()  # 分類損失
optimizer = optim.Adam(model.parameters(), lr=0.001)  # 優化器# 8. 訓練循環
for epoch in range(5000):# 1. 生成隨機批次數據input_batch, label_batch = random_batch(cbow_data)# 2. 前向傳播output = model(input_batch)  # [batch_size, vocab_size]# 3. 計算損失loss = criterion(output, label_batch)# 4. 反向傳播optimizer.zero_grad()  # 清空梯度loss.backward()  # 反向傳播計算梯度optimizer.step()  # 更新參數# 5. 打印訓練進度if (epoch + 1) % 1000 == 0:print(f"Epoch: {epoch + 1}/5000, Loss: {loss.item():.4f}")# 9. 查看訓練后的詞向量
with torch.no_grad():weights = model.embed.weight.data.numpy()  # 獲取嵌入層權重for i, word in enumerate(word_list):print(f"{word} 的詞向量: {weights[i]}")
Skip-gram

給定一個中心詞,預測其上下文詞(即周圍的詞)

  • 輸入:一個中心詞的 One-Hot 向量。
  • 輸出:上下文詞的概率分布(通過 Softmax 計算)

模型結構

  1. 輸入層:中心詞的 One-Hot 向量(維度為V×1)。
  2. 投影層:
    • 通過嵌入矩陣 WW(維度 V×N,其中 N 是嵌入維度),將 One-Hot 向量轉換為嵌入向量(維度 N×1)。
    • 公式:h=WTx,其中x 是輸入的 One-Hot 向量。
  3. 輸出層:
    • 通過另一個嵌入矩陣 W′(維度 N×V),將嵌入向量轉換為輸出層的得分(維度 1×V)。
    • 公式:u=h?W′。
    • 使用 Softmax 將得分轉換為概率分布

在這里插入圖片描述

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import math# 定義數據類型為浮點數
dtype = torch.FloatTensor# 語料庫,包含訓練模型的句子
sentences = ["i like dog", "i like cat", "i like animal","dog cat animal", "apple cat dog like", "cat like fish","dog like meat", "i like apple", "i hate apple","i like movie book music apple", "dog like bark", "dog friend cat"
]# 將所有句子拼接為一個字符串并按空格分詞
word_sequence = ' '.join(sentences).split()
# 獲取詞匯表中的所有唯一詞
word_list = list(set(word_sequence))
print("詞匯表(word_list):", word_list)# 創建詞典,詞匯表中的每個詞都分配一個唯一的索引
word2id = {w: i for i, w in enumerate(word_list)}
id2word = {i: w for w, i in word2id.items()}  # 用于根據索引還原詞
print("詞典(word2id):", word2id)# 詞匯表大小
voc_size = len(word_list)
# 定義嵌入維度(嵌入向量的大小)為2
embedding_size = 2
# 每次訓練的批量大小
batch_size = 5# 創建 Skip-gram 模型的訓練數據
skip_grams = []  # 訓練數據:[中心詞ID, 上下文詞ID]
for i in range(len(word_sequence)):# 當前詞作為中心詞target = word2id[word_sequence[i]]# 獲取上下文詞(窗口大小為1)left_context = word2id[word_sequence[i - 1]] if i > 0 else Noneright_context = word2id[word_sequence[i + 1]] if i < len(word_sequence) - 1 else None# 將目標詞與上下文詞配對if left_context:skip_grams.append([target, left_context])  # [中心詞ID, 左側詞ID]if right_context:skip_grams.append([target, right_context])  # [中心詞ID, 右側詞ID]# 打印生成的 Skip-gram 數據示例
print("生成的 Skip-gram 數據示例(前5條):")
for i in range(5):center_word = id2word[skip_grams[i][0]]context_word = id2word[skip_grams[i][1]]print(f"[中心詞: {center_word}, 上下文詞: {context_word}]")# 定義隨機批量生成函數
def random_batch(data, size):"""從 skip_grams 數據中隨機選擇 size 個樣本,生成 one-hot 編碼的輸入和標簽"""random_inputs = []  # 輸入批次(one-hot 編碼)random_labels = []  # 標簽批次(上下文詞ID)# 從數據中隨機選擇 size 個索引random_index = np.random.choice(range(len(data)), size, replace=False)# 根據隨機索引生成輸入和標簽批次for i in random_index:# 目標詞 one-hot 編碼# np.eye(voc_size) 創建 voc_size x voc_size 的單位矩陣random_inputs.append(np.eye(voc_size)[data[i][0]])# 上下文詞的索引作為標簽random_labels.append(data[i][1])return random_inputs, random_labels# 定義 Word2Vec 模型
class Word2Vec(nn.Module):def __init__(self):super(Word2Vec, self).__init__()# 定義詞嵌入矩陣 W,大小為 (voc_size, embedding_size)self.W = nn.Parameter(torch.rand(voc_size, embedding_size)).type(dtype)# 定義上下文矩陣 WT,大小為 (embedding_size, voc_size)self.WT = nn.Parameter(torch.rand(embedding_size, voc_size)).type(dtype)# 前向傳播def forward(self, x):# 通過嵌入矩陣 W 得到詞向量weight_layer = torch.matmul(x, self.W)  # [batch_size, embedding_size]# 通過上下文矩陣 WT 得到輸出output_layer = torch.matmul(weight_layer, self.WT)  # [batch_size, voc_size]return output_layer# 創建模型實例
model = Word2Vec()# 定義損失函數為交叉熵損失
criterion = nn.CrossEntropyLoss()
# 使用 Adam 優化器
optimizer = optim.Adam(model.parameters(), lr=0.001)# 訓練模型
for epoch in range(10000):# 獲取隨機的輸入和目標inputs, labels = random_batch(skip_grams, batch_size)# 轉為張量input_batch = torch.Tensor(inputs)label_batch = torch.LongTensor(labels)optimizer.zero_grad()  # 梯度清零output = model(input_batch)  # 前向傳播# 計算損失函數loss = criterion(output, label_batch)# 每 1000 輪打印一次損失if (epoch + 1) % 1000 == 0:print('Epoch:', '%04d' % (epoch + 1), 'cost =', '{:.6f}'.format(loss))loss.backward()  # 反向傳播optimizer.step()  # 參數更新# 訓練完成后,打印學習到的詞向量
print("\n學習到的詞向量(嵌入矩陣 W):")
for i in range(voc_size):print(f"{id2word[i]}: {model.W.data[i].numpy()}")# 計算詞向量之間的余弦相似度
def cosine_similarity(vec1, vec2):return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))print("\n詞向量的余弦相似度示例:")
print(f"i 和 like 的相似度: {cosine_similarity(model.W.data[word2id['i']].numpy(), model.W.data[word2id['like']].numpy())}")
print(f"like 和 dog 的相似度: {cosine_similarity(model.W.data[word2id['like']].numpy(), model.W.data[word2id['dog']].numpy())}")
print(f"dog 和 cat 的相似度: {cosine_similarity(model.W.data[word2id['dog']].numpy(), model.W.data[word2id['cat']].numpy())}")
Gensim 中 Word2Vec 使用

1. 安裝 Gensim

pip install gensim

2. 常用參數

參數名默認值說明
sentences無(必需)輸入語料,應為分詞后的句子列表,如 [["word1"], ["word2"]]。大語料建議使用 LineSentence 流式讀取。
vector_size100詞向量的維度,常用 100、200、300。維度越高表達能力越強,但需要更多數據和計算資源。
window5上下文窗口大小,即目標詞前后最多考慮的詞數。一般設置為 3~10。
min_count5忽略出現次數少于該值的詞語。用于過濾低頻詞,小語料可設為 1 或 2。
sg0訓練算法:0 表示使用 CBOW,1 表示使用 Skip-gram。Skip-gram 更適合小語料和低頻詞。
workers3訓練時使用的 CPU 線程數,建議根據 CPU 核心數設置以提升訓練速度。
alpha0.025初始學習率,訓練過程中會線性衰減。一般無需調整。
sample1e-3高頻詞的下采樣閾值,用于減少常見詞(如“的”、“是”)的訓練樣本,提升效果和速度。
hs0是否使用層次 Softmax:1 表示使用,0 表示不使用。通常與負采樣互斥。
negative5負采樣數量,0 表示不使用負采樣。推薦值為 5~20,適合大規模語料。
seed1隨機數種子,設置后可保證訓練結果可重現。

model.wv 的常用且重的方法

  • model.wv.most_similar(positive, negative, topn)
    查找與給定詞語最相似的詞,支持類比推理。

    model.wv.most_similar('apple')  # 找與 apple 相似的詞
    model.wv.most_similar(positive=['king', 'woman'], negative=['man'])  # king - man + woman ≈ queen
    
  • model.wv.similarity(word1, word2)
    計算兩個詞之間的語義相似度(余弦相似度),返回值在 -1 到 1 之間。

    model.wv.similarity('man', 'woman')  # 返回如 0.78
    
  • model.wv.doesnt_match(list_of_words)
    找出列表中語義上“最不合群”的詞。

    model.wv.doesnt_match(['cat', 'dog', 'mouse', 'table'])  # 返回 'table'
    
  • model.wv[word]model.wv.get_vector(word)
    獲取某個詞的詞向量(numpy 數組)。

    vec = model.wv['hello']  # 獲取 'hello' 的向量
    
  • model.wv.key_to_index
    獲取詞到索引的映射字典,可用于查看詞在詞匯表中的位置。

    index = model.wv.key_to_index['python']
    
  • model.wv.index_to_key
    獲取索引到詞的映射列表,與 key_to_index 對應。

    word = model.wv.index_to_key[100]  # 獲取索引為 100 的詞
    
  • model.wv.save()model.wv.load()
    保存或加載訓練好的詞向量,便于后續使用或共享。

    model.wv.save("vectors.kv")
    from gensim.models import KeyedVectors
    wv = KeyedVectors.load("vectors.kv")
    
概念定義示例
詞向量(Word Vector)將一個詞語表示為一個低維稠密向量,捕捉其語義信息“貓” → [0.8, -0.3, 0.5]
句向量(Sentence Vector)將一個完整句子表示為一個向量,反映整個句子的語義“我愛學習” → [0.6, 0.1, -0.4, ...]

【示例】

sentence = "Word embedding is the collective name for a set of language modeling and feature learning techniques in natural language processing (NLP) where words or phrases from the vocabulary are mapped to vectors of real numbers."需要把這句話通過api的方法,轉成句向量
from gensim.models import Word2Vec
import numpy as np
import resentence = "Word embedding is the collective name for a set of language modeling and feature learning techniques in natural language processing (NLP) where words or phrases from the vocabulary are mapped to vectors of real numbers."# 1.文本處理
def preprocess(text):text = re.sub(r'[^a-zA-Z0-9\s]', '', text)text = text.lower()text = text.split()return textwords = preprocess(sentence)
print('分詞后:', words)# 2.訓練模型
model = Word2Vec(sentences=[words],vector_size=100,window=5,min_count=1,    # 所有詞都保留workers=1
)
# 3.獲得句向量
def sentence2vec(sentence,model,vector_size=100):words = preprocess(sentence)word_vectors = []for word in words:if word in model.wv:# 確保詞在詞匯表中word_vectors.append(model.wv[word])if len(word_vectors) == 0:return np.zeros(vector_size)sentence_vector = np.mean(word_vectors, axis=0)return sentence_vectorvec = sentence2vec(sentence, model,vector_size=100)
print('句向量形狀:', vec.shape)
print('句向量:', vec)

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

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

相關文章

單詞記憶-輕松記憶10個實用英語單詞(13)

1. board含義&#xff1a;板子&#xff1b;董事會&#xff1b;登機 讀音標注&#xff1a;/b??rd/ 例句&#xff1a;Write your name on the board. 譯文&#xff1a;把你的名字寫在板上。 衍生含義&#xff1a;董事會&#xff08;如“board of directors”&#xff09;&#…

Spring循環依賴源碼調試詳解,用兩級緩存代替三級緩存

Spring循環依賴源碼詳解&#xff0c;改用兩級緩存并實驗 背景 最近一直在研究Spring的循環依賴&#xff0c;發現好像兩級緩存也能解決循環依賴。 關于為何使用三級緩存&#xff0c;大致有兩個原因 對于AOP的類型&#xff0c;保證Bean生命周期的順序 對于有AOP代理增強的類型&am…

亞馬遜BALL PIT球池外觀專利侵權指控?不侵權意見書助力4條鏈接申訴成功!

兒童球池作為玩具品類中常見的一款產品&#xff0c;能夠給兒童提供游樂的安全空間&#xff0c;深受亞馬遜平臺用戶的喜愛。然而在近期&#xff0c;賽貝收到了部分亞馬遜賣家的咨詢&#xff0c;原因是他們在售的兒童球池產品鏈接被美國外觀專利USD1009203S&#xff08;下稱203專…

開源,LangExtract-Python庫用LLM從非結構化文本提取結構化信息

摘要&#xff1a; LangExtract是一個Python庫&#xff0c;利用大語言模型&#xff08;LLM&#xff09;根據用戶定義指令從非結構化文本文檔中提取結構化信息。它具備精確源定位、可靠結構化輸出、長文檔優化、交互式可視化、靈活LLM支持、適應任意領域等特點。可通過幾行代碼快…

如何根據團隊技術能力選擇最適合的PHP框架?

作為一名PHP開發者&#xff0c;面對眾多的PHP框架&#xff0c;你是否曾感到選擇困難&#xff1f;Laravel、Symfony、CodeIgniter、ThinkPHP…每個框架都有其特色和優勢&#xff0c;但沒有最好的框架&#xff0c;只有最適合的框架。而選擇合適框架的關鍵因素之一&#xff0c;就是…

多人同時導出 Excel 導致內存溢出

1、問題根因分析多人同時導出Excel導致內存溢出&#xff08;OOM&#xff09;的核心原因是&#xff1a;在短時間內&#xff0c;大量數據被加載到JVM堆內存中&#xff0c;且創建了大量大對象&#xff08;如Apache POI的Cell、Row、Sheet對象&#xff09;&#xff0c;超過了堆內存…

深入 RAG(檢索增強生成)系統架構:如何構建一個能查資料的大語言模型系統

&#x1f407;明明跟你說過&#xff1a;個人主頁 &#x1f3c5;個人專欄&#xff1a;《深度探秘&#xff1a;AI界的007》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目錄 一、前言 1、LLM 的局限&#xff1a;模型知識“封閉” vs 現實知識…

linux tftpboot燒寫地址分析

1&#xff0c;loadaddr 是一個環境變量&#xff0c;用于指定文件&#xff08;如內核鏡像、設備樹等&#xff09;加載到內存的起始地址。setenv loadaddr 0x82000000setenv loadaddr 0x80008000saveenv //.保存配置將 loadaddr 設置為 0x82000000&#xff0c;表示后續文件將加載…

硬件工程師9月實戰項目分享

目錄 簡介 人員情況 實戰項目簡介 功能需求 需求分析 方案設計 電源樹設計 時鐘樹設計 主芯片外圍設計 接口設計 模擬鏈路設計 PCB設計檢查要點 測試方案設計 硬件測試培訓 測試代碼學習 培訓目標 掌握基本的硬件設計流程 掌握以FPGA為核心的硬件設計業務知識 …

力扣刷題——59.螺旋矩陣II

力扣刷題——59.螺旋矩陣II 題目 給你一個正整數 n &#xff0c;生成一個包含 1 到 n2 所有元素&#xff0c;且元素按順時針順序螺旋排列的 n x n 正方形矩陣 matrix 。示例 1&#xff1a;輸入&#xff1a;n 3 輸出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]]示例 2&#xff1a; 輸…

win11系統還原點恢復系統

背景 系統換位bug11后&#xff0c;真的是各種以前的操作和設置找不到&#xff0c;太煩了&#xff0c;我是沒想到&#xff0c;連系統恢復還原點都這么難找。然后搜了一圈都是恢復系統之類的&#xff0c;真的崩潰。只好自己記錄了。 ?內容找到設置—>系統–>系統信息系統信…

DHCP 原理與配置(一)

應用場景隨著網絡規模的不斷擴大&#xff0c;網絡復雜度不斷提升&#xff0c;網絡中的終端設備例如主機、手機、 平板等&#xff0c;位置經常變化。終端設備訪問網絡時需要配置IP地址、網關地址、DNS服務器 地址等。采用手工方式為終端配置這些參數非常低效且不夠靈活。 IETF于…

SARibbon的編譯構建及詳細用法

目錄 1.1 源碼構建 1.2 搭建項目 1.3 詳細用法 1.4 不同風格 1.5 完整代碼 引言:SARibbon是一個專門為Qt框架設計的開源Ribbon風格界面控件庫,它模仿了微軟Office和WPS的Ribbon UI風格,適用于需要復雜菜單和工具欄的大型桌面程序。本文從源碼編譯構建到詳細使用,做了一…

CSS【詳解】性能優化

精簡 CSS移除未使用的 CSS&#xff08;“死代碼”&#xff09;&#xff0c;可借助工具如 PurgeCSS、UnCSS 自動檢測并刪除未被頁面使用的樣式。避免重復樣式&#xff0c;通過提取公共樣式&#xff08;如 mixin 或公共類&#xff09;減少代碼冗余。利用預處理器&#xff08;Sass…

Flutter 線程模型詳解:主線程、異步與 Isolate

一、主線程&#xff1a;默認的執行環境 所有代碼默認運行在主線程。下面的例子展示了一個會阻塞主線程的錯誤示范&#xff1a; import package:flutter/material.dart;void main() {runApp(const MyApp()); }class MyApp extends StatelessWidget {const MyApp({super.key});ov…

ChartDB:可視化數據庫設計工具私有化部署

ChartDB:可視化數據庫設計工具私有化部署一、什么是ChartDB ChartDB 是一款基于 Web 的開源數據庫可視化工具&#xff0c;專為簡化數據庫設計與管理流程而開發。以下是其核心特性與功能概述: 1、核心功能 智能查詢可視化?&#xff1a;通過單條 SQL 查詢即可生成數據庫架構圖&a…

單片機-FreeRTOS(ing)

目錄 一、基礎介紹 1.1 調度策略 1.1.1 調度方式 1.1.2 調度器 1.2 任務以及優先級 1.2.1 任務與協程 1.2.2 任務狀態 1.2.3 任務優先級 1.2.4 任務優先級分配方案 1.3 任務間通信 - 信號量 1.3.1 信號量 1.3.2 任務間計數信號量的實現 1.3.3 中斷方式計數信號量的…

為什么調用API總返回404,該如何調試

當調用一個應用程序接口&#xff08;API&#xff09;時&#xff0c;持續地收到“404 未找到”的錯誤&#xff0c;其核心原因在于客戶端發起的“請求”&#xff0c;未能成功地&#xff0c;匹配到服務器上任何一個“真實存在”的、可供訪問的“資源路徑”。這本質上&#xff0c;是…

醫療信息化自主可控轉型的實踐探索 —— 以常德二院為例

目錄 頭雁領航 - 激發醫療新質生產力 核心支撐 - 電科金倉奠定數據底座 生態共建 - 攜手護航醫療信創發展 信創產業發展是國家經濟數字化轉型、提升產業鏈發展的關鍵&#xff0c;是科技自立自強的核心基座&#xff0c;其本質是實現中國信息化產業的自主可控。醫療信創作為關…

Gin傳參和接收參數的方式

Gin查詢參數和接收參數的方式 常用 Gin 綁定方法對比方法用途特點c.Bind()自動識別 Content-Type最通用&#xff0c;根據請求頭自動選擇綁定方式c.ShouldBindJSON()只綁定 JSON強制使用 JSON 格式&#xff0c;類型明確c.ShouldBindXML()只綁定 XML強制使用 XML 格式c.ShouldBin…