基于 BERT 微調一個意圖識別(Intent Classification)模型,你的意圖類別包括:
- 查詢天氣
- 獲取新聞咨詢
- 想聽音樂
- 想添加備忘
- 查詢備忘
- 獲取家政服務
- 結束對話
- 增加音量
- 減小音量
- 其他
具體實現步驟(詳細版)
1. 準備你的數據集
你的數據集應該是這樣的格式(通常是 CSV 或 JSON):
text | label |
---|---|
今天上海天氣怎么樣? | 查詢天氣 |
給我放首輕音樂 | 想聽音樂 |
新聞頭條是什么? | 獲取新聞咨詢 |
記一下明天開會 | 想添加備忘 |
查看一下我的備忘錄 | 查詢備忘 |
叫個鐘點工來打掃 | 獲取家政服務 |
不聊了,再見 | 結束對話 |
聲音大一點 | 增加音量 |
小點聲 | 減小音量 |
亂說的話 | 其他 |
每一行是一個用戶輸入(text)和它對應的意圖(label)。
注意:BERT只能識別數字標簽,所以需要把意圖文字映射成數字,比如:
label2id = {"查詢天氣": 0,"獲取新聞咨詢": 1,"想聽音樂": 2,"想添加備忘": 3,"查詢備忘": 4,"獲取家政服務": 5,"結束對話": 6,"增加音量": 7,"減小音量": 8,"其他": 9
}
id2label = {v: k for k, v in label2id.items()}
2. 安裝需要的庫
pip install transformers datasets torch scikit-learn
3. 代碼:BERT意圖識別模型訓練
import torch
from datasets import load_dataset, Dataset
from transformers import BertTokenizer, BertForSequenceClassification, Trainer, TrainingArguments
from sklearn.model_selection import train_test_split# 1. 準備數據
texts = ["今天上海天氣怎么樣?", "給我放首輕音樂", "新聞頭條是什么?","記一下明天開會", "查看一下我的備忘錄", "叫個鐘點工來打掃","不聊了,再見", "聲音大一點", "小點聲", "亂說的話"
]
labels = [0, 2, 1, 3, 4, 5, 6, 7, 8, 9] # 使用數字標簽# 切分成訓練集和驗證集
train_texts, val_texts, train_labels, val_labels = train_test_split(texts, labels, test_size=0.2, random_state=42
)# 2. 加載分詞器
tokenizer = BertTokenizer.from_pretrained("bert-base-chinese")# 3. 對數據進行編碼
def tokenize_function(texts):return tokenizer(texts, padding="max_length", truncation=True, max_length=32)train_encodings = tokenize_function(train_texts)
val_encodings = tokenize_function(val_texts)# 4. 構建 PyTorch Dataset
class IntentDataset(torch.utils.data.Dataset):def __init__(self, encodings, labels):self.encodings = encodingsself.labels = labelsdef __len__(self):return len(self.labels)def __getitem__(self, idx):item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}item["labels"] = torch.tensor(self.labels[idx])return itemtrain_dataset = IntentDataset(train_encodings, train_labels)
val_dataset = IntentDataset(val_encodings, val_labels)# 5. 加載預訓練BERT分類模型
model = BertForSequenceClassification.from_pretrained("bert-base-chinese", num_labels=10)# 6. 設置訓練參數
training_args = TrainingArguments(output_dir="./results",num_train_epochs=5,per_device_train_batch_size=8,per_device_eval_batch_size=8,evaluation_strategy="epoch",save_strategy="epoch",logging_dir="./logs",logging_steps=10,learning_rate=2e-5,
)# 7. 用Trainer訓練
trainer = Trainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=val_dataset,
)trainer.train()
4. 訓練好以后,保存模型
model.save_pretrained("./intent_bert_model")
tokenizer.save_pretrained("./intent_bert_model")
5. 推理(用來預測意圖)
from transformers import pipeline# 加載保存好的模型
classifier = pipeline("text-classification", model="./intent_bert_model", tokenizer="./intent_bert_model", device=0 if torch.cuda.is_available() else -1)# 測試
text = "幫我叫個保潔阿姨"
prediction = classifier(text)
predicted_label = int(prediction[0]["label"].split("_")[-1]) # 如果是默認模型格式
print(f"預測的標簽是:{id2label[predicted_label]}")
補充說明
- 數據集:建議你準備更多的數據樣本,每個意圖至少幾十條,效果更好。
- 小批量數據:小批量很少時,可以使用數據增強方法(例如同義詞替換、輕微打亂順序等)擴充數據。
- 模型優化:可以調整學習率、batch size、epoch數來進一步優化效果。
- 多意圖識別:如果未來一個句子可能有多個意圖,需要做成多標簽分類(現在是單標簽分類)。