资讯详情

资讯详情

深度学习如何统一处理人类语言:从序列建模到预训练模型

这套关于深度学习与人类语言处理的公开课我前后看了三遍笔记也整理了两版。第一版是边看边记的流水账第二版才把里面的方法论真正抽出来。今天分享的是我对整门课的“反刍”不是按课堂顺序复述而是按我自己理解这门课的正确打开方式重新串了一遍。如果你正处于“会调BERT接口但说不清理清原理”的阶段这份梳理大概率能帮你补齐中间那块拼图如果你刚入门自然语言处理或语音处理也可以把它当一份导读顺着里面的线索去补基础。课程内容覆盖了语音识别、语音合成、文本分类、机器翻译、问答系统这些典型任务但它的主线并不是某个具体模型而是“深度学习如何统一处理人类语言”这一件事。这门课让我印象最深的是授课老师反复强调的一个观点人类语言本质上是序列信号语音是连续的声音序列文字是离散的符号序列而深度学习模型恰恰擅长在序列上做映射。抓住这条主线整门课就不再是一堆孤立模型的堆砌而是一条贯穿始终的逻辑链。1. 课程主线梳理语言处理为什么需要深度学习1.1 从语音到文本人类语言处理的完整图谱很多人一提到自然语言处理脑子里只有文本分类、情感分析这些词级任务。但这门课把“语言处理”的边界划得更大输入是声音也好是文字也好只要涉及人类语言都算在内。课程开篇就抛出了一张图谱我后来自己又画了一遍把它分成了三条链路。第一条是“听”的链路输入连续的声音波形输出离散的文字或语义标签典型任务是自动语音识别、说话人识别、语音事件检测。第二条是“说”的链路输入文本或意图输出声音波形典型任务是语音合成、语音转换、口音转换。第三条是“读”的链路输入文字输出文字或结构化结果涵盖文本分类、机器翻译、摘要生成、问答系统等。这三条链路看起来各自独立但课程的框架把它们压到了同一个抽象层面都是把一个序列映射成另一个序列只是表现形态和粒度不同。这个视角对我后来的工作帮助特别大。以前我做文本项目时总觉得语音识别是另一个领域完全不想碰。但按这门课的思路去看语音识别的输入是一帧帧声学特征文本分类的输入是一个个词向量本质上都是“给模型一串有序units让它预测另一串units”。想通了这一点很多语音任务的baseline可以直接复用文本任务的经验反过来也一样。1.2 传统方法为何不够用课程在讲深度学习之前花了一些篇幅铺垫传统方法的问题。语音识别领域在深度学习普及之前主流方案是“高斯混合模型隐马尔可夫模型”的组合。音频信号要先手工设计滤波器组、MFCC这类声学特征再对每个音素建模还要通过强制对齐把音频帧对应到状态序列上。文本处理这边常用的是n-gram语言模型加上条件随机场做序列标注靠人工设计词性、句法、词典特征来辅助分类。传统方法最麻烦的地方不是精度低而是“迁移成本高”。换一个领域比如从新闻领域迁移到客服对话领域词表会变、口音会变、说话风格会变大量特征要重新设计标注规则也要跟着调整。课程里说得很直白特征工程是一个高频、费力、且很容易到瓶颈的工作而深度学习的核心动机恰恰是想让模型自己从数据里学出这些内部表示。我当时听到这里挺有共鸣。以前做传统文本分类时每次换业务线都要花一周时间调词典、调规则效果还不稳定。后来切到深度学习方案虽然也要调参但至少不用再一个词一个词去归纳规则了。课程想传递的核心逻辑就是语言处理中真正有用的信息隐藏在原始信号里与其让人去总结规则不如让模型在大规模数据上自己找出规律。1.3 端到端学习的核心思想深度学习在语言处理上的关键转变是从“多模块流水线”变成“端到端学习”。传统语音识别系统内部要拆成声学模型、语言模型、发音词典、解码器几个模块每个模块分别训练再拼装到一起。端到端模型则走另一条路输入声学特征直接输出文本序列中间所有模块由神经网络的隐藏层承担用一个统一的目标函数训练。课程里反复用一个词来概括这个过程end-to-end。它并不是说中间没有任何结构而是说我们不再手工指定“特征怎么抽、对齐怎么做、语言模型怎么融合”这些中间步骤。模型自己决定用什么样的内部表征来完成任务。我理解端到端最大的价值在于“免去人工误差的传递”。以前在流水线里每个模块都会注入一些人工假设比如音素集怎么定、词典怎么构建一旦假设错了后面再怎么调都很难补偿。而端到端模型把这些问题交给优化器虽然训练难度变大、需要更多数据但上限更高。课程在语音识别部分介绍的CTC和注意力式序列到序列模型本质上都是在解决同一个问题怎么在没有精确对齐标注的情况下让模型学会从语音序列映射到文本序列。这个思想后来也一直指导我处理序列数据的各种任务。2. 注意力机制与Transformer整门课的题眼2.1 RNN的困境与Self-Attention的出场逻辑如果只让我留一个课程重点我会留注意力机制。课程从循环神经网络开始讲序列建模再一步步过渡到Transformer这个演进过程本身就是整门课的骨架。RNN处理序列的方式是逐步递推t时刻的隐状态由t-1时刻的隐状态和当前输入共同决定。它的优点是天然符合“语言是顺序的”这一直觉缺点是长距离依赖很难建模。一个词可能和距离很远的另一个词存在指代关系但信息在逐层传递中会衰减、被干扰。课程里用了一个很形象的类比RNN就像一个只能一个字一个字往后读的人读到后面时前面内容已经模糊了。另外RNN无法并行因为每一步都依赖前一步的隐状态这在现代大规模训练中是个致命短板。Self-Attention的出现把“顺序处理”改成了“并行扫描”。它一次性看完整段输入通过计算任意两个位置之间的相关度来捕捉依赖关系。比如在“那只猫因为它很可爱所以我买了它”这句话里模型可以直接算出后面“它”和前面“猫”的关联而不需要经过一个词一个词的递归路径。课程把这一步视为深度学习序列建模的分水岭从“记住前面的信息”变成“直接去前面的位置取信息”。2.2 Query、Key、ValueAttention的具象化理解上课时第一次接触Query、Key、Value这三个词我其实有点懵。后来发现把Attention想象成一个“检索系统”就清楚了。Query是“我在找什么”每个位置都会发出一条查询指令Key是“我身上有什么标签”每个位置都把自己的标识亮出来Value是“我实际携带的信息”。模型做的事情就是拿Query去和所有位置的Key做相似度计算得到一组权重再用权重去加权求和所有位置的Value。这个过程可以理解为当前这个词需要从句子中其他哪些词收集信息、收集多少。用公式写就是先算Query和Key的点积除以根号下的维度以稳定梯度然后过softmax变成权重最后和Value加权求和。课程特别强调那个缩放因子点积结果过大会让softmax落到饱和区梯度变得非常小训练就容易停滞。我在自己写注意力代码时也踩过这个坑没加缩放loss确实降不下去加上之后就恢复正常了。2.3 Multi-Head与位置编码两个容易被忽略的细节课程在讲Transformer时对Multi-Head Attention和位置编码的讲解让我印象很深因为这两块恰恰是最容易被“拿着就用”的人略过的。多头注意力简单说就是把注意力计算切成多个子空间并行做每个头关注不同类型的关联。有的头可能在关注代词和实体之间的指代关系有的头在关注相邻词的局部语法关系有的头在关注句子级全局语义。课程用了一个很接地气的类比单头注意力像一个只从单一视角看问题的人多头则像请了一组专家从不同角度同时审视同一段文本最后把意见汇总。位置编码则解决一个更基础的问题Self-Attention本身是不带顺序感的它把输入当成一个集合如果把词的顺序打乱注意力计算结果完全一样。但语言中顺序至关重要。Transformer原始做法是往输入向量上加一组固定或可学习的正弦位置向量让模型能从向量的数值差异中感知“哪个词在前、哪个词在后”。课程还提到之所以用正弦函数是因为这种编码方式天然具备表达相对位置的能力两个位置的编码之差可以写成另一个编码的某种变换模型有机会学会“间隔几个词”这类相对关系。这个细节后来我在处理语音任务时体会更深因为音频帧的顺序就是时间顺序没有位置信息模型连基本的因果关系都学不了。2.4 Encoder-Decoder结构与语音任务的结合课程并不只在文本语境里讲Transformer它还专门讲了语音任务如何套用这套结构。语音识别里典型的LAS模型就是把声学特征序列喂给Encoder把Decoder用作逐字生成文本的模块语音合成则反过来输入文本embedding输出频谱帧序列。Encoder和Decoder共享一套注意力机制但负责的语义不同。让我印象最深的是Encoder部分对语音的处理方式。音频一秒钟常有上百帧直接做Self-Attention计算量会非常夸张。课程讲了几种降采样策略比如相邻帧合并、金字塔结构、或者用卷积层做局部下采样之后再接注意力层。这些做法本质上是在“局部感知”和“全局建模”之间做平衡先用卷积提取局部节奏信息再用注意力捕捉长距离语音模式。这部分课程还对比了CTC和注意力式模型的区别。CTC假设帧与输出之间存在单调对齐适合语音识别这种“说话顺序和文字顺序基本一致”的任务而注意力式模型更灵活能处理一些倒装、改写的情况。但灵活也带来风险就是可能出现重复或漏词。课上提到用“强制长度控制”或“覆盖惩罚”来约束重复这类招式我在实际项目中直接用过对解码质量的提升很明显。这个对比教会我一件事没有“最好”的模型结构只有“和任务匹配度更高”的结构。3. 预训练时代BERT、GPT与迁移学习的课程视角3.1 预训练为什么在2020年前后成为共识课程录制的时间点正好赶上预训练语言模型崛起。授课老师对BERT、GPT、XLNet这批模型的讲解不是只讲代码怎么用而是讲它们到底在学什么。这也让我第一次真正理解“预训练微调”这套范式为什么能统治整个NLP领域。预训练的思路是先在超大规模的无标注文本上训练一个通用的语言模型让它学会“一段文本大概率长什么样”然后再用下游任务的小规模标注数据去微调。无标注数据几乎无限而标注数据非常昂贵预训练解决了“数据不够”这个根本性问题。BERT学的是掩码语言模型随机遮住一些词让模型根据上下文猜测被遮住的词GPT学的则是自回归语言模型给定前面的词预测下一个词。两者都是让模型从文本本身构造监督信号不需要人工标注。课程里反复强调预训练模型的真正价值不在模型大小而在于它学到的中间表征可以迁移。之前做文本分类每个任务都得从头训练一套网络学到的特征高度任务相关。预训练出现以后绝大部分任务共享同一套底层语言理解能力下游只需做一层轻量适配。这个变化对整个行业的影响是革命性的很多以前需要大量标注数据的任务现在几十条样本就能跑出可用的结果。3.2 理解型任务与生成型任务的本质差异这是整门课里我记住的最重要的一句话做任务之前先区分它是“理解型”还是“生成型”。BERT类模型适合前者GPT类模型适合后者选错类型效果会差一个量级。理解型任务比如文本分类、情感分析、句子对匹配需要的是把输入文本压缩成一个语义表示再做出判断。BERT的掩码训练天然引导模型学会双向上下文建模编码出的向量对“含义”表达得更充分。生成型任务比如机器翻译、摘要、对话需要的是逐词产出连贯输出GPT的自回归训练方式和生成过程完全一致模型在训练时学的就是“接着写”推理时也自然“接着写”。课程里提到一个有趣的对比如果硬要BERT做生成你需要在解码时不断把已生成的内容重新喂给模型让它预测下一个词但训练时BERT并没有见过这种自回归的用法训练和推断不一致效果就会打折扣反过来用GPT做分类虽然能做但它只能看到单向上下文对语义的理解天然不如双向模型完整。所以选型的第一原则不是“哪个模型更强”而是“哪个模型的训练目标跟我的任务形态一致”。这一节还讲了不同任务的输出形式对模型结构的要求。比如分类任务只需要取出[CLS]位置的向量接一个线性层序列标注任务需要每个位置都输出标签机器翻译任务则要把Encoder和Decoder组合使用。同样是“用预训练模型”不同任务的搭法完全不同。听这一节时我正好在处理一个客服意图分类项目原本打算直接拿一个生成式大模型硬套听完课就回去换成了分类式微调训练成本和推理延迟都降了一个级别效果还更好。3.3 微调的实践细节与常见误区课程在讲迁移学习时专门花了力气讲“怎么把预训练模型微调好”。这些在理论课上容易被跳过但恰恰是工程里决定成败的地方。第一个细节是学习率要小。预训练模型已经在一个大空间里收敛到不错的位置微调相当于在附近做局部移动学习率太大容易直接冲出好区域造成灾难性遗忘。实践中常用1e-5到5e-5这样的小学习率配合warmup策略前一小部分训练步数把学习率从零慢慢升上来让模型平稳进入微调状态。第二个细节是层与层的差异。靠近底层的参数学到的是通用语言特征靠近顶层的参数学到的是更任务相关的特征。所以有些方案会给不同层设置不同学习率底层小一点、顶层大一点。课程里把这称为“分层解冻”或“分层学习率”我在做小数据项目时用过稳定性和收敛速度确实都有改善。第三个细节是“数据太少时不要盲目加大模型”。课程里明确说了大模型在小数据场景下更容易过拟合预训练带来的增益会被微调阶段的overfitting抵消。我后来遇到过一个情况只有两千条标注数据用大模型微调的效果反而不如用一层简单的池化加逻辑回归。这说明预训练模型不是银弹它的上限依赖数据和训练策略的匹配。课程还提到一个评估细节微调之后看训练集和验证集loss的差距如果差距快速拉大说明过拟合开始了应该提前停止或加正则。这个判断标准我几乎用在了所有后续项目中比单纯看准确率曲线可靠得多。4. 课程笔记的二次加工从课堂知识到可用方案4.1 把课程结论映射到实际任务听课是一回事把笔记变成能用的项目方案是另一回事。我自己的做法是每听完一个章节就停下来问自己三个问题这个技术解决什么任务如果换到我的业务场景输入和输出分别是什么需要做哪些预处理和后续处理这门课让我建立了一个很朴素但好用的决策流程。先判断任务形态输入是连续信号还是离散符号输出是类别标签、序列还是结构化对象再选模型家族理解型任务走双向编码器生成型任务走自回归解码器需要序列到序列映射就走编码器-解码器结构。然后考虑数据规模数据量少就尽量用预训练模型加轻量微调数据量充足再考虑从零训练或者引入领域自适应。我曾经做过一个语音质检的场景将客服对话转成文字再从文字里判断有没有违规话术。按课程的框架拆解这就是语音识别加文本分类两条链路串联。语音识别部分用序列到序列模型文本分类部分用双向编码器加分类头。拆完之后整个系统的边界一下子清晰了连数据标注的负责人看了流程图都能直接对号入座。4.2 一个最小实现意图识别模型的演进过程为了把课程内容落到实践我做了一个特别简单的意图识别Demo从零实现再到用预训练模型微调。整个过程就是课程知识的浓缩版本。第一版我用关键词和线性分类器做基线。输入是用户问题输出是几个预设意图类别比如“查天气”“订闹钟”“玩游戏”。这版模型几乎没有泛化能力换个问法就识别不了准确率在测试集上只有62%左右。但它的作用是给出一个最低参照线后面所有改进都跟它对比。第二版我换成了带注意力机制的循环网络。输入嵌入层映射成向量过一个双向循环层提取语义再接注意力层做加权汇总。这版模型能捕捉一些关键短语的上下文关系准确率提到78%但训练速度慢而且对长句的依赖关系依然不稳定。我的笔记里在这个版本旁边写了一句话“循环网络适合序列但注意力才是长依赖的正解。”第三版我用预训练模型微调取双向编码器的首层向量拼一个分类头用交叉熵训练。同样的数据和超参调优下准确率到了91%。这个提升不在于我调参多强而是预训练模型已经掌握大量语言知识下游任务只需要很小的修正。我把三版结果列成一张对比表每次给团队做方案汇报时都直接拿它说话。版本方案准确率训练耗时备注v1关键词线性分类器62%秒级无泛化能力v2双向循环网络注意力78%半小时长依赖仍弱v3预训练模型微调91%一小时需控制过拟合4.3 评估指标与数据陷阱课程花了不少篇幅讲评估这部分我收获很大因为我见过太多只看准确率翻车的情况。分类任务如果类别严重不平衡准确率会非常具有欺骗性。比如某意图占90%模型只要全部预测成那个类别准确率就有90%看起来很高实际一点用都没有。课程给的思路是看精确率和召回率的调和平均也就是F1分数并且按每个类别分别看而不是只盯一个综合数字。我在项目里也延续了这个习惯任何分类模型的验收单上都会同时列出每个类别的precision、recall和F1。语音任务也一样只看整句识别准确率不够还要看字错误率或词错误率这两个指标能反映插入、删除、替换三种错误类型。课程里讲到WER并不是越低越好很多时候漏字被算成删除多字被算成插入不同错误对下游任务的影响完全不同。比如在语音质检场景漏掉一个“不”字可能直接把语义反转但模型不会为你区分这种错误类型只有靠人工抽样去查。另一个容易被忽略的是数据泄露。课程举了一个例子做对话意图识别时如果把用户ID或时间戳当特征一起训练模型可能学到“某类用户只问某类问题”的捷径切到新用户时效果骤降。我后来在检查数据管道时也发现过类似问题好在及时发现否则模型上线后就是事故。5. 把课程价值用透复听、复现与延伸学习5.1 带着问题听第二遍第一遍看课程我是跟着老师的节奏走把每个模型、每个公式记下来就觉得自己懂了。实际上这种“懂”很浅。第二遍回看时我带着工作里真实遇到的问题去听效果完全不同。比如第一次听位置编码时我只记住了“加一个向量表示顺序”。后来在做一个语音合成的项目时发现模型拼接出来的音频在句子后半段经常出现节奏错乱我回头翻课程笔记才意识到问题可能是位置编码在小规模数据下没有充分学习导致长距离的相对位置关系没有学准。带着这个问题重新听了那节课理解深度完全不一样一眼就知道该去改编码方式还是该加数据。所以我的建议很简单这类内容丰富的课程不要指望一遍吃透。第一遍建立地图第二遍带着地名去找路第三遍才能把路走顺。每看一遍笔记都应该被“推翻”一部分那才是真正吸收了。5.2 复现课堂实验的避坑记录复现课程里的实验是个值得做的事但坑也不少。第一条坑是数据预处理不一致。同样的模型在不同分词方式、不同特征归一化方法下结果能差好几个点。课程里讲的东西默认数据已经清洗好了但实际复现时你用的英文文本和中文文本的处理方式完全不同自己要做决定。第二条坑是超参数敏感。Transformer类模型对学习率和warmup步数极其敏感我复现时一开始用默认学习率loss完全不收敛后来改成先warmup几百步再用小学习率才稳定下来。这种问题不是模型写错纯粹是优化策略不对。第三条坑是代码版本。课程讲解的是原理但框架的接口迭代很快旧代码换了版本就跑不通。我建议复现时锁定一份固定的环境不要追新。课程里讲的很多细节比如位置编码的实现、注意力权重的可视化在不同版本里接口都不一样查文档的时间经常比写代码还多。第四条坑是资源意识。很多公开课的实验示例是小规模玩具版本直接放大到真实数据会碰到显存、训练时间、分布式通信等问题。课程里的“训练了一个下午”可能是指单机单卡项目里要变成几天甚至几周的调优。所以复现时最好先在小数据集上跑通流程再逐步放大不要一上来就全量数据。5.3 顺着课程引文建立自己的知识网络课程每讲后面都列了一串参考文献这是我后来才发现的金矿。很多网上的二手博客只会告诉你某个模型“好用”但课程引用的原始论文会把“为什么这么设计”讲透。我的做法是建了一个表格把课程里提到的每篇论文按任务分类语音识别一组、文本分类一组、预训练模型一组、生成模型一组。每篇论文记录核心思想、关键公式和它引用的更早文献。这样顺着引文的引用链往前翻就能把一门课扩展成一个知识树。比如看Transformer时只读原论文是不够的还要读它前面关于注意力机制的那几篇论文才能理解为什么Self-Attention被设计成Query-Key-Value的结构。看BERT时要往前翻神经机器翻译里的预训练方法才能理解掩码语言模型到底“预训练”了什么。这种阅读方式比较费时间但对理解深度帮助极大而且能逐渐培养出筛选信息的能力不会一看到新模型就被牵着走。我自己现在看任何资料都会先问一句这条知识放在我已有的框架里属于哪一类如果框架里没有位置我就先补框架再存细节。这套习惯就是从这门课笔记的整理方法里长出来的。最后再分享一个我反复用的小技巧课程笔记不要只记结论要记“推导过程中的选择点”。比如为什么用多头而不用单头为什么用正弦位置编码而不用可学习位置编码。这些选择点才是课程真正值钱的地方因为换一个任务、换一批数据结论可能就不适用但你重走一遍推导过程就能自己得出新的结论。这门课对我来说最大的价值不是让我记住了多少模型结构而是让我养成了一种习惯看到一个语言处理任务先想清楚它的序列本质再决定用什么模型去映射。这个习惯后来帮我在好几个项目里少走了很多弯路。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →