重生之我在2024學Fine-tuning

一、Fine-tuning(微調)概述

????????Fine-tuning(微調)是機器學習和深度學習中的一個重要概念,特別是在預訓練模型的應用上。它指的是在模型已經通過大量數據訓練得到一個通用的預訓練模型后,再針對特定的任務或數據集進行進一步訓練的過程。

????????以下是Fine-tuning的一些關鍵點:

  1. 預訓練模型:在Fine-tuning之前,模型已經在大規模的數據集上進行了訓練,學習到了通用的特征和模式。例如,在自然語言處理(NLP)中,BERT(Bidirectional Encoder Representations from Transformers)就是一個預訓練模型,它在大量的文本數據上訓練,以理解語言的通用結構和語義。

  2. 特定任務:Fine-tuning通常是為了解決一個具體的任務,比如情感分析、問答系統、文本分類等。這些任務可能需要模型對特定類型的數據有更深入的理解。

  3. 數據集與調整參數:Fine-tuning需要一個針對特定任務的數據集,這個數據集可能遠小于預訓練時使用的數據集,但更專注于任務相關的數據。在Fine-tuning過程中,模型的大部分參數(通常是預訓練模型的底層參數)會被保留,只有一小部分參數(如頂層的分類器)會被調整以適應新的任務。

  4. 訓練過程與資源效率:Fine-tuning的過程通常比從頭開始訓練一個模型要快,因為模型已經學習了很多通用的知識,只需要對特定任務進行微調。Fine-tuning是一種資源效率較高的方法,因為它不需要從頭開始訓練一個大型模型,這樣可以節省大量的計算資源和時間。

  5. 遷移學習與過擬合:Fine-tuning是遷移學習的一種形式,即將在一個領域學到的知識應用到另一個領域。由于Fine-tuning使用的數據集通常較小,所以存在過擬合的風險,即模型可能過于適應訓練數據,而無法很好地泛化到未見過的數據。

????????Fine-tuning是一種強大的技術,它使得模型能夠快速適應新任務,同時利用預訓練模型的強大能力。

二、大模型微調的底層原理

1.預訓練與遷移學習

????????大模型微調的基礎是預訓練模型,這些模型已經在大規模數據集上進行了訓練,學習到了通用的特征和模式。微調過程實際上是遷移學習的一種應用,它將預訓練模型的知識遷移到新的任務上。在這個過程中,模型的大部分參數(通常是底層參數)被保留,只有一小部分參數(如頂層的分類器或輸出層)被調整以適應新任務。這種策略可以減少過擬合的風險,同時利用預訓練模型在底層學到的通用特征。

2.參數更新與適應性調整

????????在微調過程中,模型的參數更新策略是關鍵。通常,只有模型的頂層或部分層會被更新,而底層的參數保持不變。這種策略允許模型在保持其在預訓練階段學到的通用知識的同時,對特定任務進行適應性調整。通過這種方式,模型可以快速適應新任務,而無需從頭開始訓練,這大大減少了計算資源的需求。此外,微調過程中可能會調整學習率和其他超參數,以優化模型在新任務上的學習效率和性能。

3.低秩適應與參數效率

????????為了進一步提高微調的參數效率,一些技術如LoRA(Low-Rank Adaptation)被提出。LoRA通過在模型的特定層引入低秩矩陣來模擬參數的改變量,從而以極小的參數量實現大模型的間接訓練。這種方法假設預訓練模型的權重變化可以通過低秩矩陣來近似,這意味著相對于直接微調所有模型參數,通過低秩矩陣的調整,可以用更少的參數達到近似效果。這種技術顯著減少了微調過程中需要更新的參數數量,降低了計算成本,同時仍然能夠使模型適應新任務。

三、常用的Fine-tuning方法

1.全量微調(Full Fine-tuning)

????????這種方法涉及利用特定任務數據調整預訓練模型的所有參數,以充分適應新任務。這種方法依賴大規模計算資源,但能有效利用預訓練模型的通用特征,通常能夠獲得較好的性能提升。以下是一個使用PyTorch和Hugging Face的Transformers庫進行全量微調的示例代碼。這個例子中,我們將使用一個預訓練的BERT模型來微調一個文本分類任務。

