ViT微调三步走:把10类自定义数据集的准确率从90%拉到98%
【免费下载链接】pytorch-image-modelsThe largest collection of PyTorch image encoders / backbones. Including train, eval, inference, export scripts, and pretrained weights -- ResNet, ResNeXT, EfficientNet, NFNet, Vision Transformer (ViT), MobileNetV4, MobileNet-V3 & V2, RegNet, DPN, CSPNet, Swin Transformer, MaxViT, CoAtNet, ConvNeXt, and more项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-image-models
你手头有一个10类自定义数据集,预训练ViT微调后top-1停在90%。下面用pytorch-image-models的ViT微调接口,分三步做:最短配置跑通、逐项调参、用EMA验证,让你搭出一条稳定的微调流水线。
阶段一 | ViT微调最小可跑配置 🚀
先拉代码和依赖:
git clone https://gitcode.com/GitHub_Trending/py/pytorch-image-models cd pytorch-image-models pip install -r requirements.txt模型本体在 vision_transformer.py。这一步只给5个参数,先保证能跑起来:
import timm model = timm.create_model( 'vit_base_patch16_224', # ViT-B/16,86M参数 pretrained=True, # 载入ImageNet预训练权重 num_classes=10, # 按你的类别数重建分类头 drop_rate=0.1, # 全连接层dropout drop_path_rate=0.1, # 随机深度比例 )pretrained=True载入ImageNet权重,num_classes只重建最后一层线性分类头,编码器权重全部保留。这就是微调的起点。
阶段二 | ViT微调逐项调参 🔧
调参顺序:先模型自身正则,再优化器,最后数据增强。create_optimizer_v2、create_scheduler_v2、create_transform分别来自timm.optim、timm.scheduler、timm.data。一次只动一项,训5个epoch看方向,变差就回滚。
drop_path_rate(随机深度)
它控制训练时每个编码器block被整体跳过的概率 → 不设置恒为0.0,ViT的12个block全量参与,万级图片量下过拟合明显。建议0.1起步,验证集仍掉就加到0.2。
model = timm.create_model('vit_base_patch16_224', drop_path_rate=0.1)lr(AdamW基础学习率)
它控制每个参数的更新步长 → 不设置时优化器默认1e-3,是微调常用值的20倍,前几个epoch必然震荡。ViT微调稳定区间5e-5到1e-4,先取5e-5。
optimizer = create_optimizer_v2(model, opt='adamw', lr=5e-5) # 基础学习率weight_decay(权重衰减)
它控制对参数的L2惩罚强度 → 不设置恒为0.0,无惩罚,分类头参数量级容易膨胀、泛化变差。建议0.05;create_optimizer_v2默认已跳过bias、BN等1维参数,不用手动排除。
create_optimizer_v2(model, opt='adamw', lr=5e-5, weight_decay=0.05)sched与warmup_epochs(学习率调度)
它控制学习率随epoch的衰减曲线和预热长度 → 不设置时warmup_epochs默认0,第一步就是5e-5,刚初始化的分类头追不上,前100步loss跳变。用cosine,预热5到10个epoch,从1e-6爬到目标值。接口见 scheduler_factory.py。
scheduler, _ = create_scheduler_v2(optimizer, sched='cosine', num_epochs=30, warmup_epochs=5, min_lr=1e-6) # 预热5轮,学习率下限auto_augment与re_prob(数据增强)
它控制几何+颜色扰动的策略和随机擦除(往图像贴随机色块)概率 → 不设置时只有默认水平翻转,模型容易背背景细节。策略用rand-m9-mstd0.5-inc1(9种操作、强度0.5),随机擦除概率0.25、re_mode='pixel'。
tf = create_transform(input_size=(3, 224, 224), is_training=True, auto_augment='rand-m9-mstd0.5-inc1', re_prob=0.25, re_mode='pixel')decay(EMA衰减系数)
它控制EMA(指数移动平均,用历史权重均值换取更平滑的权重)追踪模型的速度 → 不设置时直接拿训练中的模型评估,权重轨迹抖动,验证分数忽上忽下。30个epoch用0.9998,百万步以上长训用0.9999。每个optimizer.step()后调用model_ema.update(model),实现见 model_ema.py。
model_ema = ModelEmaV3(model, decay=0.9998, foreach=True) # foreach多tensor加速阶段三 | 调优前后的量化对比 📊
验证一律用EMA权重,别用训练中的模型:
model_ema.module.eval() with torch.no_grad(): for x, y in val_loader: acc += (model_ema.module(x).argmax(1) == y).sum().item()损失函数把CE换成标签平滑0.1,防止模型过度自信:
criterion = LabelSmoothingCrossEntropy(smoothing=0.1) # 平滑系数对比(示意数据;测量条件:1万张图10类数据集、vit_base_patch16_224、输入224、batch 32、30个epoch、RTX 3090 + AMP、各跑1次):
| 配置 | top-1 |
|---|---|
| 仅预训练权重,未调优 | 90.2% |
+drop_path_rate=0.1+ 标签平滑0.1 | 93.5% |
+ cosine预热5轮 + RandAugment +re_prob=0.25 | 96.1% |
+ EMAdecay=0.9998 | 97.8% |
阶段四 | 调参避坑 ⚠️
训练起步前几步loss跳变→ 新初始化的分类头首步承受5e-5学习率 →warmup_epochs=5、warmup_lr=1e-6,5个epoch内爬升到目标值。
训练loss持续下降,验证准确率反而掉→ 编码器在万级数据上记死了特征 →drop_path_rate=0.2+ 标签平滑0.1,再掉就补re_prob=0.25。
同样参数重跑,准确率差±0.5个点→ 用原始模型做评估,权重轨迹有噪声 → 评估切到model_ema.module。
loss突然变NaN→ 混合精度下梯度爆炸且未裁剪 → 开启AMP,并在optimizer.step()前加torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)。
流水线稳定后,把数据和评估方式固定住,每轮只动1到2个参数,变差立即回滚。接下来两个方向:换vit_large_patch16_224继续压准确率,或者用 distillation.py 把大模型蒸馏进vit_base再上设备。
【免费下载链接】pytorch-image-modelsThe largest collection of PyTorch image encoders / backbones. Including train, eval, inference, export scripts, and pretrained weights -- ResNet, ResNeXT, EfficientNet, NFNet, Vision Transformer (ViT), MobileNetV4, MobileNet-V3 & V2, RegNet, DPN, CSPNet, Swin Transformer, MaxViT, CoAtNet, ConvNeXt, and more项目地址: https://gitcode.com/GitHub_Trending/py/pytorch-image-models
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考