自然語言處理——06 遷移學習(上)

1 fasttext工具介紹

1.1 介紹

  • fasttext 是 Facebook AI Research(FAIR)開發的開源 NLP 工具包,專門用來解決文本相關任務,比如情感分析、文本分類(判斷新聞屬于體育/財經等)、識別“人名/地名”這類實體,甚至輔助機器翻譯;

  • 其核心功能聚焦 2 件事:

    • 文本分類:給文本貼標簽、分類別(比如判斷評論是“正面”還是“負面”);

    • 訓練詞向量:把詞語轉換成計算機能理解的數字向量,捕捉詞語語義(比如 “國王”和“王后”的向量,會比“國王”和“蘋果”的向量更接近);

  • 最大優勢:正如其名。它能在保證較高精度的前提下,大幅加速訓練和預測過程,處理大規模文本數據時效率更高;

  • 優勢原因:

    • fasttext工具包中內含的fasttext模型,模型結構簡單
    • 使用fasttext模型訓練詞向量時,使用層次softmax結構,來提升超多類別下的模型性能;
    • 采用負采樣(negative sampling),每次訓練僅僅更新一小部分的權重,降低梯度下降過程中的計算量;
    • fasttext模型過于簡單無法捕捉詞序特征,可采用n-gram特征提取文本特征以彌補模型缺陷提升精度。

1.2 安裝

  • 安裝 Python 3.8.12 的 Conda 環境:

    conda create -n py3812 python=3.8.12
    
  • 激活環境:

    conda activate py3812
    
  • 若直接安裝官方源碼版,由于此處使用的是 Windows 操作系統,需要安裝 Visual Studio 或配置編譯環境,所以選擇安裝fasttext-wheel預編譯輪子版:

    pip install fasttext-wheel
    
    • 推薦使用 Linux 系統,按照下面的方式安裝:

      git clone https://github.com/facebookresearch/fastText.git
      cd fastText
      sudo pip install .
      
  • 驗證:

    (py3812) C:\Windows\System32>python
    Python 3.8.12 (default, Oct 12 2021, 03:01:40) [MSC v.1916 64 bit (AMD64)] :: Anaconda, Inc. on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import fasttext
    >>>
    

1.3 fasttext模型架構

1.3.1 三層架構

  • fasttext 架構和 Word2Vec 里的CBOW 模型很像,但目標不同:

    • CBOW 是“預測中間詞”(比如用上下文猜中間的詞);

    • fasttext 是“預測文本標簽/類別”(比如判斷文本是“體育新聞”還是“財經新聞”);

  • fasttext 模型分 3 層:

    • 輸入層:把文本拆成可計算的向量

      • 輸入的是文檔 embedding 后的向量,而且不只是單個詞,還包含N-gram 特征

      • 作用:彌補模型“太簡單,抓不住詞序”的問題,用 N-gram 保留局部短語信息;

    • 隱藏層:平均匯總

      • 對輸入層的所有向量(單個詞 + N-gram 等),直接求和、平均,得到一個匯總后的向量;

      • 特點:計算極簡單,沒有復雜的變換,所以速度快,但也會損失一些細節;

    • 輸出層:預測文本的標簽/類別

      • 輸出的是文檔對應的 label(標簽/類別),比如“正面情感”“體育分類”等;

      • 關鍵優化:為了讓多分類更高效,沒用傳統的 Softmax,而是用層次 Softmax

  • 層次 Softmax(Hierarchical Softmax)

    • 傳統 Softmax 計算多分類概率時,要遍歷所有類別算概率,類別越多越慢。fasttext 用哈夫曼樹優化;

    • 把類別建成一棵樹,葉子節點是類別。計算概率時,只需要從根到葉子走一條路徑,不用遍歷所有類別,大幅減少計算量,讓預測/訓練速度飛起。

