??BERT(Bidirectional Encoder Representations from Transformers)是Google在2018年提出的預訓練語言模型,其核心思想是通過雙向Transformer結構捕捉上下文信息,為下游NLP任務提供通用的語義表示。
一、模型架構
??BERT基于Transformer的編碼器(Encoder)堆疊而成,摒棄了解碼器(Decoder)。每個Encoder層包含:
??自注意力機制(Self-Attention):計算輸入序列中每個詞與其他詞的關系權重,動態聚合上下文信息。
前饋神經網絡(FFN):對注意力輸出進行非線性變換。
殘差連接與層歸一化:緩解深層網絡訓練中的梯度消失問題。
??與傳統單向語言模型(如GPT)不同,BERT通過同時觀察左右兩側的上下文(雙向注意力)捕捉詞語的完整語義。
二、預訓練任務
??BERT通過以下兩個無監督任務預訓練模型:
1.遮蔽語言模型(Masked Language Model, MLM)
??訓練過程中,輸入句子中一部分詞會被 (MASK) 標記替換,模型需根據上下文信息預測這些被遮蔽的詞。這種任務迫使模型在訓練時同時考慮文本前后信息,學習更豐富的語言表征。具體操作是,隨機選擇 15% 的詞匯用于預測,其中 80% 情況下用 (MASK) 替換,10% 情況下用任意詞替換,10% 情況下保持原詞匯不變。
2.下一句預測(Next Sentence Prediction, NSP)
??旨在訓練模型理解句子間的連貫性。訓練時,模型接收一對句子作為輸入,判斷兩個句子是否是連續的文本序列。通過該任務,模型能學習到句子乃至篇章層面的語義信息。在實際預訓練中,會從文本語料庫中隨機選擇 50% 正確語句對和 50% 錯誤語句對進行訓練。
三、輸入表示
??BERT的輸入由三部分嵌入相加組成:
??Token Embeddings:詞向量(WordPiece分詞)。
Segment Embeddings:區分句子A和B(用于NSP任務)。
Position Embeddings:Transformer本身無位置感知,需顯式加入位置編碼。
四、微調(Fine-tuning)
??預訓練后,BERT可通過簡單的微調適配下游任務:
??分類任務(如情感分析):用(CLS)標記的輸出向量接分類層。
序列標注(如NER):用每個Token的輸出向量預測標簽。
問答任務:用兩個向量分別預測答案的起止位置。
??微調時只需添加少量任務特定層,大部分參數復用預訓練模型。
五、Python實現示例
(環境:Python 3.11,paddle 1.0.2, paddlenlp 2.6.1)
import paddle
from paddlenlp.transformers import BertTokenizer, BertForSequenceClassification# 1. 加載預訓練模型和分詞器
model_name = 'bert-base-chinese'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_classes=2) # 2分類任務# 2. 準備示例數據 (正面和負面情感文本)
texts = ["這部電影太棒了,演員表演出色!", "非常糟糕的體驗,完全不推薦。"]
labels = [1, 0] # 1表示正面,0表示負面# 3. 數據預處理
encoded_inputs = tokenizer(texts, max_length=128, padding=True, truncation=True, return_tensors='pd')
input_ids = encoded_inputs['input_ids']
token_type_ids = encoded_inputs['token_type_ids']# 轉換為Paddle張量
labels = paddle.to_tensor(labels)# 4. 模型前向計算
outputs = model(input_ids, token_type_ids=token_type_ids)
logits = outputs# 5. 計算損失和預測
loss_fct = paddle.nn.CrossEntropyLoss()
loss = loss_fct(logits, labels)# 獲取預測結果
predictions = paddle.argmax(logits, axis=1)# 打印結果
print("Loss:", loss.item())
print("Predictions:", predictions.numpy())
print("True labels:", labels.numpy())
End.