《深度學習實戰》第4集:Transformer 架構與自然語言處理(NLP)

《深度學習實戰》第4集:Transformer 架構與自然語言處理(NLP)

在自然語言處理(NLP)領域,Transformer 架構的出現徹底改變了傳統的序列建模方法。它不僅成為現代 NLP 的核心,還推動了諸如 BERT、GPT 等預訓練模型的發展。本集將帶你深入了解 Transformer 的工作原理,并通過實戰項目微調 BERT 模型完成情感分析任務。


1. 自注意力機制與多頭注意力

1.1 自注意力機制(Self-Attention)

自注意力機制是 Transformer 的核心組件,它允許模型在處理輸入序列時關注不同位置的相關性。以下是其工作原理:
在這里插入圖片描述

  1. 輸入嵌入
    • 輸入序列被轉換為詞向量表示。
  2. 計算注意力權重
    • 通過查詢(Query)、鍵(Key)和值(Value)矩陣計算注意力分數。
    • 注意力分數公式:

在這里插入圖片描述

  1. 加權求和
    • 根據注意力分數對值進行加權求和,得到上下文相關的表示。

在這里插入圖片描述

1.2 多頭注意力(Multi-Head Attention)

為了捕捉不同子空間中的特征,Transformer 使用多頭注意力機制。每個“頭”獨立計算注意力,然后將結果拼接并線性變換。


2. Transformer 的編碼器-解碼器結構

Transformer 由編碼器(Encoder)和解碼器(Decoder)兩部分組成:

2.1 編碼器(Encoder)

  • 編碼器由多個相同的層堆疊而成,每層包含:
    • 多頭自注意力層:捕捉輸入序列的全局依賴關系。
    • 前饋神經網絡(FFN):進一步提取特征。
    • 殘差連接與層歸一化:穩定訓練過程。
      在這里插入圖片描述

2.2 解碼器(Decoder)

  • 解碼器同樣由多層組成,但額外增加了:
    • 掩碼多頭注意力(Masked Multi-Head Attention):防止未來信息泄露。
    • 編碼器-解碼器注意力層:結合編碼器輸出生成目標序列。
      在這里插入圖片描述

好的!為了讓你更好地理解 自注意力機制(Self-Attention)多頭注意力(Multi-Head Attention) 的底層結構和原理,我會用一個生活中的例子來類比,并逐步拆解它們的工作方式。


3. 自注意力機制:一場“會議討論”的比喻

想象一下,你正在參加一場公司會議,會議的主題是“如何提高產品銷量”。會議室里有幾位同事,每個人都有自己的觀點。你需要綜合大家的意見,得出一個全面的結論。

3.1 每個人的觀點

  • 假設會議室里的每個人代表輸入序列中的一個單詞。
  • 每個人的觀點(比如市場分析、用戶體驗、技術改進等)就是這個單詞的嵌入向量(Embedding Vector)。

3.2 問題來了:如何聽取所有人的意見?

在會議中,你會根據每個人的發言內容,判斷他們的觀點對你當前思考的重要性。這就像自注意力機制的核心思想:計算每個單詞對當前單詞的相關性

具體步驟:
  1. 準備材料(生成 Query、Key 和 Value)

    • 每個人會準備三份材料:
      • Query(提問):你想問的問題,比如“你的建議對我有什么幫助?”
      • Key(關鍵詞):每個人的核心觀點,比如“市場分析”或“用戶體驗”。
      • Value(具體內容):每個人的具體建議,比如“我們需要增加廣告預算”。
    • 這些材料通過線性變換(矩陣乘法)從原始觀點(嵌入向量)生成。
  2. 打分(計算注意力分數)

    • 你拿著自己的 Query,去和每個人提供的 Key 對比,看看誰的觀點和你的問題最相關。
    • 相關性通過點積計算,結果越大表示越相關。
    • 計算公式:
      [
      \text{Attention Score} = \frac{\text{Query} \cdot \text{Key}}{\sqrt{d_k}}
      ]
      (這里的 (\sqrt{d_k}) 是為了防止分數過大,保持數值穩定。)
  3. 加權求和(整合信息)

    • 根據每個人的得分,計算權重(通過 softmax 歸一化)。
    • 然后,根據權重對每個人的 Value 進行加權求和,得到最終的結論。