1.3.2 層次 Softmax

  • 為什么層次 Softmax 比普通 Softmax 計算概率分布要快?

    • 普通 Softmax 計算多分類概率時,要遍歷所有類別算指數、歸一化,類別越多越慢;

    • 層次 Softmax 用**哈夫曼樹(帶權二叉樹)**重構計算方式,把“遍歷所有類別”改成“走一條路徑”,直接砍半計算量——這是它“更快”的本質;

    • 哈夫曼樹:“讓高頻類別‘更近’”

      • 所有單詞(或類別)掛在葉子節點,樹的構建按照“出現頻率”分配:頻率越高的單詞,離根節點越近(路徑越短)

      • 效果:高頻詞計算時,少走很多“彎路”,整體平均計算步驟更少。

    • 概率計算:從遍歷所有到走一條路

      • 普通 Softmax(以計算單詞w2w_2w2?概率為例):分母要把所有VVV個類別的指數都算一遍,類別越多,計算量爆炸(比如10萬類別,就要算10萬次指數);
        p(w2)=evw2∑i=1Vevwip(w2) = \frac{e^{v_{w2}}}{\sum_{i=1}^V e^{v_{w_i}}} p(w2)=i=1V?evwi??evw2??

      • 層次Softmax(同樣算w2w_2w2?概率):把“算單個單詞概率”,拆成“走哈夫曼樹路徑上的多個二分類概率乘積”

        在這里插入圖片描述

        • 比如w2w_2w2?的路徑是“根→節點A→節點B→葉子w2w_2w2?”,每一步都是“左/右子樹”的二分類概率(類似“選左的概率是0.6,選右是0.4”),最后把這些概率相乘,就是w2w_2w2?的概率;

        • 效果:不需要遍歷所有類別,只需要算“路徑長度”次二分類(路徑長度遠小于總類別數VVV),計算量直接砍半;

  • 例:

    • 哈夫曼樹結構

      在這里插入圖片描述

      • 假設有3個詞w1w_1w1?w2w_2w2?w3w_3w3?,由于每個中間節點是一個二分類,則p(left)+p(right)=1p(left)+p(right)=1p(left)+p(right)=1
      • 如圖:w3w_3w3?=0.4、w1=0.6?0.5=0.3w_1=0.6*0.5=0.3w1?=0.6?0.5=0.3w2=0.6?0.5=0.3w_2=0.6*0.5=0.3w2?=0.6?0.5=0.3w1+𝑤2+𝑤3=1w_1+ 𝑤_2+𝑤_3 = 1w1?+w2?+w3?=1
    • 普通Softmax:要算ew1+ew2+ew3e^{w_1}+e^{w_2}+e^{w_3}ew1?+ew2?+ew3?,然后再歸一化;

    • 層次Softmax:算w2w_2w2?概率時,走“根→右子樹→左子樹→w2w_2w2?”,概率是 “根選右(0.6)×下一層選左(0.5)×再下一層選左(0.3)”,最后相乘得到w2w_2w2?的概率;

  • 總結:

    • 層次Softmax把**“多分類問題”拆解成“多個二分類問題的乘積”**,不需要遍歷所有類別,計算量隨“哈夫曼樹深度”線性增長(而普通Softmax是隨類別數VVV線性增長);

    • 代價:精度會略降(因為路徑拆分后,不是直接算所有類別概率),但換來的是速度大幅提升,尤其類別數極多(比如10萬+類別)時,優勢碾壓。

