
大模型RAG技術:從入門到實踐
接下來,我們加載 BERT 模型和對應的分詞器。
from transformers import BertTokenizer, BertForSequenceClassification
# 加載分詞器
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
# 加載模型
model = BertForSequenceClassification.from_pretrained("bert-base-uncased", num_labels=2)
# 對數據集進行分詞處理
def tokenize_function(examples):
return tokenizer(examples["sentence"], padding="max_length", truncation=True)
tokenized_datasets = dataset.map(tokenize_function, batched=True)
為了輸出模型參數的更新情況,我們需要自定義 Trainer
類,并在訓練循環中插入代碼來監控參數更新。
from transformers import Trainer, TrainingArguments
import torch
# 自定義 Trainer 類
class CustomTrainer(Trainer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.previous_params = {name: param.clone() for name, param in self.model.named_parameters()}
def training_step(self, model, inputs):
# 執行前向傳播和反向傳播
loss = super().training_step(model, inputs)
# 獲取當前模型參數
current_params = {name: param.clone() for name, param in self.model.named_parameters()}
# 計算參數更新
for name, param in current_params.items():
previous_param = self.previous_params[name]
param_update = param - previous_param
print(f"Parameter {name} updated by: {param_update.norm().item()}")
# 更新 previous_params
self.previous_params = {name: param.clone() for name, param in current_params.items()}
return loss
# 定義訓練參數
training_args = TrainingArguments(
output_dir="./results",
evaluation_strategy="epoch",
learning_rate=2e-5,
per_device_train_batch_size=16,
per_device_eval_batch_size=16,
num_train_epochs=3,
weight_decay=0.01,
)
# 初始化自定義 Trainer
trainer = CustomTrainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
)
# 開始訓練
trainer.train()
Trainer
類,并重寫了 training_step
方法。在每次訓練步驟中,我們首先執行標準的前向傳播和反向傳播,然后計算每個參數的更新情況,并輸出更新的幅度。previous_params
字典來存儲上一次訓練步驟中的模型參數,以便計算參數更新。在訓練過程中,你將看到類似以下的輸出:
Parameter bert.embeddings.word_embeddings.weight updated by: 0.00123456789
Parameter bert.embeddings.position_embeddings.weight updated by: 0.00098765432
...
Parameter classifier.weight updated by: 0.00234567891
Parameter classifier.bias updated by: 0.00112345678
這些輸出顯示了每個參數在每次訓練步驟中的更新幅度,幫助你更好地理解模型的訓練過程。
在實際應用中,你可能希望更詳細地監控參數更新情況,例如:
你可以將參數更新的歷史保存到 CSV 文件中,以便后續分析。
import csv
class CustomTrainer(Trainer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.previous_params = {name: param.clone() for name, param in self.model.named_parameters()}
self.update_history = []
def training_step(self, model, inputs):
loss = super().training_step(model, inputs)
current_params = {name: param.clone() for name, param in self.model.named_parameters()}
updates = {}
for name, param in current_params.items():
previous_param = self.previous_params[name]
param_update = param - previous_param
updates[name] = param_update.norm().item()
self.update_history.append(updates)
self.previous_params = {name: param.clone() for name, param in current_params.items()}
return loss
def save_update_history(self, filename):
with open(filename, mode="w", newline="") as file:
writer = csv.DictWriter(file, fieldnames=self.update_history[0].keys())
writer.writeheader()
writer.writerows(self.update_history)
# 初始化自定義 Trainer
trainer = CustomTrainer(
model=model,
args=training_args,
train_dataset=tokenized_datasets["train"],
eval_dataset=tokenized_datasets["validation"],
)
# 開始訓練
trainer.train()
# 保存參數更新歷史
trainer.save_update_history("parameter_updates.csv")
你可以使用 matplotlib
或 seaborn
等庫繪制參數更新的趨勢圖。
import pandas as pd
import matplotlib.pyplot as plt
# 讀取參數更新歷史
df = pd.read_csv("parameter_updates.csv")
# 繪制參數更新趨勢圖
plt.figure(figsize=(10, 6))
for column in df.columns:
plt.plot(df[column], label=column)
plt.xlabel("Training Step")
plt.ylabel("Parameter Update Norm")
plt.legend()
plt.show()
通過本文的介紹,你應該已經掌握了如何在 Trainer
中輸出模型參數的更新情況。這一技巧不僅可以幫助你更好地理解模型的訓練過程,還可以用于調試和優化模型。在實際應用中,你可以根據需求進一步擴展這一功能,例如記錄參數更新的歷史、可視化參數更新趨勢等。
希望本文對你有所幫助,祝你在深度學習的世界中探索出更多有趣的技術!