3.3 總結:自注意力機制的作用

自注意力機制的核心是讓每個單詞都能“看到”整個句子中的其他單詞,并根據它們的相關性調整自己的表示。這樣,模型可以捕捉到全局的上下文信息。


4. 多頭注意力:多個“視角”的討論

回到剛才的會議場景,假設你不僅關心“如何提高產品銷量”,還想知道“哪些用戶群體最重要”、“競爭對手有哪些策略”等多個問題。這時,你可以邀請幾個專家小組,分別從不同角度分析問題。

4.1 多個“專家小組”

  • 每個專家小組相當于一個多頭注意力的一個“頭”。
  • 每個小組會獨立地進行討論,生成自己的結論。

4.2 如何整合多個小組的意見?

  • 每個小組的討論結果(即每個頭的輸出)會被拼接在一起。
  • 然后通過一個線性變換(矩陣乘法),將這些結果融合成一個最終的結論。

4.3 多頭注意力的好處

  • 不同的“頭”可以關注輸入的不同部分。例如:
    • 一個頭可能專注于語法關系(主語和謂語的聯系)。
    • 另一個頭可能關注語義關系(情感或主題)。
  • 通過多頭注意力,模型可以從多個角度提取特征,從而更全面地理解輸入。

圖解:會議討論與注意力機制的對應關系

會議討論注意力機制
每個人的觀點輸入序列中的單詞嵌入向量
提問(Query)查詢向量(Query Vector)
關鍵詞(Key)鍵向量(Key Vector)
具體內容(Value)值向量(Value Vector)
打分并加權求和注意力分數計算 + 加權求和
多個專家小組分別討論多頭注意力的多個“頭”

一個具體的例子:翻譯句子

假設我們要翻譯一句話:“The cat sat on the mat.”(貓坐在墊子上)。

自注意力機制的作用

  • 當處理單詞“cat”時,自注意力機制會讓它“看到”整個句子。
  • 它會發現“sat”和“mat”與自己高度相關,因為它們描述了貓的動作和位置。

多頭注意力的作用

  • 一個頭可能專注于語法關系(“cat”是主語,“sat”是謂語)。
  • 另一個頭可能專注于語義關系(“cat”和“mat”之間存在空間關系)。
  • 最終,這些信息被整合起來,幫助模型生成更準確的翻譯。

關于自注意力機制和多頭注意力的總結

  • 自注意力機制:就像你在會議上聽取每個人的意見,計算出誰的觀點最重要,并據此做出決策。
  • 多頭注意力:就像你邀請多個專家小組,從不同角度分析問題,最后整合所有意見。

通過這種機制,Transformer 模型能夠高效地捕捉輸入序列中的全局依賴關系,從而在自然語言處理任務中表現出色。


5. BERT、GPT 等預訓練模型的原理與應用

5.1 BERT(Bidirectional Encoder Representations from Transformers)

  • 特點
    • 雙向編碼:同時考慮上下文信息。
    • 預訓練任務:
      • Masked Language Model(MLM):預測被遮擋的單詞。
      • Next Sentence Prediction(NSP):判斷句子對是否連續。
  • 應用場景
    • 文本分類、命名實體識別、問答系統等。

5.2 GPT(Generative Pre-trained Transformer)

  • 特點
    • 單向解碼:從左到右生成文本。
    • 基于自回歸語言模型。
  • 應用場景
    • 文本生成、對話系統、代碼補全等。

6. 實戰項目:使用 Hugging Face Transformers 微調 BERT 模型

我們將使用 Hugging Face 的 transformers 庫微調 BERT 模型,完成情感分析任務。