1.3.3 哈夫曼樹的簡介、構建和訓練

  • 哈夫曼樹的本質是帶權路徑最短的二叉樹

    • WPL(Weighted Path Length):帶權路徑長度
      WPL=∑(節點權重×該節點到根的路徑長度)WPL = \sum (\text{節點權重} \times \text{該節點到根的路徑長度}) WPL=(節點權重×該節點到根的路徑長度)

    • WPL最小的二叉樹就是哈夫曼樹

    • 例:葉子節點是 3、5、7、9,構建哈夫曼樹后:WPL=3×3+5×3+7×2+9×1=47WPL = 3 \times 3 + 5 \times 3 + 7 \times 2 + 9 \times 1 = 47WPL=3×3+5×3+7×2+9×1=47,路徑越短,權重×長度的和越小;

      在這里插入圖片描述

  • 例:假設有四個Label分別為:A~D,統計其在語料庫出現的頻數為A(5次)、B(9次)、C(7次)、D(3次)

    • 步驟1:初始化森林。每個Label(A/B/C/D)單獨成樹,權重是它們的出現頻率(5、9、7、3);

      在這里插入圖片描述

    • 步驟2:選權重最小的兩棵樹合并

      • 第一次合并:選最小的 D(3) 和 A(5),合并成新樹,權重=3+5=8。此時森林里剩下:B(9)、C(7)、新樹(8);

        在這里插入圖片描述

      • 第二次合并:選次小的 C(7) 和 新樹(8),合并成新樹,權重=7+8=15。此時森林里剩下:B(9)、新樹(15);

        在這里插入圖片描述

      • 第三次合并:合并 B(9) 和 新樹(15),權重=9+15=24。此時森林只剩1棵樹——哈夫曼樹構建完成!

        在這里插入圖片描述

  • 哈夫曼樹建好后,如何訓練哈夫曼樹?

    • 構建好霍夫曼樹后,所有單詞都會掛在葉子節點上;

    • 給每個葉子節點創建哈夫曼編碼:給每個節點編二進制碼

      • 規則:左分支記0,右分支記1,從根到葉子的路徑上的0/1序列,就是該葉子節點的哈夫曼編碼;

      • 例子:D的路徑是“根→右→右→左”,編碼可能是:110;

        在這里插入圖片描述

    • 訓練模型:用路徑概率乘積優化參數

      • 任務:比如用上下文預測單詞D,需要從根節點出發,沿著D的編碼路徑(比如110)走;

      • 計算:每一步是二分類概率(走左/右的概率),把這些概率相乘,用極大似然估計(讓預測概率盡可能大)反向更新模型參數(比如中間節點的權重);

      在這里插入圖片描述

    極大似然估計(Maximum Likelihood Estimation,MLE)是一種在統計學和機器學習中廣泛使用的參數估計方法,它的目標是利用已知的樣本數據,來估計模型中未知參數的值,使得模型產生這些樣本數據的概率最大;

    基本思想

    • 假設我們有一組來自某個概率分布的樣本數據,而這個概率分布由一些未知參數決定;
    • 極大似然估計的核心想法是,找到這樣一組參數值,在這組參數值下,我們現有的樣本數據出現的可能性最大;
    • 比如,我們拋一枚硬幣,不知道它是否是均勻的(即不知道正面朝上的概率 ppp 是多少),現在拋了10次,得到7次正面,3次反面。按照極大似然估計的思想,我們要找到一個 ppp 的值,使得出現 “7次正面,3次反面” 這種結果的概率最大;

    計算步驟

    1. 確定似然函數
      • 對于離散型隨機變量,設樣本 X1,X2,…,XnX_1, X_2, \ldots, X_nX1?,X2?,,Xn? 來自概率質量函數為 P(X;θ)P(X; \theta)P(X;θ) 的總體(其中 θ\thetaθ 是未知參數),似然函數 L(θ)L(\theta)L(θ) 就是在參數 θ\thetaθ 下,樣本出現的聯合概率,即 L(θ)=∏i=1nP(Xi;θ)L(\theta)=\prod_{i = 1}^{n}P(X_i; \theta)L(θ)=i=1n?P(Xi?;θ)
      • 對于連續型隨機變量,設樣本 X1,X2,…,XnX_1, X_2, \ldots, X_nX1?,X2?,,Xn? 來自概率密度函數為 f(X;θ)f(X; \theta)f(X;θ) 的總體,似然函數 L(θ)=∏i=1nf(Xi;θ)L(\theta)=\prod_{i = 1}^{n}f(X_i; \theta)L(θ)=i=1n?f(Xi?;θ)
    2. 對似然函數取對數:取對數后的對數似然函數 ln?L(θ)\ln L(\theta)lnL(θ) 與原似然函數在相同的參數值處取得極值,而且取對數后可以將連乘運算轉化為連加運算,簡化計算,即 ln?L(θ)=∑i=1nln?P(Xi;θ)\ln L(\theta)=\sum_{i = 1}^{n}\ln P(X_i; \theta)lnL(θ)=i=1n?lnP(Xi?;θ)(離散型)或 ln?L(θ)=∑i=1nln?f(Xi;θ)\ln L(\theta)=\sum_{i = 1}^{n}\ln f(X_i; \theta)lnL(θ)=i=1n?lnf(Xi?;θ)(連續型);
    3. 求對數似然函數的導數:對 ln?L(θ)\ln L(\theta)lnL(θ) 關于未知參數 θ\thetaθ 求導;
    4. 令導數為0,求解參數:通過求解導數為0的方程,得到使似然函數最大的參數估計值 θ^\hat{\theta}θ^

    示例:以拋硬幣為例,設正面朝上的概率為 ppp,拋 nnn 次硬幣,出現 kkk 次正面。每次拋硬幣是獨立的伯努利試驗,其概率質量函數為 P(X=1;p)=pP(X = 1; p)=pP(X=1;p)=p(正面朝上,X=1X = 1X=1 ),P(X=0;p)=1?pP(X = 0; p)=1 - pP(X=0;p)=1?p(反面朝上,X=0X = 0X=0 );

    • 確定似然函數:拋 nnn 次硬幣,出現 kkk 次正面的似然函數為 L(p)=Cnkpk(1?p)n?kL(p)=C_{n}^{k}p^{k}(1 - p)^{n - k}L(p)=Cnk?pk(1?p)n?k,其中 Cnk=n!k!(n?k)!C_{n}^{k}=\frac{n!}{k!(n - k)!}Cnk?=k!(n?k)!n!? 是組合數;
    • 取對數:對數似然函數為 ln?L(p)=ln?Cnk+kln?p+(n?k)ln?(1?p)\ln L(p)=\ln C_{n}^{k}+k\ln p+(n - k)\ln(1 - p)lnL(p)=lnCnk?+klnp+(n?k)ln(1?p)
    • 求導數:對 ln?L(p)\ln L(p)lnL(p) 關于 ppp 求導,得到 dln?L(p)dp=kp?n?k1?p\frac{d\ln L(p)}{dp}=\frac{k}{p}-\frac{n - k}{1 - p}dpdlnL(p)?=pk??1?pn?k?
    • 令導數為0求解:令 dln?L(p)dp=0\frac{d\ln L(p)}{dp}=0dpdlnL(p)?=0,解得 p^=kn\hat{p}=\frac{k}{n}p^?=nk? 。例如前面拋10次硬幣出現7次正面的情況,按照極大似然估計得到正面朝上的概率估計值為 710=0.7\frac{7}{10}=0.7107?=0.7

    在機器學習中的應用

    • 在機器學習里,極大似然估計常用于估計模型參數。比如:
    • 在邏輯回歸中,通過極大似然估計來確定模型中參數的值,使得模型對給定訓練數據的預測概率最大;
    • 在樸素貝葉斯分類器中,也利用極大似然估計來估計各類別下特征的概率,從而進行分類預測 。

