ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

python神经网络编程入门(四十四)——微调预训练 BERT 做下游任务

python神经网络编程入门(四十四)——微调预训练 BERT 做下游任务 路标本篇位于《从零构建 Transformer》系列第 15/16 章 · 实战篇。系列主线注意力思想 → 自注意力 → 多头 → 位置编码 → 编解码架构 → 手撕实现 → 预训练模型 → 实战微调 → 知识收官。进度▸ 基石篇(1-5) ▸ 架构篇(6-10) ▸ 预训练篇(11-13) ▸实战篇(14-16·本篇)▸ 知识收官摘要第 15 章讲站在巨人肩上不自己从零训练而是先用无标注语料预训练学会用 [CLS] 聚合全句判断是否含情感词30 步到 96%再在少量噪声标注数据上微调做情感分类。真实输出对比三种方案从零训练测试 76.7%、预训练后微调88.3%胜出、冻结特征46.7%并在 10/40/100 条标注下验证微调全面优于从零8~18 个百分点还踩出一个真实教训任务头必须重新初始化、只能迁移骨干。上一篇四十三从零训练一个小型 Transformer 做文本分类引言上一章从零造这一章站在巨人肩上第 14 章我们从零训练了一个 842 参数的分类器测试准确率 92.5%——听起来不错但要看清代价200 条数据、60 步、纯 NumPy、而且任务极其简单情感词决定标签。换到真实 IMDB2.5 万条影评、否定句、反讽、长句这个模型会跌到 60% 以下。真实世界的分类器是怎么做到 90% 的答案不是从零训一个更大的而是加载别人用海量数据预训练好的 BERT只微调几轮。这就是迁移学习Transfer Learning把在某处学到的知识搬到另一处任务上。人类每天都在做这件事——你学会了中文再学给句子标情绪只需要看几个例子BERT 也一样它在几十亿 token 上学会了语言再学情感分类只需要几千条标注。这一章用可复现的小实验把迁移学习的每个环节拆开验证预训练先用 300 条无标注语料训练一个模型标签由词表自动推导不需要人工标注让它学会用 [CLS] 聚合全句判断句子是否含情感词demo1微调把预训练好的骨干嵌入 Encoder复制过来换一个新的随机分类头在 40 条标注数据上微调——测试准确率 88.3%比从零训练的 76.7% 高 11.6 个百分点demo2/3冻结特征对比Encoder 完全冻结、只训分类头的做法demo4——在本设置下它反而受限原因值得分析小样本优势标注数据越少微调相对从零的优势越明显demo5一个真实教训写这章时我踩了个坑——连任务头一起继承让微调反而变差最后发现任务头必须重新初始化、只能迁移骨干这正是真实 BERT 微调的标准做法。这一章也是知识的总验收它把第 10 章的训练三件套平滑 CE、AdamW、warmup、第 11 章的数据管线分词、padding、mask、第 12 章的小 BERTencoder-only、CLS 聚合、第 14 章的分类器全部串联起来又加上了迁移学习这块新拼图。如果你读到这里觉得每个环节都眼熟说明前 14 章没有白写——迁移学习不是新数学而是旧零件 新策略策略只有三条骨干继承、头重建、小学习率本章用实验逐一验证。先给一句话定位本章与第 14 章的关系第 14 章是造从零训练一个能用的模型第 15 章是借借别人预训练好的骨架快速改造成自己的模型。两章用的是同一套训练代码、同一个模型结构唯一区别是初始权重从哪来——随机第 14 章还是预训练第 15 章。而这个唯一区别带来的效果差异正是迁移学习这门学问的全部内容。读懂本章你就明白为什么今天几乎没有团队再从零训练语言模型——不是不能而是没必要预训练模型已经替你把最贵的学语言这步做完了。本章目标理解迁移学习的两阶段范式预训练无标注、贵、一次→ 微调有标注、便宜、多次亲手验证预训练先验的价值微调 88.3% vs 从零 76.7%demo2/3看懂三种方案从零/微调/冻结的差异与适用场景demo2/3/4验证小样本优势10/40/100 条标注下微调全面优于从零demo5理解任务头必须重新初始化、只迁移骨干这一核心原则图 10对接真实世界HuggingFace 微调 BERT 的学习率、轮次、头初始化方式。一、迁移学习为什么站在巨人肩上更快1.1 两阶段范式第 12 章我们讲过 BERT 的预训练 → 微调两阶段第 14 章我们验证了从零训练的完整闭环。这一章把两者接起来预训练海量无标注文本学语言贵但只做一次→微调少量标注数据学任务便宜且可重复。为什么预训练值得做一句话语言知识是可迁移的。情感分类需要懂great 是好词、terrible 是坏词、句子结构怎么组织——这些在预训练里无标注地学会了微调时只需学会怎么把情感说出来这个薄薄的一层。而从零训练要把语言知识 任务一起学数据不够就学不好。1.2 同一任务不同的起点用图把两种方式摆在一起同一个任务、同一个模型结构唯一差别是初始权重——随机从零vs 预训练微调。一句话总结迁移学习预训练花钱买语言微调花小钱买任务——总价远低于从零把两者一起学。1.3 迁移学习的三种常见形式。顺便把术语理清面试常考①特征迁移Feature Transfer——用预训练模型把输入变成特征向量下游只用特征对应本章的冻结特征方案②参数迁移Parameter Transfer——用预训练权重初始化模型继续训练对应全量微调本章主角③领域迁移Domain Transfer——在 A 领域预训练用到 B 领域如用英文模型初始化中文模型先做语言适配。三种形式中参数迁移微调是 NLP 的主流因为它让预训练知识参与下游训练、效果最好特征迁移省算力但效果略逊领域迁移一般作为前两者的前置步骤。本章实验恰好覆盖了①②两种冻结特征①vs 全量微调②的对比就是图 8 那两根柱子的故事。1.4 本章实验设计总览。为了让你在读代码前心里有数先把实验地图画出来环节数据任务训练预训练300 条无标注句含情感词句/纯填充句各半句级是否含情感词[CLS] 二分类30 步lr 0.1方案 A 从零40 条标注15% 噪声情感二分类30 步lr 0.1随机初始化方案 B 微调同上同上40 步lr 0.05预训练骨干 随机头方案 C 冻结同上同上30 步只训 18 个头参数小样本对比10/40/100 条标注同上各 20~25 步从零 vs 微调评估60 条干净测试集——所有方案共用同一测试集注意两个公平性设计①测试集对所有方案完全相同60 条、干净无噪声、与训练集不同源——否则对比无意义②微调与从零的骨干结构完全相同842 参数——差别的唯一来源就是初始权重。控制变量才能把效果差异归因于预训练而不是别的。二、预训练无标注语料上的自监督任务2.1 标签从哪来——从词表自动推导“无标注不意味着没有可学的信号”。这一章的预训练用了一个巧妙的自监督信号句子是否含情感词。这个标签不需要人工标注——查词表great/love 是情感词the/and 不是就能算出来。语料里一半是含情感词的句子、一半是纯填充词的句子这个任务设计有两个用心①它训练了CLS 聚合全句的能力——和下游分类任务同构②它让模型记住哪些词是情感词——正是下游情感分类最需要的先验。真实 BERT 的预训练MLM第 12 章也是同类思路标签从文本自身来被遮的词就是标签不需要人标注。2.2 预训练实测demo1真实输出【demo1】预训练无标注语料上做句级二分类是否含情感词[CLS]聚合30 步 step 10 loss 0.7111 预训练准确率 52.3% step 20 loss 0.6718 预训练准确率 52.3% step 30 loss 0.3085 预训练准确率 96.0% → 预训练后模型学会了用 [CLS] 聚合全句、判断句子里有没有情感词——和下游任务同构前 20 步几乎没动warmup 数据简单第 30 步准确率从 52.3%瞎猜跳到 96.0%——模型学会了CLS 聚合 情感词检测。训练完的骨干嵌入 Encoder就是我们要搬到下个任务的财富。一句话总结预训练“无标注不等于没信号”——从词表推导标签、从文本自身推导标签MLM都是自监督。预训练的目的不是完成任务而是学到可迁移的语言先验。2.3 为什么选是否含情感词这个预训练任务诚实交代设计理由真实 BERT 用 MLM猜被遮的词那是几十亿 token 才喂得动的任务第 12 章我们验证过小模型猜具体词会卡在局部最优。本章把预训练任务换成句子是否含情感词——它是一个与下游任务同构、但标签无需人工标注的二分类①同构下游是句子积极/消极CLS 聚合预训练是句子是否含情感词同样是 CLS 聚合——预训练直接教会模型CLS 怎么聚合、情感词在哪微调只需把是否含细化为积极还是消极②自监督标签查词表就有符合无标注精神③可学小模型 数值梯度 30 步就能到 96%demo1。“预训练任务与下游任务对齐度越高迁移收益越大”——这是本章最重要的设计心得也解释了真实世界为什么 MLM 好使它教的是语言理解这个通用能力对几乎所有下游任务都对齐。2.4 预训练与微调的数据性格不同。一张小表收尾数据部分预训练数据多而脏无标注、规模大、质量参差标签是自动推导的近似微调数据少而贵人工标注、规模小、含噪声但可信。这两个性格决定了两种训练的态度预训练可以大胆地跑数据多不怕过拟合微调必须小心地跑数据少怕过拟合、怕踢飞先验。真实项目里预训练数据是量的胜利微调数据是质的精选——这也是为什么收集几千条高质量标注往往比在低质量数据上再训几轮更有效。三、微调继承骨干 新头 小学习率预训练完成开始微调。流程三步复制骨干把预训练模型的嵌入 Encoder 权重原样复制过来只复制骨干不复制预训练的任务头——原因第六节讲换新头为下游任务新初始化一个分类头随机权重小学习率微调用远小于从零训练的学习率0.05 vs 0.1继续训练避免一脚踢飞预训练学好的先验。一句话总结微调“复制骨干、换新头、小步走”——前两步是结构操作第三步是训练策略第 10 章学过的动作要轻学习率太大 踢飞先验。3.1 两个为什么提前说透。①为什么只复制骨干、不复制头预训练的任务头判断是否含情感词期望的输入是某位置的向量而下游分类头拿到的是[CLS] 聚合向量——两者的输入分布不是一回事。带着不匹配的头开始微调等于带着错误偏见出发第六节会用实验证明这一点。②为什么微调学习率要小第 10 章我们讲过预训练权重是存款微调是取零花动作要轻——学习率决定了每次参数移动的幅度0.05 表示骨干只允许小幅调整0.1 以上就可能把预训练学好的情感词在哪、CLS 怎么聚合一把冲掉第七节对照表里真实 BERT 用 2e-5比我们更小因为它的先验更值钱。微调的微字一半指数据少一半指步子小。四、三种方案实测对比预训练先验到底值多少钱这是本章最核心的实验。同一个任务40 条标注、15% 标签噪声、同一个测试集60 条干净样本三种起点方案 A从零训练demo2——骨干随机初始化30 步【demo2】方案A 从零训练随机初始化 40 条标注30 步 从零初始化未训练测试集准确率: 48.3%随机约等于瞎猜 step 10 loss 0.3122 训练准确率 95.0% step 20 loss 0.2952 训练准确率 97.5% step 30 loss 0.3314 训练准确率 97.5% 测试集准确率: 76.7%方案 B预训练后微调demo3——预训练骨干 新分类头40 步【demo3】方案B 微调继承预训练骨干embEncoder 新分类头小学习率 0.0540 步 微调前继承骨干随机头未训练测试集准确率: 45.0%约等于瞎猜——预训练收益在微调后才显现 step 10 loss 0.5634 训练准确率 80.0% step 20 loss 0.2290 训练准确率 100.0% step 30 loss 0.2241 训练准确率 100.0% step 40 loss 0.2031 训练准确率 100.0% 测试集准确率: 88.3%方案 C冻结特征demo4——Encoder 完全冻结只训练 18 个分类头参数【demo4】方案C 冻结特征Encoder 冻结预训练骨干只训练新分类头18 参数30 步 step 10 loss 0.7208 训练准确率 50.0% step 20 loss 0.6805 训练准确率 57.5% step 30 loss 0.6966 训练准确率 50.0% 测试集准确率: 46.7%三组数字的解读从零 76.7% vs 微调 88.3%同样的骨干结构只差起点差了11.6 个百分点——预训练先验的价签清清楚楚。微调还更稳训练准确率 100%把 15% 噪声样本之外的全学对了loss 一路平滑下降微调前只有 45%注意这个数字——继承骨干但还没微调时测试集只有 45%约等于瞎猜。这说明预训练先验不是白送的结果而是一个更好的起点它在微调过程中让模型学得更快、更好、更稳而不是躺赢冻结特征 46.7%在本设置下小模型 小数据冻结特征反而受限——因为预训练任务产出的 [CLS] 特征含情感词检测与下游积极/消极区分不完全对齐且分类头只有 18 个参数、数据只有 40 条学不到足够的区分。真实世界里冻结特征通常有效大模型特征很丰富但本章数据告诉我们能微调就微调别偷懒。4.1 三组数字背后的机制。逐个拆解为什么是这样①从零 76.7% 为什么不错因为任务本质是情感词检测40 条标注里含足够的情感词样本随机初始化也能学会——但只学到 76.7% 就上不去了因为 15% 噪声样本它照单全收训练 97.5% ≈ 学会了 15% 的错误标签②微调 88.3% 为什么更高预训练已教会哪些是情感词、CLS 怎么聚合微调只需补积极还是消极这一层——而且先验让模型对噪声样本有主见不盲从错误标签所以训练 100%、测试也高③冻结 46.7% 为什么崩预训练特征CLS 向量只编码了含不含情感词这个信号对积极 vs 消极区分度不足而 18 个头参数在 40 条数据上无法变出新特征——冻结 信任预训练特征足够好但本章的预训练特征还不够好。三组数字合起来讲了一个完整的故事先验的价值不在于免费微调前 45%而在于引导微调时学得又快又稳又抗噪。4.2 抗噪的机制是什么值得多想一层为什么微调面对 15% 噪声标签更稳打个比方从零模型像一个没有底线的学生——40 条例题里有 6 条答案印错了它全部照背训练 97.5% ≈ 6/40 全错也记下微调模型像一个有常识的学生——它早知道great 是好词即使 6 条例题把 great 标成消极它也会犹豫而不是全盘接受。这个犹豫来自预训练先验模型对哪些词是情感词已有稳定的内部表示标签噪声只让它在边界处摇摆不足以推翻整体认知。在真实项目中这种抗噪性意味着预训练模型可以用更脏的标注数据降低标注成本而仍保持不错的效果——这也是迁移学习在工业界省钱的方式之一。微调训练曲线与三方案对比柱状图一句话总结对比微调 从零 冻结本设置下——预训练先验值 11.6 个百分点冻结特征在小规模下省了训练也省了效果。五、小样本优势标注越少迁移越值钱迁移学习最著名的卖点标注数据很少时预训练模型依然能用。用三档标注量10/40/100 条分别训练从零和微调在同一 60 条干净测试集上评估demo5【demo5】小样本优势标注数据越少微调相对从零的优势越大测试集 60 条 标注量 从零训练 预训练微调 差距 10 条 56.7% 66.7% 10.0% 40 条 85.0% 93.3% 8.3% 100 条 73.3% 91.7% 18.3% → 三档标注量下微调全部优于从零8~18 个百分点——预训练先验在噪声标注数据上更稳健10 条从零只有 56.7%数据太少 15% 噪声模型被噪声带偏微调 66.7%——预训练先验像锚一样稳住模型100 条从零 73.3%噪声数据多从零学噪微调 91.7%——数据多了从零也追不上因为 15% 噪声是学不对的预训练先验让模型不被噪声带跑结论修正了常见误解“标注足够多时从零也能追上”——在本实验里没追上因为预训练先验帮模型抵抗了标签噪声真实数据总带噪声。一句话总结小样本优势预训练先验 免费的数据增强 抗噪盾牌——数据越少、噪声越多它的价值越大。5.1 数据的边际收益为什么 100 条没有比 40 条好多少看 demo5 的微调列66.7%10 条→ 93.3%40 条→ 91.7%100 条——从 40 条加到 100 条准确率几乎没涨。这不是 bug而是数据边际收益递减的典型表现任务能学的东西区分 12 个情感词的方向在 40 条时已基本学完再加 60 条只是重复。反过来看从零列56.7%10 条→ 85%40 条→ 73.3%100 条——从零在 100 条时反而掉了15% 噪声样本更多过拟合噪声更严重。这条规律给工程实践的启示先看加数据是否还有收益再决定要不要标数据——预训练模型的数据饥饿远比从零模型低很多时候几千条标注就够用了对照真实 BERT 微调通常只需要几千条。六、一个真实的教训任务头必须重新初始化写这一章时我踩了一个坑值得原原本本讲出来一开始我把预训练模型连任务头一起继承词类头直接当分类头用结果微调反而比从零还差60% vs 73.3%。排查后发现原因预训练的词类头期望输入的是单个词的向量词级任务微调的分类头输入的是[CLS] 聚合向量句级任务两者输入分布完全不同——用词类头当分类头等于给句级分类塞了一个词级分类器初始权重就跑偏了。修正后只继承骨干、分类头随机初始化微调立刻变成 88.3%。这个坑的价值在于它不是巧合而是迁移学习的核心原则——一句话总结本章最重要的坑“骨干可迁移头不可迁移”——预训练学的是任务无关的语言理解输出头学的是任务专属的映射换任务时头必须重建。6.1 从坑里能带走的经验。这个坑的价值不只在头不迁移这一条还有两条通用教训①实验里出现反直觉结果时先怀疑初始化而不是怀疑训练——微调比从零差第一反应应该是是不是继承的权重带偏了而不是微调没调好②对照组要做得细——如果我一开始就同时跑继承头和重建头两个版本对比坑当场就能发现只跑一个版本就容易把坏结果误归因于方法不行。这两条是可迁移的调试经验在深度学习里错误往往藏在你没想到要检查的那一步这里是初始化而对照实验是照妖镜。6.2 除了头还有什么不该迁移顺着头不迁移的原则再想一步位置编码、padding token 的嵌入这类协议相关的权重在任务变化时通常也不迁移或重新学习——因为序列长度、padding 约定可能变了第 11 章。真实 BERT 微调时一般保留位置编码BERT 固定 max_len512但重新初始化分类头、并视情况重学 segment 嵌入句子对任务才用。一个实用的判断标准“这个权重编码的是’语言知识’可迁移还是’任务协议’不可迁移”——语言知识词义、句法带走任务协议输出格式、特殊 token 的含义重建。这个标准能帮你在任何迁移场景里快速决定带什么、丢什么。6.3 迁移学习与第 10 章训练三件套的化学反应。回顾本章所有实验训练用的还是第 10 章的平滑 CE、AdamW、warmup——但迁移学习给它们加了新含义warmup 不只是防起步爆炸更是防止第一步就踢飞先验学习率从 0 爬升 先不动骨干标签平滑不只是防过度自信更让模型对噪声标注不较真这正是 4.2 节抗噪机制的一部分权重衰减在微调小数据时尤其重要防止把几百条标注背下来。同一个工具在从零训练和微调两个场景里有不同的使命——理解了这一点你就不是在套模板而是在懂原理地调参。七、真实世界的微调对照 HuggingFace本章的小实验是微调 BERT的微缩版。对照真实世界HuggingFace 微调bert-base-uncased做情感分类你会发现参数不同配方完全一致环节本章小实验真实 BERT 微调预训练300 条语料30 步33 亿 token几十万步骨干嵌入 1 层 Encoder842 参数嵌入 12 层 Encoder1.1 亿参数分类头随机初始化8→2随机初始化768→2学习率0.05warmup 5 步2e-5~5e-5warmup 若干步轮次40 步2~4 epoch冻结策略默认全量微调默认全量微调冻结特征可选结果88.3%40 条标注90%几千条标注三点对照读懂这张表①头随机初始化、骨干继承、小学习率三个配方完全一致——本章学的就是真实的微调②规模差 6 个数量级但机制相同——小实验验证的规律在大模型上成立③真实 BERT 用 2e-5 这种极小学习率因为 1.1 亿参数的先验比我们 842 参数值钱得多更要轻拿轻放。一句话总结真实微调本章小实验 真实 BERT 微调的同构缩放——配方一样只是把 842 换成 1.1 亿、把 300 条换成 33 亿 token。7.1 微调还会遇到的两个问题。①灾难性遗忘catastrophic forgetting如果微调学习率过大或轮次过多模型会忘掉预训练学的东西、只记住下游任务——表现是训练集准确率很高、但一到新领域就崩。缓解手段就是小学习率 少轮次本章配方以及不要贪杯2~4 epoch 就停多训反而过拟合②小数据过拟合下游标注只有几百条时微调也可能把这几百条背下来——此时可以用第 10 章的权重衰减、标签平滑或者干脆退回到冻结特征方案。真实项目里微调到底调几轮通常用验证集train/validation/test 三段决定——训练中定期看验证集准确率不再上升就停早停early stopping。7.2 把本章数字换算到真实 BERT。一个练习本章预训练 300 条、微调 40 条、差距 11.6 个百分点真实 BERT 预训练 33 亿 token、微调几千条、典型差距是多少其实真实世界很难做从零 vs 微调的公平对比从零训 1.1 亿参数根本不现实——这正是迁移学习最厉害的地方它让从零训练这个选项直接退出比赛。真实的证据是另一个方向BERT 刚发布时用 2500 条标注数据微调就能在多数任务上超过用全部数据从头训的传统模型。数字会随规模变但预训练先验让下游又快又好这个方向从 842 参数到 1.1 亿参数从未改变。八、常见坑与自查连任务头一起继承本章最大的坑第六节。预训练头的输入分布与下游头不同直接继承会跑偏。自查微调前确认分类头是随机初始化的学习率太大踢飞先验微调 lr 要明显小于从零训练本章 0.05 vs 0.1真实 BERT 2e-5。学习率太大 第一步就把预训练学的知识冲掉把预训练准确率当下游能力预训练 96%判断是否含情感词≠ 下游 88.3%积极/消极。预训练是起点微调才是终点——微调前测试只有 45%就是证明测试集与训练集同源评估必须在从没见过的测试集上本章测试集单独生成、干净无噪声。用训练集评估会虚高从零能到 97.5%冻结特征无脑用冻结省训练但本章数据显示小模型小数据下冻结只有 46.7%。能微调就微调冻结通常只在特征已足够丰富或算力受限时用忽略标签噪声真实标注总有噪声本章 15%。噪声下从零模型学噪100 条从零 73.3%预训练先验能抗噪——评估时别只看训练集测试集才是真相忘了 warmup微调同样需要第 10 章的 warmup学习率从小爬升尤其在小数据上一上来就大学习率会震荡用训练集上的预训练准确率判断迁移好坏预训练 96% 是预训练任务的成绩不是下游任务的成绩——迁移效果要用微调后的测试集来评判本章 88.3% 才是数字小测试集上比大小60 条测试集差 2~3 条样本就是 4~5 个百分点单次实验的微小差距可能是噪声——判断方案 A 是否优于方案 B最好多次换 seed 重跑看波动范围。小结第 15 章用可复现实验把迁移学习从口号变成数字核心收获九条两阶段范式预训练无标注、贵、一次→ 微调有标注、便宜、多次“预训练买语言、微调买任务”图 1自监督信号无标注 ≠ 没信号——标签可从词表推导是否含情感词也可从文本自身推导MLM图 3预训练实测30 步内准确率 52.3% → 96.0%模型学会CLS 聚合 情感词检测demo1、图 6微调配方复制骨干 新随机分类头 小学习率图 4三方案实测从零 76.7% vs 微调 88.3%11.6vs 冻结 46.7%——微调完胜demo2/3/4、图 5、图 7、图 8微调前 45%预训练先验不是白送结果而是更好的起点——收益在微调中兑现小样本优势10/40/100 条标注下微调全面优于从零8~18 个百分点且抗噪声demo5、图 9头不可迁移任务头必须重新初始化、只迁移骨干——本章踩坑换来的核心原则图 10真实世界对照HuggingFace 微调 BERT 与本章配方完全一致头随机、小 lr 2e-5、2-4 epoch规模差 6 个数量级、机制相同一句话记住本章预训练解决学语言微调解决学任务——先验的价值是引导不是免费而头不迁移是铁律。系列进度第 14 章自己造、第 15 章站在巨人肩上实战篇只剩最后一章——把 RNN 与 Transformer 两条知识线织成一张认知树并为整个 16 章系列画上句号。到这一章为止预训练 → 微调这个当今 NLP 的黄金范式你已经从原理到代码完整走了一遍看得懂、写得出、验得明——从 842 个参数的小实验到 1.1 亿参数的真实 BERT配方从未变过。下一篇四十五知识体系收官——从 RNN 到 Transformer 的完整地图
返回列表