6.1 數據準備

下載 SST-2數據集,鏈接如下:SST-2下載鏈接

import pandas as pd
from sklearn.model_selection import train_test_split
import os
from transformers import BertTokenizer, BertForSequenceClassification
import torch# 設置代理(如果需要)
# os.environ["HTTP_PROXY"] = "http://your_proxy:port"
# os.environ["HTTPS_PROXY"] = "http://your_proxy:port"# 設置離線模式,使用本地文件
# 定義文件路徑(根據你的實際路徑修改)
train_file = "SST-2/SST-2/train.tsv"
dev_file = "SST-2/SST-2/dev.tsv"

6.2 數據預處理

from transformers import BertTokenizer
# 使用 Pandas 讀取 TSV 文件
try:train_data = pd.read_csv(train_file, sep='\t')test_data = pd.read_csv(dev_file, sep='\t')print("成功加載本地數據集")print(train_data.head())
except Exception as e:print(f"加載本地數據集失敗: {e}")print("請確保數據文件路徑正確")# 嘗試加載本地分詞器或使用備選方案
try:# 嘗試從本地緩存加載cache_dir = "./models_cache"os.makedirs(cache_dir, exist_ok=True)# 使用本地緩存目錄tokenizer = BertTokenizer.from_pretrained("bert-base-uncased", cache_dir=cache_dir,local_files_only=False,  # 允許在線下載use_fast=True)print("成功加載分詞器")
except OSError as e:print(f"無法加載BERT分詞器: {e}")print("嘗試使用備選方案...")# 備選方案:使用簡單的分詞方法from sklearn.feature_extraction.text import CountVectorizervectorizer = CountVectorizer(max_features=10000)print("已切換到簡單分詞器 (CountVectorizer)")# 定義預處理函數
def preprocess_data(data):sentences = data["sentence"].tolist()labels = data["label"].tolist()try:# 如果BERT分詞器加載成功if 'tokenizer' in locals():# 對句子進行分詞和編碼encodings = tokenizer(sentences,truncation=True,padding="max_length",max_length=128,return_tensors="pt")return encodings, labels, True  # 返回True表示使用BERTelse:# 使用備選分詞方法# 注意:這里只對訓練數據進行fit_transformif 'vectorizer_fitted' not in globals():global vectorizer_fittedvectorizer_fitted = Truefeatures = vectorizer.fit_transform(sentences)else:# 對于測試數據,只進行transformfeatures = vectorizer.transform(sentences)return features, labels, False  # 返回False表示使用備選方案except Exception as e:print(f"預處理數據時出錯: {e}")return None, labels, False# 預處理訓練集和測試集
if 'train_data' in locals() and 'test_data' in locals():print("開始預處理數據...")train_features, train_labels, using_bert = preprocess_data(train_data)test_features, test_labels, _ = preprocess_data(test_data)print("數據預處理完成")

6.3 模型定義與訓練

import torch
from torch.utils.data import Dataset
import numpy as np
from sklearn.linear_model import LogisticRegressionclass SSTDataset(Dataset):def __init__(self, encodings, labels):self.encodings = encodingsself.labels = labelsself.is_bert_encoding = isinstance(encodings, dict)def __len__(self):if self.is_bert_encoding:return len(self.labels)else:return self.encodings.shape[0]def __getitem__(self, idx):if self.is_bert_encoding:item = {key: val[idx] for key, val in self.encodings.items()}item["labels"] = torch.tensor(self.labels[idx])return itemelse:# 對于非BERT編碼,返回稀疏向量的密集表示和標簽features = torch.tensor(self.encodings[idx].toarray()[0], dtype=torch.float)label = torch.tensor(self.labels[idx])return {"features": features, "labels": label}# 創建數據集實例
train_dataset = SSTDataset(train_features, train_labels)
test_dataset = SSTDataset(test_features, test_labels)# 根據使用的分詞器選擇不同的模型訓練方法
if using_bert:from transformers import BertForSequenceClassification, Trainer, TrainingArguments# 加載預訓練的 BERT 模型(用于二分類任務)model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)# 定義訓練參數training_args = TrainingArguments(output_dir="./results",          # 輸出目錄evaluation_strategy="epoch",     # 每個 epoch 后評估模型per_device_train_batch_size=16,  # 訓練時的批量大小per_device_eval_batch_size=16,   # 驗證時的批量大小num_train_epochs=3,              # 訓練輪數weight_decay=0.01,               # 權重衰減logging_dir="./logs",            # 日志目錄logging_steps=10                 # 每 10 步記錄一次日志)# 定義 Trainertrainer = Trainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=test_dataset)# 開始訓練trainer.train()