1.3.4 負采樣

  • 為什么需要負采樣樣(Negative Sampling)?

    • 訓練模型時,最大的痛點是計算量爆炸
      • 神經網絡經過一個訓練樣本的訓練, 它的權重就會進行一次調整;
      • 比如利用 Skip-Gram 進行詞向量訓練,用 Softmax 算概率時,輸出層要對所有單詞 算指數、歸一化,每次訓練都要更新所有權重;
      • 假設有詞匯量 1 萬,每次訓練就要算 1 萬次指數 + 反向傳播更新 1 萬組權重,訓練速度肉眼可見地慢,根本跑不動大規模數據;
  • 而負采樣的本質是砍計算量

    • 每次訓練時,不更新所有單詞的權重,只挑一小部分“負樣本”(不需要預測正確的單詞)和“正樣本”(需要預測正確的單詞)來更新;
    • 相當于把“更新 1 萬次”砍成“更新 5 - 20 次”,直接讓訓練速度起飛;
  • 以訓練詞向量的場景為例(輸入“hello”,輸出“man”):

    • 傳統 Softmax 的問題

      • 輸入“hello”,輸出層要預測“man”是正樣本(期望輸出 1),剩下 9999 個單詞都是負樣本(期望輸出 0);

      • 用 Softmax 的話,得給這 9999 個負樣本都算概率、反向更新權重,計算量直接拉滿;

    • 負采樣的操作

      • 只挑一小部分負樣本:比如隨機選 5 個負樣本(比如“apple”“dog”“book”…),只更新這些負樣本 + 正樣本(“man”)的權重;

      • 效果:原本要更新 10000 個權重,現在只更新 6 個(5 負 + 1 正),計算量直接砍到 0.06%(比如 300 萬權重,現在只算 1800 個);

  • 負采樣的優勢

    • 訓練速度爆炸提升:少更新 99% 的權重,訓練時間直接腰斬甚至更多,大規模數據也能跑起來;

    • 模型更穩、泛化更好:加入“負樣本噪聲”(隨機選負樣本),相當于讓模型“見更多錯誤案例”,能模擬真實場景的噪聲,反而讓模型更魯棒(不容易過擬合),預測更準。

2 fasttext文本分類

2.1 文本分類介紹

  • 概念

    • 簡單說,就是給文本貼標簽、歸類:把郵件、帖子、評論、新聞……這類文本,按照規則分到對應的類別里(比如“這封郵件是垃圾郵件/正常郵件”“這條評論是正面/負面”);
    • 關鍵點: 需要有監督學習。即訓練模型時,得先給一批文本標好標簽(比如人工標“垃圾郵件”“正面評論”),模型才能學怎么分類;
  • 種類

    • 二分類

      • 特點:文本只能“非此即彼”,分到 2 個類別里的 1 個

      • 例子:判斷評論是“好評”還是“差評”;識別郵件是“垃圾郵件”還是“正常郵件”;

    • 單標簽多分類

      • 特點:文本從多個類別里選 1 個 標簽,多選一;

      • 例子:識別“人名”屬于哪個國家(比如“張三”→“中國”;“瑪麗”→“美國”);新聞分類(“體育新聞”“財經新聞”選一個);

    • 多標簽多分類

      • 特點:文本可以同時貼多個標簽,多選多;

      • 例子:一段討論“既聊美食,又聊體育、游戲”,就同時打“美食”“體育”“游戲”標簽。

2.2 使用fasttext做文本分類

2.2.1 獲取數據

  • 數據集下載地址:https://dl.fbaipublicfiles.com/fasttext/data/cooking.stackexchange.tar.gz && tar xvzf cooking.stackexchange.tar.gz

  • 本案例使用烹飪相關的數據集, 它是由 Facebook AI 實驗室提供的演示數據:

    在這里插入圖片描述

  • 每行是標簽 + 文本內容結構

    label  AAA  label  BBB text1 text2...  
    
    • 比如: label sauce label cheese How much does potato starch affect a cheese sauce recipe?
    • 這里 label sauce label cheese 是標簽(代表文本分類類別,說明文本和 “醬料、奶酪” 相關),后半句是具體問題文本;
  • 每條文本可對應多個標簽,屬于多標簽文本分類問題

2.2.2 訓練集與驗證集的劃分

  • 12404條數據作為訓練數據,3000條數據作為驗證數據:

    在這里插入圖片描述

  • 可以使用一些系統指令,取出cooking.stackexchange中的從頭開始多少行或從尾部開始多少行,分別作為訓練集和數據集,以Linux為例:

    # 12404條數據作為訓練數據
    $ head -n 12404 cooking.stackexchange.txt > cooking.train
    # 3000條數據作為驗證數據
    $ tail -n 3000 cooking.stackexchange.txt > cooking.valid
    

2.2.3 訓練模型

  • 將 PyCharm 切換至創建的 py3812 環境:

    在這里插入圖片描述

    在這里插入圖片描述

    在這里插入圖片描述

  • 以管理員權限打開 Anaconda,然后激活 py3812 環境,再安裝 jupyter:

    • 由于 Python 3.8 的版本有點老了,所以一些依賴問題需要自己處理;
    • ipykernel是一個 Python 包,在 Jupyter 生態系統中扮演著關鍵角色,它的主要作用是作為 Jupyter Notebook、JupyterLab 等交互式開發環境與 Python 解釋器之間的橋梁;
    pip install pywinpty==2.0.10
    pip install jupyter
    conda install ipykernel
    
  • 重啟 PyCharm(這同時也重啟了 Anaconda)

  • 導包:

    import fasttext
    
  • 使用 fasttext 的train_supervised方法進行文本分類模型的訓練

    # 使用fasttext的train_supervised方法進行文本分類模型的訓練
    model = fasttext.train_supervised(input="cooking_data/cooking.train")
    