import torch
from torch.utils.data import DataLoader, RandomSampler, SequentialSampler
from transformers import BertTokenizer, BertForSequenceClassification, AdamW, get_linear_schedule_with_warmup
from sklearn.metrics import accuracy_score# 檢查是否有可用的GPU,如果有則使用GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 加載預訓練的BERT模型和分詞器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name)# 將模型移動到GPU上(如果可用)
model.to(device)# 假設我們有一些數據集,這里我們使用隨機數據作為示例
# 你需要替換這些數據為你的實際數據集
train_data = [{'text': "I love using BERT for text classification.", 'label': 1},{'text': "BERT is not useful for my task.", 'label': 0},# ... 更多數據 ...
]# 將文本數據編碼為模型可以理解的格式
input_ids = []
attention_masks = []
labels = []for data in train_data:encoded = tokenizer.encode_plus(data['text'],add_special_tokens=True,max_length=64,return_attention_mask=True,return_tensors='pt',)input_ids.append(encoded['input_ids'])attention_masks.append(encoded['attention_mask'])labels.append(data['label'])# 將數據轉換為PyTorch張量
input_ids = torch.cat(input_ids, dim=0)
attention_masks = torch.cat(attention_masks, dim=0)
labels = torch.tensor(labels)# 創建DataLoader
train_data = torch.utils.data.TensorDataset(input_ids, attention_masks, labels)
train_sampler = RandomSampler(train_data)
train_dataloader = DataLoader(train_data, sampler=train_sampler, batch_size=8)# 設置優化器和學習率調度器
optimizer = AdamW(model.parameters(), lr=2e-5, eps=1e-8)
total_steps = len(train_dataloader) * 3  # 假設我們訓練3個epoch
scheduler = get_linear_schedule_with_warmup(optimizer,num_warmup_steps=0,num_training_steps=total_steps
)# 訓練模型
model.train()
for epoch in range(3):  # 訓練3個epochfor batch in train_dataloader:batch = tuple(t.to(device) for t in batch)inputs = {'input_ids': batch[0],'attention_mask': batch[1],'labels': batch[2]}optimizer.zero_grad()outputs = model(**inputs)loss = outputs.lossloss.backward()optimizer.step()scheduler.step()# 評估模型(這里需要一個真實的測試集)
# 這里省略了評估代碼,你需要根據你的數據集來實現評估邏輯# 保存模型
model.save_pretrained('./my_fine_tuned_bert_model')

請注意,這個代碼是一個簡化的示例,實際應用中你需要準備一個真實的數據集,并可能需要添加更多的訓練邏輯,比如模型評估、早停(early stopping)、保存最佳模型等。此外,你還需要確保數據集的格式與模型輸入的要求相匹配。

2.參數高效微調(Parameter-Efficient Fine-Tuning, PEFT)

這種技術旨在通過最小化微調參數的數量和計算復雜度,實現高效的遷移學習。它僅更新模型中的部分參數,顯著降低訓練時間和成本,適用于計算資源有限的情況。PEFT技術包括:

2.1 前綴調優(Prefix-tuning)

在輸入前添加可學習的virtual tokens作為Prefix,僅更新Prefix參數,Transformer其他部分固定。

from transformers import AutoModelForCausalLM
from peft import PeftModel, PeftConfig# 加載預訓練模型
model_name_or_path = "bert-base-uncased"
model = AutoModelForCausalLM.from_pretrained(model_name_or_path)# 創建PeftConfig配置
peft_config = PeftConfig.from_pretrained(model_name_or_path)# 應用前綴調優
peft_model = PeftModel.from_pretrained(model, peft_config, torch_dtype=torch.float16)# 打印可訓練參數數量
peft_model.print_trainable_parameters()

這段代碼首先加載了一個預訓練的BERT模型,然后創建了一個PeftConfig配置,最后應用前綴調優并打印出可訓練的參數數量。

2.2 提示調優(Prompt-tuning)

在輸入層加入prompt tokens,簡化版的Prefix Tuning,無需MLP調整。隨著模型規模增大,效果接近full fine-tuning。

from transformers import AutoModelForCausalLM, AutoTokenizer# 加載預訓練模型和分詞器
model_name_or_path = "bert-base-uncased"
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path)
model = AutoModelForCausalLM.from_pretrained(model_name_or_path)# 添加prompt tokens
prompt = tokenizer(["explain", "the", "concept", "of"], return_tensors="pt")
input_ids = torch.cat([prompt["input_ids"], torch.randint(0, 100, (1, 10))])  # 添加隨機tokens# 將輸入傳遞給模型
outputs = model(input_ids)

這段代碼加載了一個預訓練的BERT模型和分詞器,然后添加了prompt tokens到輸入中,并傳遞給模型。

2.3 Adapter調優(Adapter Tuning)