6.4 測試模型

 # 測試單句預測test_sentence = "This movie was absolutely fantastic!"inputs = tokenizer(test_sentence, return_tensors="pt", truncation=True, padding=True, max_length=128)outputs = model(**inputs)prediction = outputs.logits.argmax(dim=-1).item()# 輸出結果print("情感分析結果:", "積極" if prediction == 1 else "消極")
else:print("使用備選方案 (LogisticRegression) 進行訓練...")# 將稀疏矩陣轉換為numpy數組進行訓練X_train = train_features.toarray()X_test = test_features.toarray()# 使用邏輯回歸作為備選模型clf = LogisticRegression(max_iter=1000)clf.fit(X_train, train_labels)# 評估模型accuracy = clf.score(X_test, test_labels)print(f"測試集準確率: {accuracy:.4f}")# 測試單句預測test_sentence = "This movie was absolutely fantastic!"# 使用已經訓練好的vectorizer進行轉換test_features = vectorizer.transform([test_sentence])prediction = clf.predict(test_features)[0]# 輸出結果print("情感分析結果:", "積極" if prediction == 1 else "消極")

程序運行結果:

2025-02-27 23:52:05.928189: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2025-02-27 23:52:07.648400: I tensorflow/core/util/port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
成功加載本地數據集sentence  label
0       hide new secretions from the parental units       0
1               contains no wit , only labored gags       0
2  that loves its characters and communicates som...      1
3  remains utterly satisfied to remain the same t...      0
4  on the worst revenge-of-the-nerds clichés the ...      0
無法加載BERT分詞器: (MaxRetryError("HTTPSConnectionPool(host='huggingface.co', port=443): Max retries exceeded with url: /bert-base-uncased/resolve/main/tokenizer_config.json (Caused by ProxyError('Unable to connect to proxy', FileNotFoundError(2, 'No such file or directory')))"), '(Request ID: 3fff21e5-ab5a-4c4c-8695-70d49bb4ebdf)')
嘗試使用備選方案...
已切換到簡單分詞器 (CountVectorizer)
開始預處理數據...
數據預處理完成
使用備選方案 (LogisticRegression) 進行訓練...
測試集準確率: 0.8131
情感分析結果: 積極


7. 前沿關聯:超大規模語言模型的能力與挑戰

7.1 超大規模模型

  • GPT-4PaLM 等模型擁有數千億參數,能夠生成高質量的文本、代碼甚至圖像描述。
  • 能力
    • 上下文理解、多語言支持、零樣本學習。
  • 挑戰
    • 計算資源需求高。
    • 模型可解釋性差。
    • 潛在的偏見與倫理問題。

7.2 未來方向

  • 更高效的訓練方法(如稀疏激活、知識蒸餾)。
  • 提升模型的可控性與安全性。

總結

Transformer 架構以其強大的自注意力機制和靈活的編碼器-解碼器結構,成為 NLP 領域的基石。通過實戰項目,我們學會了如何使用 Hugging Face 的工具微調 BERT 模型。同時,我們也探討了超大規模語言模型的潛力與挑戰。

希望這篇博客能幫助你更好地理解 Transformer 的原理與應用!如果需要進一步擴展或優化,請隨時告訴我!

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

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