2.2.4 模型的保存和重加載

# 模型的保存和重加載
model.save_model("cooking_data/model/model_cooking.bin")
model = fasttext.load_model("cooking_data/model/model_cooking.bin")
# 重加載后的模型使用方法
model.predict("Which baking dish is best to bake a banana bread ?", k=-1, threshold=0.01)
  • k=-1 表示返回所有可能分類(按預測概率排序);
  • threshold=0.01 是概率閾值,分類預測概率 ≥0.01 才會被輸出;
(('__label__baking','__label__food-safety','__label__bread','__label__substitutions','__label__equipment','__label__chicken','__label__eggs','__label__storage-method','__label__cake','__label__sauce','__label__meat','__label__coffee','__label__chocolate','__label__freezing','__label__flavor','__label__cheese'),array([0.06340391, 0.04024106, 0.0361773 , 0.03421036, 0.02819154,0.01837722, 0.01678729, 0.01484748, 0.01481829, 0.01259199,0.01250622, 0.01226074, 0.01125562, 0.01081415, 0.01021101,0.01014362]))

2.2.5 使用模型進行預測并評估

model.predict("Which baking dish is best to bake a banana bread ?")

在這里插入圖片描述

  • 標簽:__label__baking → 模型判斷文本屬于“烘焙”類別;
  • 概率:0.0634 → 模型對該分類的“置信度”,數值低,說明把握不大;
  • 預測正確,但是概率不大;
model.predict("Why not put knives in the dishwasher?")

在這里插入圖片描述

  • 預測錯誤;
# 為了評估模型到底表現如何, 下面在3000條的驗證集上進行測試
model.test("cooking_data/cooking.valid")

在這里插入圖片描述

  • 3000:驗證集樣本總數;

  • 0.148:準確率(Precision) → 模型預測為 “正確” 的樣本中,實際真正確的比例。數值低(僅 14.8%),說明模型容易 “亂分類”,很多預測的標簽是錯的;

  • 0.064:召回率(Recall) → 實際為正類的樣本中,被模型正確預測為正類的比例。數值極低(6.4%),說明大量真實正類樣本沒被模型識別出來。

  • 由此可見:訓練出來的模型準確率非常低,需要模型調優,有以下方法

    • 數據方面:重新處理數據
    • 增加訓練輪數
    • 調整學習率
    • 增加n-gram特征
    • 修改損失計算方式
    • 自動超參數調優
    • 實際生產中多標簽多分類問題的損失計算方式

2.3 fasttext模型調優

2.3.1 原始數據處理

  • 通過查看數據,可以發現數據中存在許多標點符號與單詞相連以及大小寫不統一,這些因素對我們最終的分類目標沒有益處,反而是增加了模型提取分類規律的難度,因此我們選擇將它們去除或轉化;

  • 如果使用的是 Linux 操作系統,可以使用終端執行下面的命令,進行簡單的數據預處理:

    # 使標點符號與單詞分離并統一使用小寫字母
    cat cooking.stackexchange.txt | sed -e "s/\([.\!?,'/()]\)/ \1 /g" | tr "[:upper:]" "[:lower:]" > cooking.preprocessed.txt
    head -n 12404 cooking.preprocessed.txt > cooking.pre.train
    tail -n 3000 cooking.preprocessed.txt > cooking.pre.valid
    
  • 完成以上的數據處理操作后,進行訓練:

    # 原始數據處理后的訓練
    model = fasttext.train_supervised(input="cooking_data/cooking.train", epoch=25)
    model.test("cooking_data/cooking.pre.valid")
    

    在這里插入圖片描述

    • 準確率提升到了 47%;
    • 召回率提升到了 20%。

2.3.2 增加訓練輪次

# 增加訓練輪次
model = fasttext.train_supervised(input="cooking_data/cooking.train", epoch=50)
model.test("cooking_data/cooking.pre.valid")

在這里插入圖片描述

2.3.3 調整學習率

# 調整學習率
model = fasttext.train_supervised(input="cooking_data/cooking.train", lr=1.0, epoch=50)
model.test("cooking_data/cooking.pre.valid")

在這里插入圖片描述

2.3.4 增加n-gram特征

  • 設置train_supervised方法中的參數 wordNgrams 來添加 n-gram 特征,默認是1,也就是沒有n-gram特征;
  • 下面將其設置為2意味著添加2-gram特征,這些特征幫助模型捕捉前后詞匯之間的關聯,更好的提取分類規則用于模型分類,當然這也會增加模型訓時練占用的資源和時間;
# 調整學習率
model = fasttext.train_supervised(input="cooking_data/cooking.train", lr=1.0, epoch=50, wordNgrams=2)
model.test("cooking_data/cooking.pre.valid")

在這里插入圖片描述