設計Adapter結構并嵌入Transformer中,僅對新增的Adapter結構進行微調,原模型參數固定。

from transformers import AutoModelForSequenceClassification, AdapterConfig# 加載預訓練模型
model_name_or_path = "bert-base-uncased"
model = AutoModelForSequenceClassification.from_pretrained(model_name_or_path)# 創建AdapterConfig配置
adapter_config = AdapterConfig(r=1, lora_alpha=32, lora_dropout=0.1)# 應用Adapter調優
model.add_adapter(name="task_specific", config=adapter_config)# 打印可訓練參數數量
model.print_trainable_parameters()

這段代碼加載了一個預訓練的BERT模型,創建了一個AdapterConfig配置,并應用Adapter調優。最后打印出可訓練的參數數量。

3.凍結部分層進行微調

在Fine-tuning過程中,通常會凍結預訓練模型中較低層級(靠近輸入端)的參數不變,僅對較高層級(靠近輸出端)的參數進行訓練。這是因為底層特征通常更具通用性,而高層特征與特定任務關聯更緊密。以下是一個使用PyTorch和Hugging Face的Transformers庫進行這種微調策略的示例代碼。這個例子中,我們將使用一個預訓練的BERT模型來微調一個文本分類任務。

import torch
from torch.utils.data import DataLoader, Dataset
from transformers import BertTokenizer, BertForSequenceClassification, AdamW# 檢查是否有可用的GPU,如果有則使用GPU
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 加載預訓練的BERT模型和分詞器
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name)# 將模型移動到GPU上(如果可用)
model.to(device)# 凍結預訓練模型的底層參數
for param in model.bert.parameters():param.requires_grad = False# 僅對分類器頭部的參數進行訓練
for param in model.classifier.parameters():param.requires_grad = True# 假設我們有一些數據集,這里我們使用隨機數據作為示例
# 你需要替換這些數據為你的實際數據集
class SimpleDataset(Dataset):def __init__(self, texts, labels):self.texts = textsself.labels = labelsdef __len__(self):return len(self.texts)def __getitem__(self, idx):text = self.texts[idx]label = self.labels[idx]encoding = tokenizer.encode_plus(text,add_special_tokens=True,max_length=64,return_attention_mask=True,return_tensors='pt',padding='max_length',truncation=True,)return {'input_ids': encoding['input_ids'].flatten(),'attention_mask': encoding['attention_mask'].flatten(),'labels': torch.tensor(label, dtype=torch.long)}# 創建數據集和數據加載器
texts = ["I love using BERT for text classification.", "BERT is not useful for my task."]
labels = [1, 0]  # 假設1是正面,0是負面
dataset = SimpleDataset(texts, labels)
dataloader = DataLoader(dataset, batch_size=2)# 設置優化器
optimizer = AdamW(model.classifier.parameters(), lr=5e-5)# 訓練模型
model.train()
for epoch in range(3):  # 訓練3個epochfor batch in dataloader:batch = {k: v.to(device) for k, v in batch.items()}inputs = {'input_ids': batch['input_ids'],'attention_mask': batch['attention_mask'],'labels': batch['labels']}optimizer.zero_grad()outputs = model(**inputs)loss = outputs.lossloss.backward()optimizer.step()# 保存模型
model.save_pretrained('./my_fine_tuned_bert_model')

在這個示例中,我們首先加載了一個預訓練的BERT模型,并將其移動到GPU上(如果可用)。然后,我們凍結了BERT模型的底層參數,只允許分類器頭部的參數進行訓練。我們創建了一個簡單的數據集和數據加載器,并設置了優化器。在訓練過程中,我們只更新分類器頭部的參數。最后,我們保存了微調后的模型。

4.微調全部層

雖然風險略高,但有時也會選擇對整個預訓練模型的所有參數進行微調。這在目標任務與預訓練任務高度相關、數據量充足且計算資源允許的情況下較為有效。以下是一個示例代碼,展示了如何在目標任務與預訓練任務高度相關、數據量充足且計算資源允許的情況下,對整個預訓練模型的所有參數進行微調。

