目錄
1. 確定目標:明確任務和數據
2. 選擇預訓練模型
3. 數據預處理
(1) 數據清洗與格式化
(2) 劃分數據集
(3) 數據加載與批處理
4. 構建微調模型架構
(1) 加載預訓練模型
(2) 修改模型尾部(適配任務)
(3) 凍結部分層(可選)
5. 設置超參數
(1) 優化器與學習率
(2) 損失函數
(3) 其他超參數
6. 微調模型
(1) 定義訓練循環
(2) 監控訓練過程
7. 調整超參數(可選)
8. 評估與部署
(1) 模型評估
(2) 部署模型
9. 常見問題與解決方案
(1) 過擬合
(2) 欠擬合
(3) 計算資源不足
10. 總結:微調的流程圖
附錄:代碼示例(文本分類)
關鍵點回顧
1. 確定目標:明確任務和數據
- 任務類型:
確定你要解決的問題類型,例如:- 文本分類(如情感分析)
- 圖像分類(如識別貓狗)
- 序列生成(如文本生成或機器翻譯)
- 數據集:
收集或準備與任務相關的數據集,并進行初步分析:- 數據規模(樣本數量、類別分布)
- 數據質量(是否有噪聲、缺失值、標簽錯誤)
- 數據預處理需求(如文本清洗、圖像歸一化)
2. 選擇預訓練模型
- 預訓練模型:
根據任務選擇合適的預訓練模型:- 文本任務:BERT、RoBERTa、GPT、T5
- 圖像任務:ResNet、EfficientNet、ViT
- 多模態任務:CLIP、Mixture of Experts(MoE)
- 模型來源:
常用的模型庫包括:- Hugging Face(如
transformers
庫) - PyTorch/TensorFlow官方模型庫
- Timm庫(針對計算機視覺)
- Hugging Face(如
3. 數據預處理
(1) 數據清洗與格式化
- 文本數據:
- 去除特殊字符、停用詞
- 統一大小寫(如全小寫)
- 處理缺失值或異常標簽
- 圖像數據:
- 調整尺寸(如統一為224x224)
- 歸一化(如將像素值縮放到[0,1]或[-1,1])
- 數據增強(如旋轉、翻轉、裁剪)
(2) 劃分數據集
- 訓練集:用于模型訓練(通常占80%)。
- 驗證集:用于調參和監控過擬合(通常占10%)。
- 測試集:最終評估模型性能(通常占10%)。
(3) 數據加載與批處理
- 使用
DataLoader
(PyTorch)或tf.data
(TensorFlow)將數據分批次加載: python深色版本
from torch.utils.data import DataLoader, Datasetclass MyDataset(Dataset):def __init__(self, data, labels):self.data = dataself.labels = labelsdef __len__(self):return len(self.data)def __getitem__(self, idx):return self.data[idx], self.labels[idx]train_dataset = MyDataset(train_data, train_labels) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
4. 構建微調模型架構
(1) 加載預訓練模型
- 文本模型示例(Hugging Face): python
深色版本
from transformers import BertModel, BertConfigmodel = BertModel.from_pretrained("bert-base-uncased")
- 圖像模型示例(PyTorch): python
深色版本
import torchvision.models as modelsmodel = models.resnet18(pretrained=True)
(2) 修改模型尾部(適配任務)
- 分類任務:替換最后一層全連接層(全連接層的輸出維度需匹配任務類別數): python
深色版本
# 對于ResNet: num_features = model.fc.in_features model.fc = nn.Linear(num_features, num_classes) # num_classes是目標類別數# 對于BERT: model.classifier = nn.Linear(model.config.hidden_size, num_classes)
(3) 凍結部分層(可選)
- 凍結預訓練層:保留底層的通用特征提取能力,只訓練新增層: python
深色版本
for param in model.parameters():param.requires_grad = False # 凍結所有層# 解凍最后一層(如分類層) for param in model.fc.parameters(): # 對BERT可能是model.classifier.parameters()param.requires_grad = True
5. 設置訓練參數
(1) 優化器與學習率
- 選擇優化器:
- 常用優化器:Adam、AdamW、SGD
- 示例: python
深色版本
optimizer = torch.optim.Adam(model.parameters(), lr=2e-5)
- 學習率(Learning Rate):
- 預訓練模型微調時,學習率通常比從頭訓練低(如1e-5到1e-3)。
- 可使用學習率調度器(如
torch.optim.lr_scheduler.CosineAnnealingLR
)。
(2) 損失函數
- 根據任務選擇損失函數:
- 分類任務:交叉熵損失(
nn.CrossEntropyLoss
) - 回歸任務:均方誤差(
nn.MSELoss
) - 生成任務:交叉熵或自定義損失(如BERT的MLM損失)
- 分類任務:交叉熵損失(
(3) 其他超參數
- 批量大小(Batch Size):根據硬件限制選擇(如32、64、128)。
- 訓練輪次(Epochs):通常5-20輪,根據驗證集表現調整。
- 早停(Early Stopping):當驗證損失不再下降時停止訓練,防止過擬合。
6. 訓練模型
(1) 定義訓練循環
python
深色版本
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)for epoch in range(num_epochs):model.train()total_loss = 0for batch in train_loader:inputs, labels = batchinputs, labels = inputs.to(device), labels.to(device)optimizer.zero_grad()outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()total_loss += loss.item()# 驗證階段model.eval()val_loss = 0with torch.no_grad():for batch in val_loader:inputs, labels = batchinputs, labels = inputs.to(device), labels.to(device)outputs = model(inputs)val_loss += criterion(outputs, labels).item()print(f"Epoch {epoch+1}, Train Loss: {total_loss/len(train_loader)}, Val Loss: {val_loss/len(val_loader)}")
(2) 監控訓練過程
- 使用工具如TensorBoard或Weights & Biases記錄損失、準確率等指標。
- 定期保存模型檢查點(Checkpoint): python
深色版本
torch.save(model.state_dict(), f"model_epoch{epoch}.pth")
7. 調整超參數(可選)
- 網格搜索(Grid Search)或隨機搜索(Random Search):
調整學習率、批量大小、層凍結策略等。 - 自動化工具:
使用Optuna
或Ray Tune
進行超參數優化。
8. 評估與部署
(1) 模型評估
- 在測試集上評估最終性能: python
深色版本
model.eval() test_loss = 0 correct = 0 with torch.no_grad():for data, target in test_loader:data, target = data.to(device), target.to(device)output = model(data)test_loss += criterion(output, target).item()pred = output.argmax(dim=1, keepdim=True)correct += pred.eq(target.view_as(pred)).sum().item()print(f"Test Accuracy: {100. * correct / len(test_loader.dataset)}%")
(2) 部署模型
- 導出模型為ONNX格式或使用框架工具(如TorchScript): python
深色版本
torch.onnx.export(model, torch.randn(1, 3, 224, 224), "model.onnx")
9. 常見問題與解決方案
(1) 過擬合
- 解決方法:
- 增加數據增強(如隨機裁剪、翻轉)。
- 添加正則化(如Dropout、L2正則化)。
- 減少模型復雜度或訓練輪次。
(2) 欠擬合
- 解決方法:
- 增加訓練輪次或學習率。
- 解凍更多層(釋放模型潛力)。
- 嘗試更復雜的模型架構。
(3) 計算資源不足
- 解決方法:
- 使用小批量(如batch_size=16)。
- 使用模型量化或知識蒸餾(Knowledge Distillation)。
- 選擇輕量級模型(如MobileNet、DistilBERT)。
10. 總結:微調的流程圖
深色版本
1. 確定任務和數據 →
2. 選擇預訓練模型 →
3. 數據預處理 →
4. 修改模型尾部 →
5. 設置超參數 →
6. 訓練并監控 →
7. 調參優化 →
8. 評估與部署
附錄:代碼示例(文本分類)
以下是一個完整的微調BERT進行文本分類的代碼框架:
python
深色版本
import torch
from transformers import BertTokenizer, BertForSequenceClassification
from torch.utils.data import Dataset, DataLoader# 加載預訓練模型和分詞器
model_name = "bert-base-uncased"
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=num_classes)# 數據預處理
class TextDataset(Dataset):def __init__(self, texts, labels):self.encodings = tokenizer(texts, truncation=True, padding=True, max_length=512)self.labels = labelsdef __len__(self):return len(self.labels)def __getitem__(self, idx):item = {k: torch.tensor(v[idx]) for k, v in self.encodings.items()}item["labels"] = torch.tensor(self.labels[idx])return item# 加載數據
train_dataset = TextDataset(train_texts, train_labels)
train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)# 訓練配置
device = torch.device("cuda")
model.to(device)
optimizer = torch.optim.AdamW(model.parameters(), lr=2e-5)
criterion = nn.CrossEntropyLoss()# 訓練循環(參考步驟6)
關鍵點回顧
- 微調的核心:利用預訓練模型的通用特征,僅針對特定任務調整部分參數。
- 數據質量:垃圾進,垃圾出(Garbage In, Garbage Out)。
- 超參數調優:學習率、批量大小、層凍結策略是關鍵。