2.3.5 修改損失計算方式

  • 隨著不斷添加優化策略,模型訓練速度也越來越慢;
  • 為了能夠提升 fasttext 模型的訓練效率,縮短訓練時間,可以設置train_supervised方法中的參數 loss 來修改損失計算方式(等效于輸出層的結構);
    • 默認是softmax層結構;
    • 下面將其設置為'hs',代表層次softmax結構,意味著輸出層的結構(計算方式)發生了變化,將以一種更低復雜度的方式來計算損失;
# 修改損失計算方式
model = fasttext.train_supervised(input="cooking_data/cooking.train", lr=1.0, epoch=50, wordNgrams=2, loss='hs')
model.test("cooking_data/cooking.pre.valid")

在這里插入圖片描述

  • 雖然精度和召回率稍有波動,但訓練時間能感受到明顯加快。

2.3.6 自動超參數調優

  • 手動調節和尋找超參數是非常困難的,因為參數之間可能相關,并且不同數據集需要的超參數也不同;

  • 因此可以使用 fasttext 的 autotuneValidationFile 參數進行自動超參數調優;

    • autotuneValidationFile 參數需要指定驗證數據集所在路徑,它將在驗證集上使用隨機搜索方法尋找可能最優的超參數;
    • 使用 autotuneDuration 參數可以控制隨機搜索的時間,默認是300s,根據不同的需求,可以延長或縮短時間;
  • 注意:

    • autotuneValidationFile 和 lr 參數不會直接沖突,但存在一定的優先級關系;
    • autotuneValidationFile 開啟后,lr 等手動指定的參數會被視為初始值或候選值,自動調優過程可能會根據驗證集表現調整 lr 的值(例如增大或減小),最終選擇更優的學習率;
# 自動超參數調優
model = fasttext.train_supervised(input="cooking_data/cooking.train", lr=1.0, epoch=50, wordNgrams=2, loss='hs', autotuneValidationFile='cooking_data/cooking.pre.valid', autotuneDuration=600)
model.test("cooking_data/cooking.pre.valid")

在這里插入圖片描述

2.3.7 實際生產中多標簽多分類問題的損失計算方式

  • 針對多標簽多分類問題,使用 softmax 或者 hs 有時并不是最佳選擇,因為我們最終得到的應該是多個標簽,而softmax卻只能最大化一個標簽;
  • 所以我們往往會選擇為每個標簽使用獨立的二分類器作為輸出層結構,對應的損失計算方式為'ova',表示one vs all;
  • 這種輸出層的改變意味著我們在統一語料下同時訓練多個二分類模型,對于二分類模型來講,lr不宜過大,下面設置為0.2;
# 實際生產中多標簽多分類問題的損失計算方式
model = fasttext.train_supervised(input="cooking_data/cooking.train", lr=0.2, epoch=50, wordNgrams=2, loss='ova')
model.predict("Which baking dish is best to bake a banana bread ?", k=-1, threshold=0.5)

在這里插入圖片描述

  • 輸出結果輸出了它的三個最有可能的標簽。

3 fasttext詞向量遷移

3.1 介紹

  • **詞向量遷移(Word Vector Transfer)**概念:復用預訓練詞向量,加速模型開發

    • 直接用別人在大規模語料(比如全網文本、維基百科)訓好的詞向量模型,不用自己從頭訓練;

    • 舉例:你想做“美食評論分類”,但自己數據少。可以先下載 fasttext 預訓練的詞向量,再用自己的“美食評論數據”微調,這就是遷移

  • fasttext 官方開源了兩類預訓練詞向量:

    • 第一類(157 種語言)

      • 訓練數據:CommonCrawl(超大網絡文本庫) + Wikipedia(維基百科)

      • 訓練模式:CBOW

      • 詞向量規格:300 維(每個單詞用 300 個數表示,維度越高語義信息越細)

      • 獲取地址:https://fasttext.cc/docs/en/crawl-vectors.html

    • 第二類(294 種語言)

      • 訓練數據:Wikipedia

      • 訓練模式:Skipgram

      • 詞向量規格:300 維

      • 獲取地址:https://fasttext.cc/docs/en/pretrained-vectors.html

  • 詞向量遷移的優勢:省時間、省資源、提效果

    1. 不用自己訓:訓詞向量需要超大規模語料(比如幾十 GB 文本) + 超長訓練時間(可能跑幾天),普通開發者根本扛不住。直接用預訓練的,1 分鐘下載,直接開干

    2. 語義基礎好:CommonCrawl、Wikipedia 是“通用語義富礦”,訓出來的詞向量已經包含“單詞的通用語義”(比如 apple 既知道是“蘋果”,也知道和 fruit 相關)。你用這些詞向量做任務,相當于默認帶了“通用知識”,再用自己數據微調,效果比“從零訓”好很多;

    3. 跨任務適配:不管你是做“情感分析”“文本分類”“機器翻譯”,都能先用預訓練詞向量打基礎,再針對具體任務微調。遷移性極強,適合小數據場景。