from transformers import BertForSequenceClassification, BertTokenizer, Trainer, TrainingArguments
import torch# 選擇預訓練模型
model_name = "bert-base-uncased"# 加載預訓練模型和分詞器
tokenizer = BertTokenizer.from_pretrained(model_name)
model = BertForSequenceClassification.from_pretrained(model_name, num_labels=2)# 準備訓練和驗證數據集
# 這里假設已經有了train_dataset和eval_dataset
# train_dataset = ...
# eval_dataset = ...# 設置訓練參數
training_args = TrainingArguments(output_dir="./results",per_device_train_batch_size=16,per_device_eval_batch_size=64,num_train_epochs=3,evaluation_strategy="epoch",learning_rate=2e-5,save_total_limit=2,save_steps=500,load_best_model_at_end=True,  # 保存最佳模型metric_for_best_model="accuracy",  # 根據準確率選擇最佳模型greater_is_better=True,push_to_hub=False,
)# 初始化Trainer
trainer = Trainer(model=model,args=training_args,train_dataset=train_dataset,eval_dataset=eval_dataset,tokenizer=tokenizer,
)# 開始訓練
trainer.train()# 評估模型性能
results = trainer.evaluate()
print(results)

????????這個示例展示了如何對整個預訓練模型進行全量微調,適用于目標任務與預訓練任務高度相關且計算資源允許的情況。通過這種方式,模型可以充分利用預訓練階段學到的知識,并針對新任務進行優化。

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

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

相關文章

計算機網絡 4-2-1 網絡層(IPv4)

2 IPv4分組 各協議之間的關系 IP協議(Internet Protocol, 網際協議)是互聯網的核心&#xff01; ARP協議用于查詢同一網絡中的<主機IP地址&#xff0c;MAC地址>之間的映射關系 ICMP協議用于網絡層實體之間相互通知“異常事件” IGMP協議用于實現IP組播 2.1 結構<首…

Docker中運行的Chrome崩潰問題解決

問題 各位看官是否在 Docker 容器中的 Linux 桌面環境&#xff08;如Xfce&#xff09;上啟動Chrome &#xff0c;遇到了令人沮喪的頻繁崩潰問題&#xff1f;尤其是在打開包含圖片、視頻的網頁&#xff0c;或者進行一些稍復雜的操作時&#xff0c;窗口突然消失&#xff1f;如果…

K8S cgroups詳解

以下是 Kubernetes 中 cgroups&#xff08;Control Groups&#xff09; 的詳細解析&#xff0c;涵蓋其核心原理、在 Kubernetes 中的具體應用及實踐操作&#xff1a; 一、cgroups 基礎概念 1. 是什么&#xff1f; cgroups 是 Linux 內核提供的 資源隔離與控制機制&#xff0c…

javaer快速從idea轉戰vscode

插件安裝列表 在插市場安裝下面插件 Extension Pack for JavaSpring Boot Tools 配置文件提示Database Client Database/No-SQL管理工具httpYac - Rest Client .http文件編輯、API測試工具 https://httpyac.github.io/guide/request.htmlGit Graph 圖形化Git工具XML by Red H…

[項目總結] 抽獎系統項目技術應用總結

&#x1f338;個人主頁:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;?熱門專欄: &#x1f9ca; Java基本語法(97平均質量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection與…

【趙渝強老師】TiDB SQL層的工作機制

TiDB節點的SQL層&#xff0c;即TiDB Server&#xff0c;它負責將SQL翻譯成Key-Value操作&#xff0c;將其轉發給共用的分布式Key-Value存儲層TiKV&#xff0c;然后組裝TiKV返回的結果&#xff0c;最終將查詢結果返回給客戶端。這一層的節點都是無狀態的&#xff0c;節點本身并不…

性能遠超SAM系模型,蘇黎世大學等開發通用3D血管分割基礎模型

如果把人的身體比作一座龐大的城市&#xff0c;那么血管無疑就是這座城市的「道路」&#xff0c;動脈、靜脈以及毛細血管對應著高速公路、城市道路以及鄉間小道&#xff0c;它們相互協作&#xff0c;通過血液將營養物質、氧氣等輸送到身體各處&#xff0c;從而維持著這座「城市…

git高效殺器——cz-customizable 搭配 commitlint

What is cz-customizable and commitlint? cz-customizable 一款可定制化的Commitizen插件(也可作為獨立工具),旨在幫助創建如約定式提交規范的一致性提交消息。commitlint commitlint 是一個用于檢查 Git 提交信息的工具,它可以幫助開發者保持提交信息的規范性和一致性。…

Spark 中RDD、Job,stage,task的關系

目錄 1. 概念定義1.1 Job1.2 Stage1.3 Task 2. 關系總結3. 示例分析代碼示例執行過程 4. Spark中的運行流程5. 關鍵點5.1 寬依賴和窄依賴5.2 并行度5.3 性能優化 **6. 總結****1. RDD的核心作用****1.1 什么是RDD&#xff1f;****1.2 RDD與Job、Stage、Task的關系** **2. Job、…

