今早在赶地铁时刷到一个关于Dropout的旧帖,让我不禁思考:那些初看让我觉得“这靠谱吗”的方法,却往往是这些年最成功的突破。 比如Dropout、残差连接等。今天,我们就来聊聊深度学习中几个经典的 “第一眼像瞎搞,实际越想越妙” 的算法。
1、Dropout:随机让神经元“罢工”
2014年,Hinton发表了一篇里程碑式的论文,其核心思想用一句话就能概括:每次训练时,随机“关闭”网络中约一半的神经元。
初见此思路,我的反应大概和很多人一样:训练时一半节点都在“罢工”,这能学到东西吗?更让人疑惑的是,论文提到推理时只需将输出乘以保留概率 p(比如0.5)即可。实验结果却让人“脸肿”——Dropout不仅可行,且效果显著,普遍能提升模型2-5个百分点的性能。
后来理解了解释才恍然大悟。Dropout的本质,是在训练过程中同时训练了大量不同的子网络。 例如,一个100个神经元的网络,使用保留率为0.5的Dropout,理论上可以组合出 2^100 个不同的子网络。每个mini-batch训练时,都在优化其中一个随机子网络。推理时,所有可能子网络的输出做一个“平均”(乘以0.5即是这种平均的数学近似)。
这就像一个公司的项目,不让固定团队从头做到尾,而是每次随机抽调一个小组来完成一部分。这样做有个明显好处:没有任何一个神经元可以偷懒。 因为它不确定自己下一轮是否还在“岗”,所以必须学会“独立工作”,掌握有意义的特征——颇有几分进化论中“适者生存”的意味。
学术上,这被称为 “防止co-adaptation” ——防止神经元之间形成过度的、不必要的依赖关系,从而有效缓解过拟合。
另一个视角是,Dropout相当于施加了一种强正则化。但与传统的L2正则化不同,Dropout是一种数据依赖的正则化——它不直接惩罚权重的大小,而是通过对网络结构的随机扰动,迫使模型变得更为鲁棒。
有趣的是,Hinton后来透露,其灵感来源于银行的反欺诈系统:银行不会让任何一个员工看到完整的客户信息,以防内部勾结。这个类比确实精妙。
但Dropout并非万能,也有“翻车”的时候。 在现代大模型(如GPT、LLaMA等)的训练中,Dropout已很少使用。原因很简单:大模型本身参数量和数据量巨大,过拟合风险相对较低,而Dropout引入的随机性反而会降低训练效率,并使收敛行为更难以预测。因此,技术发展的趣味在于,一个方法在特定场景是“神器”,换一个场景可能就成了“累赘”。
2、SGD:最“朴素”的优化器,却常有意外之喜
随机梯度下降(SGD)可能是深度学习里最“朴素”的优化方法。每一步,随机抽取一小批(Mini-batch)数据,计算梯度,然后朝梯度反方向走一小步。没有动量,没有自适应学习率,没有二阶近似。就是:算个方向,走一步,完事。
这听起来效率低下,好比开车去目的地,不看地图,每步随便选个方向挪一下。但SGD不仅总能到达“目的地”,而且在模型的泛化能力上,常常优于Adam、AdaGrad等更“高级”的优化器。
直到2020年,论文《Towards Theoretically Understanding Why SGD Generalizes Better Than ADAM in Deep Learning》给出了一个比较令人信服的解释:SGD的“随机性”恰恰是其最大优势。
具体来看:
第一,SGD天然具备“跳出局部最优”的能力。 因为每次只用一小批数据,计算出的梯度本身带有噪声。这个噪声看似是“误差”,却可能帮助模型跳出不良的局部最优解。想象下山:如果每一步都精确沿最陡方向走,很容易卡在半山腰的小坑(局部最优)里。但如果每步因只看一小片地形而稍有偏差,反而可能跳出小坑,找到更深的山谷。
第二,SGD倾向于找到“更平坦”的最优解。 多篇论文(如Keskar等人的“Large Batch Training of Neural Networks”)发现,SGD收敛到的损失函数区域通常比较“平坦”,而Adam等优化器倾向于“尖锐”的区域。平坦意味着在最优解附近稍作移动,损失变化不大;尖锐则意味着稍一偏离,损失就急剧上升。因此,SGD找到的解泛化能力通常更好,因为它对训练数据与测试数据之间的微小差异更鲁棒。
第三,SGD的噪声本身起到了正则化作用。 这种噪声限制了模型过度拟合训练数据中细节的能力。
“SGD的噪声带来好泛化”这一洞察已深刻影响现代训练策略。虽然当前大模型训练多用AdamW等优化器,但我们会通过调整Batch Size与学习率的比例,甚至引入SAM(锐度感知最小化)等算法,刻意保留或模拟SGD那种“跳出局部最优”的宝贵能力。
3、残差连接:给网络一条“偷懒”的高速公路
2015年,何恺明团队的ResNet横空出世,将ImageNet分类错误率一举降至3.57%,首次超越人类水平。ResNet的核心贡献,就是那个著名的残差块公式:
y = x + F(x)
就这么一行。它所做的,是把这一层的输入 x,直接加到该层的输出 F(x) 上。
当初很多人疑惑:这为啥有效?如果 F(x) 学到了0,那这层不是白加了吗?但它恰恰精准命中了当时深度学习的头号难题:网络退化问题。
在ResNet之前,人们发现一个怪象:当网络深度增加到一定程度后,继续加深反而会导致训练误差上升。 理论上,深层网络只要让新增的层学习恒等映射(F(x) = x),效果至少不该比浅层网络差。但实践表明,让几十个带ReLU的非线性层去精确模拟一个简单的 y=x 是极其困难的,信号在层层传递中早已失真。
何恺明团队的洞察深刻而直接:既然让模型学会恒等映射这么难,那我们直接把它设置为默认选项。 残差连接的巧妙之处在于,它将“学习恒等映射”这个艰巨任务,转变为了“学习残差”。
有了捷径连接(Shortcut),如果某一层真的“没用”,它只需要学会输出 F(x) = 0 即可。学习“零映射”比学习“恒等映射”简单太多了——神经网络权重初始化通常接近0,这几乎不需要太多优化就能实现。所以,残差连接本质上赋予了网络一个“偷懒”的选择权:如果这一层有用,就学习有意义的变换;如果没用,就输出接近0的值,让信息主要从捷径流过。
此外,残差连接还从根本上缓解了梯度消失问题。在没有捷径的深层网络中,梯度回传遵循链式法则的连续乘法。若每层回传梯度模长小于1,几十层连乘后梯度将趋于消失,底层参数无法有效更新。有了残差连接,梯度可以沿着捷径这条“高速公路”直接、快速地传回浅层,这使得训练成百上千层的网络成为可能。
当然,残差连接也并非完美。 正如之前讨论过的Kimi团队《Attention Residuals》工作(原文链接)所指出的,经典残差连接将所有层的贡献等权重相加(权重为1),可能导致早期层的关键信息被后期层的噪声稀释。他们的改进思路是利用注意力机制自适应地加权各层贡献,这想法本身也源自对残差连接本质(可视为RNN翻转90度)的深入思考。
4、层归一化(LayerNorm):稳定深度网络的“质检员”
层归一化(Layer Normalization)的操作,一句话就能说清:把每一层所有神经元的输出,减去其均值,再除以其标准差。 之后,再通过两个可学习的参数 γ(缩放)和 β(平移)进行调节。
如此简单的一个统计学标准化操作,为何成为几乎所有大模型的标配?因为它解决了一个核心问题:深度网络中,层与层之间输入分布会发生剧烈漂移。
在深度网络中,前一层的输出就是下一层的输入。如果前一层的输出分布突然剧烈变化(例如均值从0漂移到100),下一层的权重就需要费力地重新适应这个新分布。层数越深,这种因非线性变换累积导致的分布漂移就越夸张。
LayerNorm通过在每一层之后强行进行标准化,将输出分布拉回到一个相对稳定的范围(均值为0,标准差为1),然后通过 γ 和 β 让网络恢复必要的表达能力。
打个比方:LayerNorm就像工厂流水线上的质检员。 每道工序完成后,质检员检查产品规格,若偏差过大就调整校准,然后再送入下一道工序。没有这个环节,工序越往后,累积偏差越大,最终产品可能完全不合格。
LayerNorm有个知名的“兄长”叫批归一化(BatchNorm),它是对一个批次内所有样本的同一特征进行标准化。在深度学习领域,尤其是大语言模型中,LayerNorm完胜。原因在于:NLP任务中序列长度可变,BatchNorm难以处理;且BatchNorm在小批量(Batch Size)下效果不稳定。在视觉领域,虽然BatchNorm曾是CNN的标配,但近年来随着ViT等模型的兴起,LayerNorm的应用也越来越广泛。
此外,一个值得关注的变体是RMSNorm(均方根归一化)。它被当前许多大模型采用,原理更简单——不减均值,只除以均方根。效果与LayerNorm相当,但计算量更小。在训练千亿参数模型时,这点效率提升累积起来相当可观。
5、学习率预热(Warmup):训练大模型的“温柔起步”
训练大模型时,几乎人人都会用到一个技巧:学习率预热。
具体做法是:训练初始的几百到几千步,学习率从一个接近0的极小值开始,线性或按某种策略缓慢增大至预设的目标值,然后再按照既定计划(如余弦退火)逐渐下降。
仔细想想,这非常符合直觉。以Transformer为例,其参数在初始化时是随机的,初期梯度方向极其混乱且噪声大。若此时使用大学习率,就像蒙眼跨大步,极易“失足”掉进损失函数的“悬崖”。Warmup的作用就是:在训练初期,让模型先用小碎步“试探”和“感受”地形,找到一个相对安全稳定的下降方向后,再加速前进。
Warmup的另一个关键作用是稳定自适应优化器(如Adam/AdamW)。Adam类优化器会根据历史梯度方差为每个参数自适应调整步长。但在训练最开始的前几步或几十步,由于见过的数据太少,估计出的方差极不稳定、误差极大。Warmup提供了一个“热身”期,让优化器积累足够的梯度信息,待其方差估计相对稳定后,再切换到正常的学习率进行训练。
例如,在GPT-3的训练配置中,Warmup阶段使用了约3.75亿个token,约占其总训练量的0.1%。对于训练成本动辄数百万美元的大模型而言,用0.1%的算力成本为整个训练过程“买一份保险”,防止因初期不稳定而导致训练崩溃,无疑是极其划算的。
写在最后
回顾这些经典的算法与技巧,我发现一个有趣的模式:真正高效且影响深远的算法,往往第一眼看起来不够“聪明”或“复杂”。 它们并非源自繁复的数学推演,而是源于对训练过程中真实发生的问题的本质洞察。
Dropout的灵感来自银行防欺诈,残差连接源于对“网络学不会恒等映射”这一现象的直面,SGD的泛化优势是在无数次实验后才被后知后觉地理解。这或许正是深度学习乃至整个AI领域最独特的魅力所在——实践经常领先于理论,我们往往是先发现某个技巧“行之有效”,然后花费数年去探究它“为何有效”。
所以,下次当你再看到一个“看起来不太正经”的新方法时,不妨先别急着否定。它的背后,可能藏着比我们想象中更为深刻的逻辑与智慧。技术的演进总是在打破常规,而保持开放与好奇,正是我们能在云栈社区这样的技术论坛中持续学习和成长的关键。