3.2 使用fasttext進行詞向量遷移

  • 中文詞向量模型:cc.zh.300.bin

    • 地址:dl.fbaipublicfiles.com/fasttext/vectors-crawl/crawl.zh.300.bin.gz;
    • 大小:2.01GB
    • 解壓縮后大小:6個多G
    • 讀入到內存:需要8個G
  • 使用fasttext進行詞向量遷移的步驟:

    • 下載詞向量模型壓縮的 bin.gz 文件
    • 解壓 bin.gz 文件到 bin 文件
    • 加載 bin 文件獲取詞向量
    • 利用鄰近詞進行效果檢驗
import fasttext
model = fasttext.load_model("model/cc.zh.300.bin")
# 查看前100個詞匯(這里的詞匯是廣義的, 可以是中文符號或漢字)
model.words[:100]

在這里插入圖片描述

model.get_word_vector("音樂")

在這里插入圖片描述

# 以'音樂'為例,返回的鄰近詞基本上與音樂都有關系,如樂曲、音樂會、聲樂等
model.get_nearest_neighbors("音樂")
[(0.6703276634216309, '樂曲'),(0.6565821170806885, '聲樂'),(0.6540279388427734, '音樂會'),(0.6502416133880615, '配樂'),(0.6501686573028564, '藝術'),(0.6489475965499878, '音樂人'),(0.6426260471343994, '音樂界'),(0.6395964026451111, '非音樂'),(0.639589250087738, '原聲'),(0.637651264667511, '交響樂')]
# 以'美術'為例,返回的鄰近詞基本上與美術都有關系,如藝術、繪畫、霍廷霄(滿城盡帶黃金甲的美術師)等
model.get_nearest_neighbors("美術")
[(0.724744975566864, '藝術'),(0.7165924310684204, '繪畫'),(0.7006476521492004, '中國畫系'),(0.6706337332725525, '版畫系'),(0.6470299363136292, '純藝'),(0.6455479860305786, '環藝系'),(0.6304370164871216, '美院'),(0.6295372247695923, '國畫系'),(0.6293253898620605, '鐘志鵬'),(0.627504825592041, '中國畫')]
# 以'周杰倫'為例,返回的鄰近詞基本上與明星有關系,如杰倫、周董、陳奕迅等
model.get_nearest_neighbors("周杰倫")
[(0.7129376530647278, '杰倫'),(0.6841713786125183, '周董'),(0.6783010959625244, '周杰倫'),(0.6644064784049988, '陳奕迅'),(0.6536471843719482, '張韶涵'),(0.6481418609619141, '葉惠美'),(0.6470388174057007, '周華健'),(0.643777072429657, '張靚穎'),(0.6342697143554688, '張惠妹'),(0.6318544149398804, '林俊杰')]

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

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

相關文章

數據庫MVCC是什么

問題數據庫MVCC是什么我的回答MVCC,全稱是"多版本并發控制"(Multi-Version Concurrency Control),是數據庫管理系統中常用的一種并發控制技術。說白了,它就是通過維護數據的多個版本,讓讀操作不會被寫操作阻塞&#xff…

游戲廣告投放數據分析項目:拆解投放的“流量密碼”

用數據說話:1441條投放記錄拆解游戲廣告投放的“流量密碼”一、數據概況 & 處理思路 先放一張數據全家福,字段 13 個,樣本 1441 條,缺失值 0,只做了一件事:把“未知大小”“無”等臟數據清洗掉。 impor…

數據庫服務語句應用

文章目錄🌟數據庫語句應用介紹🍀數據庫語句分類介紹DDL(Data Definition Language)數據定義語言DCL(Data Control Language)數據控制語言DML(Data Manipulation Language)數據操作語…

解釋器模式與布爾表達式的C++實現

詳細探討一下解釋器模式(Interpreter Pattern)以及如何使用它來實現一個簡單的布爾表達式求值器。 第一部分:解釋器模式詳解 1. 模式定義與意圖 解釋器模式是一種行為設計模式,它給定一個語言,定義其文法的一種表示,并定義一個解釋器,該解釋器使用該表示來解釋語言中…

ELK 重難點解析以及最佳實踐

ELK 重難點解析以及最佳實踐 目錄 ELK簡介核心組件詳解使用技巧重難點解析Spring Boot集成具體場景使用最佳實踐 ELK簡介 什么是ELK ELK是一個開源的日志分析平臺,由三個核心組件組成: Elasticsearch: 分布式搜索引擎,用于存儲和檢索日…

【PyTorch】單對象分割項目

對象分割是在圖像中找到目標對象的邊界的過程。單目標分割的重點是自動勾勒出圖像中一個目標對象的邊界。對象邊界通常由二進制掩碼定義。 通過二進制掩碼,可以在圖像上覆蓋輪廓以勾勒出對象邊界。例如以下圖片描繪了胎兒的超聲圖像、胎兒頭部的二進制掩碼以及覆蓋在…

esp dl

放下了好多年 又回到了dl 該忘的也忘的差不多了 其實沒啥復雜的 只是不習慣 熟悉而已 好吧 現代的人工智能體 還是存在著很大的問題 眼睛 耳朵 思考 雖然功能是正常的 但距離"真正"()意思上的獨立意識個體 還是差別很大 再等個幾十年 看看…