相關文章

高效管理 React 狀態和交互:我的自定義 Hooks 實踐

高效管理 React 狀態和交互:自定義 Hooks 實踐 在 React 中,Hooks 是一種使我們能夠在函數組件中使用狀態和副作用的強大工具。隨著項目的增大,重復的邏輯可能會出現在多個組件中,這時使用自定義 Hooks 就非常合適。它們幫助我們…

Exoplayer(MediaX)實現音頻變調和變速播放

在K歌或錄音類應用中變調是個常見需求,比如需要播出蘿莉音/大叔音等。變速播放在影視播放類應用中普遍存在,在傳統播放器Mediaplayer中這兩個功能都比較難以實現,特別在低版本SDK中,而Exoplayer作為google官方推出的Mediaplayer替…

Meta最新研究:從單張照片到3D數字人的革命性突破

隨著人工智能技術的發展,3D建模和虛擬人物生成逐漸變得更加普及和高效。Meta(前身為Facebook)的最新研究成果展示了如何僅通過一張普通手機拍攝的照片就能生成高質量、全方位的3D數字人。這項技術不僅適用于虛擬試衣、游戲角色建模,還能廣泛應用于AR/VR內容生成等領域。本文…

軟件供應鏈安全工具鏈研究系列——RASP自適應威脅免疫平臺(上篇)

1.1 基本能力 RASP是一種安全防護技術,運行在程序執行期間,使程序能夠自我監控和識別有害的輸入和行為。也就是說一個程序如果注入或者引入了RASP技術,那么RASP就和這個程序融為一體,使應用程序具備了自我防護的能力,…

2025-02-27 學習記錄--C/C++-PTA 7-29 刪除字符串中的子串

合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、題目描述 ?? 二、代碼&#xff08;C語言&#xff09;?? #include <stdio.h> // 引入標準輸入輸出庫&#xff0c…

Redis---字符串SDS(簡單動態字符串)底層結構

文章目錄 什么是SDS&#xff08;簡單動態字符串&#xff09;SDS結構SDS的優點O(1) 時間復雜度獲取字符串長度避免緩沖區溢出減少內存重分配次數二進制安全兼容C語言字符串函數 SDS的操作總結 什么是SDS&#xff08;簡單動態字符串&#xff09; redis是由C語言編寫的&#xff0…

Elasticsearch:使用阿里云 AI 服務進行嵌入和重新排名

作者&#xff1a;來自 Elastic Toms Mura 將阿里云 AI 服務功能與 Elastic 結合使用。 更多閱讀&#xff0c;請參閱 “Elasticsearch&#xff1a;使用阿里 infererence API 及 semantic text 進行向量搜索”。 在本文中&#xff0c;我們將介紹如何將阿里云 AI 功能與 Elastics…

Spring Cloud Alibaba與Spring Boot、Spring Cloud版本對應關系

一、前言 在搭建SpringCloud項目環境架構的時候&#xff0c;需要選擇SpringBoot和SpringCloud進行兼容的版本號&#xff0c;因此對于選擇SpringBoot版本與SpringCloud版本的對應關系很重要&#xff0c;如果版本關系不對應&#xff0c;常見的會遇見項目啟動不起來&#xff0c;怪…

【含文檔+PPT+源碼】基于過濾協同算法的旅游推薦管理系統設計與實現

項目介紹 本課程演示的是一款基于過濾協同算法的旅游推薦管理系統設計與實現&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運行本套…

MTK Android12 預裝apk可卸載

文章目錄 需求解決方法1、device/mediatek/mt6761/device.mk2、/vendor/mediatek/proprietary/frameworks/base/data/etc/pms_sysapp_removable_vendor_list.txt3、路徑&#xff1a;4、Android.mk 需求 近期&#xff0c;客戶需要預裝一個apk&#xff0c;同時該apk要可卸載。解…

從 0 到 1,用 Python 構建超實用 Web 實時聊天應用