Kubernetes基礎(三十二):Worker節點啟動全解析

Worker節點是Kubernetes集群的"肌肉"&#xff0c;負責實際運行業務負載。本文將深入剖析Worker節點的完整啟動流程&#xff0c;并揭秘生產環境中的關鍵優化點。 一、啟動流程全景圖 二、核心啟動階段詳解 1. 系統初始化&#xff08;0-30秒&#xff09; 關鍵任務&a…

matlab實現模型預測控制

考慮擴展狀態空間形式 縮寫為 對于未來的預測&#xff0c;這里要注意&#xff0c;默認了最小預測時域為1&#xff0c;如果不為1&#xff0c;從k1到k最小預測時域的x的預測為0 模型預測控制matlab運行代碼&#xff0c;可實現模型預測控制。 StateMPC是按照錢積新版《預測控制》…

Python_day22

DAY 22 復習日 復習日 仔細回顧一下之前21天的內容&#xff0c;沒跟上進度的同學補一下進度。 作業&#xff1a; 自行學習參考如何使用kaggle平臺&#xff0c;寫下使用注意點&#xff0c;并對下述比賽提交代碼 kaggle泰坦里克號人員生還預測 一、Kaggle 基礎使用步驟 注冊與登錄…

【軟件測試】基于項目驅動的功能測試報告(持續更新)

目錄 一、項目的介紹 1.1 項目背景 二、測試目標 2.1 用戶服務模塊 2.1.1 用戶注冊模塊 2.1.1.1 測試點 2.1.1.2 邊界值分析法(等價類+邊界值) 2.1.1.2.1 有效等價類 2.1.1.2.2 無效等價類 2.1.1.2.3 邊界值 2.1.1.2.4 測試用例設計 2.1.2 用戶登錄 2.1.2.1 測試…

QT中多線程的實現

采用官方推薦的 QObject::moveToThread 方式實現&#xff08;相比繼承 QThread 更靈活&#xff09;&#xff0c;包含耗時任務執行、主線程通信、線程安全退出等核心功能。 環境說明 Qt 版本&#xff1a;Qt 5.15 或 Qt 6&#xff08;兼容&#xff09;項目類型&#xff1a;GUI …

從知識圖譜到精準決策:基于MCP的招投標貨物比對溯源系統實踐

前言 從最初對人工智能的懵懂認知&#xff0c;到逐漸踏入Prompt工程的世界&#xff0c;我們一路探索&#xff0c;從私有化部署的實際場景&#xff0c;到對DeepSeek技術的全面解讀&#xff0c;再逐步深入到NL2SQL、知識圖譜構建、RAG知識庫設計&#xff0c;以及ChatBI這些高階應…

maven如何搭建自己的私服(LINUX版)?

環境準備 安裝 JDK &#xff1a;確保系統已安裝 JDK 8 或更高版本。可以通過以下命令安裝 JDK&#xff1a; 安裝 OpenJDK &#xff1a;sudo apt update && sudo apt install openjdk-11-jdk 安裝 Oracle JDK &#xff1a;需要添加第三方倉庫&#xff0c;例如 WebUpd8 …

armv7 backtrace

ref&#xff1a; ARM Cortex-M3/M4/M7 Hardfault異常分析_arm hardfault-CSDN博客

探索 C++23 的 views::cartesian_product

文章目錄 一、背景與動機二、基本概念與語法三、使用示例四、特點與優勢五、性能與優化六、與 P2374R4 的關系七、編譯器支持八、總結 C23 為我們帶來了一系列令人興奮的新特性&#xff0c;其中 views::cartesian_product 是一個非常實用且強大的功能&#xff0c;它允許我們輕…

SHAP分析!Transformer-BiLSTM組合模型SHAP分析,模型可解釋不在發愁!

SHAP分析&#xff01;Transformer-BiLSTM組合模型SHAP分析&#xff0c;模型可解釋不在發愁&#xff01; 目錄 SHAP分析&#xff01;Transformer-BiLSTM組合模型SHAP分析&#xff0c;模型可解釋不在發愁&#xff01;效果一覽基本介紹程序設計參考資料 效果一覽 基本介紹 基于SH…

牛客周賽 Round 92-題解

牛客周賽 Round 92-題解 A-小紅的簽到題 code #include<iostream> #include<string> using namespace std; string s; int main() {int n;cin >> n;cout << "a_";for (int i 0; i < n - 2; i )cout << b;return 0; }B-小紅的模…