基于django/python的服裝銷售系統平臺/服裝購物系統/基于django/python的服裝商城

基于django/python的服裝銷售系統平臺/服裝購物系統/基于django/python的服裝商城

詳解ThreadLocal<HttpServletRequest> requestThreadLocal

public static ThreadLocal<HttpServletRequest> requestThreadLocal ThreadLocal.withInitial(() -> null);一、代碼逐部分詳解 1. public static public&#xff1a;表示這個變量是公開的&#xff0c;其他類可以訪問。static&#xff1a;表示這是類變量&#xff0c…

Vue2 響應式系統設計原理與實現

文章目錄Vue2 響應式系統設計原理與實現Vue2 響應式系統設計原理與實現 Vue2 的響應式原理主要基于以下幾點&#xff1a; 使用 Object.defineProperty () 方法對數據對象的屬性進行劫持 當數據發生變化時&#xff0c;通知依賴該數據的視圖進行更新 實現一個發布 - 訂閱模式&a…

探索 JUC:Java 并發編程的神奇世界

探索 JUC&#xff1a;Java 并發編程的神奇世界 在 Java 編程領域&#xff0c;隨著多核處理器的普及和應用場景復雜度的提升&#xff0c;并發編程變得愈發重要。Java 并發包&#xff08;JUC&#xff0c;Java.util.concurrent&#xff09;就像是一座寶藏庫&#xff0c;為開發者提…

selenium采集數據怎么應對反爬機制?

selenium是一個非常強大的瀏覽器自動化工具&#xff0c;通過操作瀏覽器來抓取動態網頁內容&#xff0c;可以很好的處理JavaScript和AJAX加載的網頁。 它能支持像點擊按鈕、懸停元素、填寫表單等各種自動化操作&#xff0c;所以很適合自動化測試和數據采集。 selenium與各種主流…

指定文件夾上的壓縮圖像格式tiff轉換為 jpg 批量腳本

文章大綱 背景簡介 代碼 背景簡介 隨著數字成像技術在科研、醫學影像和遙感等領域的廣泛應用,多頁TIFF(Tag Image File Format)文件因其支持多維數據存儲和高位深特性,成為存儲序列圖像、顯微鏡切片或衛星遙感數據的首選格式。然而在實際應用中,這類文件存在以下顯著痛點…

Docker 部署 MySQL 8.0 完整指南:從拉取鏡像到配置遠程訪問

目錄前言一、拉取鏡像二、查看鏡像三、運行容器命令參數說明&#xff1a;四、查看運行容器五、進入容器內部六、修改 MySQL 配置1. 創建配置文件2. 配置內容七、重啟 MySQL 服務八、設置 Docker 啟動時自動啟動 MySQL九、再次重啟 MySQL十、授權遠程訪問1. 進入容器內部2. 登錄…

IntelliJ IDEA 常用快捷鍵筆記(Windows)

前言&#xff1a;特別標注的快捷鍵&#xff08;Windows&#xff09;快捷鍵功能說明Ctrl Alt M將選中代碼提取成方法Ctrl Alt T包裹選中代碼塊&#xff08;try/catch、if、for 等&#xff09;Ctrl H查看類的繼承層次Alt 7打開項目結構面板Ctrl F12打開當前文件結構視圖Ct…

疏老師-python訓練營-Day54Inception網絡及其思考

浙大疏錦行 DAY54 一、 inception網絡介紹 今天我們介紹inception&#xff0c;也就是GoogleNet 傳統計算機視覺的發展史 從上面的鏈接&#xff0c;可以看到其實inceptionnet是在resnet之前的&#xff0c;那為什么我今天才說呢&#xff1f;因為他要引出我們后面的特征融合和…

LeetCode第3304題 - 找出第 K 個字符 I

題目 解答 class Solution {public char kthCharacter(int k) {int n 0;int v 1;while (v < k) {v << 1;n;}String target kthCharacterString(n);return target.charAt(k - 1);}public String kthCharacterString(int n) {if (n 0) {return "a";}Str…

Codeforces Round 1043 (Div. 3) D-F 題解

D. From 1 to Infinity 題意 有一個無限長的序列&#xff0c;是把所有正整數按次序拼接&#xff1a;123456789101112131415...\texttt{123456789101112131415...}123456789101112131415...。求這個序列前 k(k≤1015)k(k\le 10^{15})k(k≤1015) 位的數位和。 思路 二分出第 …

【C語言16天強化訓練】從基礎入門到進階:Day 7

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓、LeetCode代碼強化刷題、洛谷刷題、C/C基礎知識知識強化補充、C/C干貨分享&學習過程記錄 &#x1f349;學習方向&#xff1a;C/C方向學習者…

【AI基礎:神經網絡】16、神經網絡的生理學根基:從人腦結構到AI架構,揭秘道法自然的智能密碼

“道法自然,久藏玄冥”——人工神經網絡(ANN)的崛起并非偶然,而是對自然界最精妙的智能系統——人腦——的深度模仿與抽象。從單個神經元的信號處理到大腦皮層的層級組織,從突觸可塑性的學習機制到全腦并行計算的高效能效,生物大腦的“玄冥”智慧為AI提供了源源不斷的靈感…