從 0 到 1&#xff0c;用 Python 構建超實用 Web 實時聊天應用 本文深入剖析如何運用 Python 的 Flask 框架與 SocketIO 擴展&#xff0c;搭建一個功能完備的 Web 實時聊天應用。從環境搭建、前后端代碼實現&#xff0c;到最終運行展示&#xff0c;逐步拆解關鍵步驟&#xff0…

視頻字幕識別和翻譯

下載的視頻很多不是漢語的&#xff0c;我們需要用剪映將語音識別出來作為字幕壓制到視頻中去。 剪映6.0以后語音識別需要收費&#xff0c;但是低版本還是沒有問題。 如果想要非漢語字幕轉成中文&#xff0c;剪映低版本不提供這樣功能。但是&#xff0c;用剪映導出識別字幕&am…

每天一個Flutter開發小項目 (4) : 構建收藏地點應用 - 深入Flutter狀態管理

引言 歡迎回到 每天一個Flutter開發小項目 系列博客!在前三篇博客中,我們從零開始構建了計數器應用、待辦事項列表應用,以及簡易天氣應用。您不僅掌握了 Flutter 的基礎組件和布局,還學習了網絡請求、JSON 解析等實用技能,更重要的是,我們一起探討了高效的 Flutter 學習…

Visual Studio打開文件后,中文變亂碼的解決方案

文件加載 使用Unicode&#xff08;UTF-8&#xff09;編碼加載文件 C:\WorkSpace\Assets\Scripts\UI\View\ExecuteComplateView.cs時&#xff0c;有些字節已用Unicode替換字符替換。保存該文件將不會保留原始文件內容。

OpenGL ES -> GLSurfaceView繪制點、線、三角形、正方形、圓(頂點法繪制)

XML文件 <?xml version"1.0" encoding"utf-8"?> <com.example.myapplication.MyGLSurfaceViewxmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"…

threejs 安裝教程

嗨&#xff0c;我是小路。今天主要和大家分享的主題是“threejs 安裝教程”。 在當今的數字化時代&#xff0c;用戶對視覺體驗的要求越來越高。傳統的2D網頁已經無法滿足所有需求&#xff0c;而三維&#xff08;3D&#xff09;圖形技術則為前端開發者提供了新的方向。…

win11編譯pytorch cuda128版本流程

Geforce 50xx系顯卡最低支持cuda128&#xff0c;torch cu128 release版本目前還沒有釋放&#xff0c;所以自己基于2.6.0源碼自己編譯wheel包。 1. 前置條件 1. 使用visual studio installer 安裝visual studio 2022&#xff0c;工作負荷選擇【使用c的桌面開發】,安裝完成后將…

如何安裝Vm和centos

一、VMware 安裝 &#xff08;一&#xff09;前期準備 下載 VMware 軟件&#xff1a;首先&#xff0c;你需要從 VMware 官方網站下載適合你計算機操作系統版本的 VMware Workstation 軟件安裝包。確保選擇的版本與你的主機操作系統兼容&#xff0c;例如&#xff0c;如果你的主…

OpenGL 04--GLSL、數據類型、Uniform、著色器類

一、著色器 在 OpenGL 中&#xff0c;著色器&#xff08;Shader&#xff09;是運行在 GPU 上的程序&#xff0c;用于處理圖形渲染管線中的不同階段。 這些小程序為圖形渲染管線的某個特定部分而運行。從基本意義上來說&#xff0c;著色器只是一種把輸入轉化為輸出的程序。著色器…

服務器離線部署DeepSeek

目標 本次部署的目標是在本地服務器上部署DeepSeek。但是該服務不能連接外網&#xff0c;因此只能使用離線部署的方式。為了一次完成部署。現在云服務器上進行嘗試。 云服務器部署嘗試 云服務器配置 CentOS72080Ti 11GB 安裝準備 1、上傳iso并配置為本地yum源 安裝前先將…