4.7 迁移学习与微调:接手一条成熟流水线


4.7 迁移学习与微调:接手一条成熟流水线

本节摘要:手头只有几百上千张标注图时,从零训练注定失败,正确开局是迁移学习——接手一条在百万级图集上练熟的流水线,冻结主干只换分类头,或在极低学习率下整体微调。本节讲清"哪些层可迁移、怎么迁"的判断依据,给出一套冻结换头的完整代码与两段式学习率配置,并交代迁移失效的边界。

接手一条成熟流水线

带过项目的人都见过这个开局:业务方拍来几百张缺陷图、宠物照或票据照片,希望"训个模型"。从零训练在此必败——参数千万级、样本不足千级,模型只会背题。但深看一眼会发现问题没那么悲观:第三章六代机型的浅层学的是什么?边缘、色块、纹理——这些特征在缺陷图与宠物照上同样成立。真正任务专属的只有高层语义与分类头。那么合理的做法是:主干连同它的特征直接继承,只把分类头换成自己的规模,用少量数据把这一小部分练好。这就是迁移学习,深度学习工程里杠杆率最高的操作。

学习目标

阅读完本节,你应当能够:

  1. 说出"浅层通用、高层专属"的证据链与迁移的适用边界;
  2. 执行冻结主干加换头的完整流程,并算清可训练参数占比;
  3. 配置两段式学习率做整体微调,知道何时该解冻主干;
  4. 判断手头任务该走特征提取、微调还是从零训练。

一、冻结换头:最小代价的迁移

以 ResNet-18 为例:主干一千一百多万参数原封不动(设为不可训练),把千类的分类头换成五类的新头,全网络需要训练的只剩新头的 2,565 个参数——占总量的 0.02%。训练量骤减五个数量级,几百张图也喂得动。

import torch import torch.nn as nn from torchvision import models net = models.resnet18(weights=None) # 实际使用时加载 ImageNet 预训练权重 for p in net.parameters(): p.requires_grad = False # 冻结主干:不参与训练与梯度计算 net.fc = nn.Linear(512, 5) # 换上五类新头 trainable = sum(p.numel() for p in net.parameters() if p.requires_grad) total = sum(p.numel() for p in net.parameters()) print("可训练参数:", f"{trainable:,}") # 2,565 = 512×5 + 5 print("总参数约:", f"{total:,}") # 约 11,179,077 print("训练占比:", round(trainable / total * 100, 2), "%") # 0.02%

细节有二。其一是 4.5 节埋过的坑:冻结主干时把它里面的批归一化一并切到推理态(eval),否则滑动统计仍会被新数据改写,训练抖得没道理。其二是预处理必须与预训练时完全一致——同样的尺寸、同样的均值方差,主干是在那套规格上练熟的。

二、整体微调:解冻与两段学习率

换头嫌不够时进入微调:解冻主干全部或一部分,用远小于头部的学习率整体训练。主干已接近谷底,大步子会把它拽离;新头从随机初始化起步,需要正常步长。给两段配不同学习率即可两头兼顾:

def make_opt(net, backbone_lr=1e-4, head_lr=1e-3): backbone = [p for n, p in net.named_parameters() if not n.startswith("fc")] head = [p for n, p in net.named_parameters() if n.startswith("fc")] return torch.optim.AdamW([ {"params": backbone, "lr": backbone_lr}, {"params": head, "lr": head_lr}, ]) opt = make_opt(net) print("参数组数:", len(opt.param_groups)) # 2 print("主干学习率:", opt.param_groups[0]["lr"]) # 0.0001 print("头部学习率:", opt.param_groups[1]["lr"]) # 0.001

流程的经验顺序:先只训头到收敛,再解冻主干低率微调若干轮——两阶段几乎总比一上来就全解冻稳。数据越多、与预训练域越远,解冻越有必要;数据极少且域接近时,冻结换头就够。反方向也有边界:医学影像的灰度单通道、遥感图的天顶视角与 ImageNet 的自然照片差距过大,浅层特征不再通用,迁移收益骤减甚至为负——域差距太大时,更大规模的同域预训练(或在已有预训练上先用本域数据做一次自监督适配)才是正路。

三、选型速查

手头数据 与预训练域的关系 推荐路线
几百到几千张 接近(普通照片) 冻结换头,头用 1e-3
几千到几万张 接近 两段学习率整体微调
任意规模 相差悬殊(医学、遥感) 找同域预训练,或先域适配
百万级自有数据 无关 从零训练,主干自选第三章机型

背景、操作、结果、解读串成一次真实感复盘:八百张五类零件图(背景),冻结 ResNet-18 主干只训新头十个轮次(操作),验证准确率从零训练对照的六成上下抬到九成以上、训练时间缩到十分之一量级(结果,具体数字随数据而异,量级关系稳定),原因正是主干早已会看边缘与纹理,八百张图只需要教会它"本公司缺陷长什么样"(解读)。变式:若缺陷是极细划痕这类局部弱特征,浅层通用性打折扣,应解冻到 layer3 再训。

巡检记录

  • 迁移的依据:浅层特征通用、高层语义专属——接手主干、只训头部,训练参数可降到总量的 0.02%;
  • 双态纪律:冻结主干同时冻结其批归一化统计,预处理与预训练口径完全对齐;
  • 两段学习率:主干 1e-4、头部 1e-3,先训头后解冻;域越远解冻越多;
  • 失效边界:灰度、天顶视角等域差距过大时迁移收益为负,别硬迁。

💡 关键直觉:把预训练模型当成"识字的人"。教一个识字的人认五类零件,几百张图足够;从零开始得先教识字。迁移学习省掉的从来不是训练,是"学会看"的那部分底子。

验收环节只剩最后一站:练完的模型拿什么指标交卷。下一节把混淆矩阵与三件套算清楚。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U