“預訓練(Pre-training)”和“Warm-up(預熱)”是深度學習中常見的兩個訓練策略,它們雖然都在訓練初期起作用,但本質和目的完全不同。
一、預訓練(Pre-training)
1. 定義
預訓練是指:先在一個大規模數據集或相關任務上訓練模型,以獲取有用的參數初始化,然后再在目標任務上進行微調(Fine-tuning)。
2. 目的
加快收斂
避免從頭開始訓練
提高小數據集上的性能(通過遷移知識)
3. 舉例
NLP領域(經典):
模型 | 預訓練任務 | 微調任務 |
---|---|---|
BERT | Masked Language Model | 文本分類、問答、NER等 |
GPT系列 | 下一個詞預測(語言建模) | 對話、寫作、代碼生成等 |
CV領域(圖像):
用 ResNet-50 在 ImageNet 上預訓練,遷移到醫療圖像/遙感圖像等小樣本任務中。
4. 形式
# 加載預訓練權重 model.load_state_dict(torch.load("pretrained_model.pth")) # 再進行微調 train(model, task_dataset)
二、Warm-up(預熱)
1. 定義
Warm-up 指的是:在訓練初期,逐漸增加學習率,從一個較小值慢慢變大,直到達到設定的初始學習率。如下面例子中的線性warm up。
2. 目的
防止一開始梯度爆炸或震蕩
提高訓練穩定性,特別是Transformer類模型
3. 常見策略
(1) 線性 warm-up:
lr = base_lr × step / warmup_steps if step <= warmup_steps
(2) 結合衰減策略(如 transformer):
# 經典 Transformer warmup+inverse sqrt decay def get_lr(step, d_model=512, warmup=4000): return d_model**-0.5 * min(step**-0.5, step * warmup**-1.5)
4. 舉例
PyTorch 中使用 warmup:
from transformers import get_linear_schedule_with_warmup
optimizer = AdamW(model.parameters(), lr=1e-4)
scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=1000, num_training_steps=10000)
for step in range(total_steps): optimizer.step() scheduler.step()
三、對比總結
項目 | 預訓練(Pre-training) | Warm-up(預熱) |
---|---|---|
作用階段 | 訓練前或訓練初期 | 訓練初期 |
針對對象 | 模型權重 | 學習率調度 |
目標 | 利用已有知識遷移,加快收斂 | 防止梯度不穩定,提高初始階段魯棒性 |
應用領域 | NLP、CV、大模型、元學習等 | Transformer、BERT、GAN、深度網絡等 |
四、實際項目中如何配合使用?
預訓練 + warm-up 經常聯合使用(如 BERT)
示例:
加載預訓練 BERT 模型
采用 warm-up + cosine decay 的學習率策略
微調分類任務(如情感分析)
在軌跡預測、分類或Transformer類任務,warm-up 幾乎是標配;而預訓練則要看你有沒有現成的預訓練模型或大規模源域數據。
五、PyTorch 實現的warm-up 學習率調度器(warm-up + 余弦退火)
下面是一個使用 PyTorch 實現的 warm-up 學習率調度器 的完整示例,適用于 Transformer、BERT 或任意深度模型訓練時的預熱策略。
示例:線性 warm-up + 余弦退火(Cosine Annealing)
import torch
import torch.nn as nn
import torch.optim as optim
import math
import matplotlib.pyplot as plt# 模擬模型
model = nn.Linear(512, 10)# 優化器
optimizer = optim.Adam(model.parameters(), lr=1e-3)# 訓練總步數
num_training_steps = 10000# warm-up 步數(前10%步數用于 warm-up)
num_warmup_steps = int(0.1 * num_training_steps)# 自定義 warm-up + cosine 衰減調度器
def get_lr(step):if step < num_warmup_steps:return step / num_warmup_stepselse:# 余弦衰減,值在 [1, 0]progress = (step - num_warmup_steps) / (num_training_steps - num_warmup_steps)return 0.5 * (1.0 + math.cos(math.pi * progress))# 模擬訓練流程
lrs = []
for step in range(1, num_training_steps + 1):# 當前的學習率(乘基礎學習率)scale = get_lr(step)lr = scale * 1e-3for param_group in optimizer.param_groups:param_group['lr'] = lr# 模擬一次訓練optimizer.step()lrs.append(lr)# 可視化學習率變化
plt.plot(lrs)
plt.title("Learning Rate Schedule (Warm-up + Cosine Decay)")
plt.xlabel("Step")
plt.ylabel("Learning Rate")
plt.grid(True)
plt.show()
代碼解釋:
階段 | 策略 |
---|---|
前1000步 | 學習率從 0 線性上升到 1e-3 |
后9000步 | 學習率從 1e-3 余弦方式逐漸衰減到接近 0 |
線性 warm-up 的核心邏輯定義在 get_lr(step)
函數中的這部分:
if step < num_warmup_steps:return step / num_warmup_steps
線性 warm-up 就是:在訓練開始時,學習率從 0 按線性方式逐步升到設定的最大值,防止一開始梯度太大導致訓練不穩定。
余弦退火(Cosine Annealing)是一種學習率調度策略,其核心目的是:
讓學習率在訓練后期逐漸減小,有節奏地收斂到接近 0,從而提升模型收斂的穩定性與最終精度。
為什么要用余弦退火?
訓練初期: 需要較大的學習率來快速探索優化空間;
訓練后期: 逐漸減小學習率,有助于模型精細調優、避免震蕩;
相比線性衰減或固定學習率更有效,尤其在 Transformer、BERT、CV大模型中常用。