ARTICLE DETAIL

资讯详情

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

L1与L2正则化详解:从稀疏解到软阈值算子

L1与L2正则化详解:从稀疏解到软阈值算子 做过广告点击率预估的朋友应该都体会过这种痛特征上百万维模型文件动不动几百兆线上推理一次要等十几毫秒。我之前一版逻辑回归就是这样后来在损失函数里加了L1正则化把惩罚系数调到合适值一版下来超过一半的特征权重直接变成0模型文件缩到原来的三分之一推理耗时肉眼可见地降下来。当时组里有同事问我“为什么加L1能把权重清零加L2却只是把权重压小”这个问题其实问到了机器学习里最基础、也最容易被一句“L1稀疏、L2平滑”带过去的点上。L1正则化和L2正则化是机器学习、深度学习里最常用的两种正则化手段。这篇文章不打算停留在“L1做特征选择、L2防过拟合”这种口号层面而是把两者背后的数学推导、几何直觉、贝叶斯解释和工程调参经验摊开来讲尤其是会重点拆一个最近经常被问到的热词软阈值算子为什么是L1正则化的解。搞懂这一层你才算真正理解L1为什么能产生稀疏解。1. 正则化到底在解决什么问题1.1 过拟合模型记住了不该记住的东西不先讲清楚正则化在解决什么问题后面说L1和L2的区别都是空中楼阁。过拟合的典型症状大家都见过训练集准确率99%验证集掉到82%训练loss一路往下走验证loss却开始反弹。很多新手第一反应是加数据、加dropout但很少有人意识到过拟合的本质是模型复杂度和样本量不匹配。我习惯用一个比喻理解这件事模型就像一个备考的学生训练数据是模拟题。如果学生只盯着一套模拟题死记硬背连题目里的错别字都背下来换一套新题就抓瞎——这就是过拟合。正则化相当于给学生立一条规矩可以答题但每个知识点只能记有限的笔记不能把整本书抄上去。这个“限制笔记量”的机制落到损失函数里就是给权重“上税”。还有一个很容易被忽略的场景是p远大于n的问题也就是特征数量远大于样本数量。比如基因表达数据可能只有几百个样本但特征有上万维或者文本分类里的词袋模型样本几万条特征几十万维。这种时候模型有无穷多种方式完美拟合训练集不加正则化几乎必然过拟合。正则化不是锦上添花而是能不能用的问题。1.2 正则项是如何被加进损失函数的原始损失函数只关心一件事预测值和真实值之间的误差比如平方误差或者交叉熵。为了让模型不过于复杂我们在损失后面加一个关于权重的惩罚项$$ J(\mathbf{w}) L(\mathbf{w}) \lambda \cdot \text{penalty}(\mathbf{w}) $$这里很重要的一点是惩罚项只针对权重不针对偏置。原因是偏置只是一个平移项它不会让模型变得弯曲或复杂惩罚它没有意义。这个细节很多代码里没注意框架默认对bias也做了weight decay后面我会再提。λ是正则化强度的控制旋钮λ0 的时候就是普通训练模型想怎么复杂就怎么复杂λ特别大的时候权重被压得接近0模型几乎变成一个常数预测器。从方差-偏差的角度看λ增大是牺牲偏差换方差模型变得简单但对数据的拟合能力下降。所以调正则化系数本质上是在偏差和方差之间找平衡点不存在一个万能值必须依据具体数据试。2. L1和L2的数学定义与第一层直觉2.1 数学形式的本质差异先把两个公式摆出来。加了L1正则后优化目标变成$$ J(\mathbf{w}) L(\mathbf{w}) \lambda \sum_{j1}^{p} |w_j| $$加了L2正则后优化目标变成$$ J(\mathbf{w}) L(\mathbf{w}) \frac{\lambda}{2} \sum_{j1}^{p} w_j^2 $$单看公式好像只是把绝对值换成了平方但这一点差别导致了完全不同的行为。为了后面算梯度方便L2通常写成 λ/2 乘以权重平方和求导的时候那个2被消掉梯度就变成 λw。L1的梯度就有意思了它是 λ·sign(w)也就是不管权重是0.001还是0.1只要符号相同梯度贡献都是同一个固定值。这个数学差异直接决定了两种正则化的性格。我做了一个对比表方便快速抓重点对比项L1正则化L2正则化惩罚形式|w| 的绝对值之和w² 的平方之和的一半权重更新时的额外项恒定向0方向拉大小为λ按比例缩放权重系数(1-ηλ)解的特点大量权重精确等于0产生稀疏解权重被压小但不精确归零对离群大权重的态度惩罚力度恒定相对温和惩罚随权重大小线性增长更严厉典型应用特征选择、模型压缩、可解释模型防止过拟合、提升泛化、深度学习weight decay约束区域的几何形状菱形/多面体角在坐标轴上圆形/球体表面光滑2.2 “固定人头税”和“收入累进税”的直觉我第一次接触L1和L2时觉得所有解释都太抽象后来找到一个类比豁然开朗。把权重想象成收入正则化想象成税收。L2是累进税收入越高税率越高所以高收入大权重会被狠狠砍一刀低收入小权重几乎感觉不到压力但永远不会把收入清零。L1更像固定人头税不管你收入多少只要你有收入就得交固定一笔钱。一个权重是0.01还是0.1对L1来说惩罚一视同仁都是λ。这时候一个小权重就会算账我存在的价值减少拟合误差可能还不如我交的税多干脆把自己清零拉倒。这也是为什么L1能做到真正稀疏对微小权重下狠手逼它们归零而L2对接近0的权重几乎不构成压力权重就停在0附近的小值上永远差一口气到0。理解了这层后面看软阈值算子的时候会特别顺畅。3. 为什么L1产生稀疏解三个视角讲透3.1 几何视角菱形与圆的差别第一个视角是几何的也是最直观的。假设模型只有两个权重 w1 和 w2原始损失函数的等高线是以无约束最优解为中心的一圈圈椭圆。加正则化相当于在权重空间里加了一个可行域L1的可行域是菱形L2的可行域是圆。优化过程就是让椭圆等高线向外扩张直到和可行域边界相切切点就是最优解。关键差异就在边界的形状。菱形的四个尖角正好落在坐标轴上等高线往外扩的时候最先碰到尖角的概率远大于碰到边的概率。一旦切点落在坐标轴上就意味着另一个权重等于0——稀疏解就这样产生了。圆不然圆表面是光滑的切点通常不在坐标轴上大概率落在某个非零位置于是两个权重都被压缩但不归零。推广到高维空间这个差异更明显。L1的约束区域是高维多面体有大量尖角落在坐标轴上维度越高尖角数量相对表面面积的比例越大解撞到尖角从而稀疏的概率也越高。这也是为什么在高维稀疏特征场景下L1几乎是必选——维度越高L1的稀疏效果越显著。3.2 梯度视角L1的“拉回”和L2的“缩放”几何视角解释了最优解长什么样但没有回答训练过程中权重是怎么一步步走到0的。这个问题得从梯度更新看。先说L2。用梯度下降更新权重L2带来的额外梯度是λw。假设训练数据的梯度部分是g更新公式为$$ w \leftarrow w - \eta (g \lambda w) (1 - \eta\lambda) w - \eta g $$注意看这个 (1 - ηλ) 系数它小于1。也就是说即使没有数据梯度g每一步权重也会被等比缩小一点。这个操作在深度学习的框架里有个专门的名字叫权重衰减weight decay它像一个永不停歇的抽水泵持续把权重往外抽。但问题是当w越来越小的时候λw也越来越小抽水力度同步变小所以权重会无限逼近0却永远到不了0。再看L1。L1带来的额外梯度是λ·sign(w)更新公式为$$ w \leftarrow w - \eta (g \lambda \cdot \text{sign}(w)) $$这里的关键在于λ·sign(w) 的模长是固定的λ不随权重变小而变小。哪怕w已经小到0.0001它受到的向0拉力仍然是完整的λ。这种恒定拉力的结果就是权重会被一直推到0推过0之后就改变符号然后又被反向拉回来最终在0处达到平衡。所以L1的解里会出现很多“精确等于0”的权重这不是近似值而是硬生生推出边界的结果。3.3 软阈值算子为什么L1正则化的解是它前面两个视角虽然直观但都没有回答一个更根本的问题L1正则化在0点不可导传统梯度下降根本没法处理这个点那优化算法到底是怎么处理它的这时候就要引出近端梯度法以及它的核心组件——软阈值算子。先说结论L1正则化对应的近端算子就是软阈值函数。给定一个变量z软阈值算子的定义是$$ \text{soft}(z, \tau) \text{sign}(z) \cdot \max(|z| - \tau, 0) $$这个式子看起来简单但为什么会是这个形式它是从一个一步优化问题推出来的。考虑优化问题$$ \min_{w} ; \frac{1}{2}(w - z)^2 \tau |w| $$其中第一项把w往z上拉第二项要求w尽量小。解析求解需要分三种情况讨论可以看一眼推导情况1: w 0 f(w) (1/2)(w - z)^2 τ w f(w) w - z τ 0 w* z - τ 要求 w* 0即 z τ 情况2: w 0 f(w) (1/2)(w - z)^2 - τ w f(w) w - z - τ 0 w* z τ 要求 w* 0即 z -τ 情况3: w 0 需要0属于次梯度集合即 z 落在区间 [-τ, τ] 内 三种情况合并得到: w* sign(z) · max(|z| - τ, 0) soft(z, τ)这个推导透露出非常深刻的含义。当z离0比较近绝对值不超过τ时最优解直接就是0。为什么因为此时如果把w从0挪到z拟合误差的减少量还比不上因为引入非零权重而付出的正则惩罚τ|w|不划算。只有当z离0足够远绝对值大于τ才值得把w移动到z方向但也不能完全到z而是要收缩τ这么多。这就是软阈值名字的由来不是硬性保留或砍掉而是先砍掉τ剩下的如果还是正的才保留。那它和实际的L1优化有什么关系在训练过程中每一步迭代可以拆成两步。第一步先按常规梯度下降走一小步得到中间变量v第二步对这个v施加软阈值算子。写成迭代格式就是所谓的ISTAv w^{(t)} - η · ∇L(w^{(t)}) w^{(t1)} soft(v, η·λ)注意这里的阈值是η·λ不是λ。因为近端梯度推导里软阈值算子的惩罚参数是在缩放过的损失里出现的实际更新时要乘上学习率η。很多初学者照着公式抄把阈值写成λ结果发现稀疏效果完全不对越调越迷糊。到这里软阈值算子为什么是L1正则化解这个问题答案就很清晰了L1正则化的近端算子就是软阈值而近端梯度法就是在解决“不可导点怎么优化”的问题。每一次迭代中软阈值都会把所有绝对值小于阈值的权重直接置零这就是L1解稀疏性的最直接来源。3.4 硬阈值和软阈值的区别理解了软阈值顺便把硬阈值也说了因为两者容易混淆。硬阈值函数是如果|z|大于阈值就保留z否则直接置0。它对应L0范数非零元素个数的正则化是最理想的稀疏化方案但L0是非凸的优化起来是NP难问题。软阈值则是对L1凸松弛的结果不仅保留了稀疏化能力还让整个优化问题变得可解。两者的行为差异很微妙。硬阈值只做“保”或“斩”两个动作留下的权重原封不动软阈值不管权重最后是死是活先砍掉阈值那么长的距离。在实际效果上软阈值不会产生“阈值边缘突变”的问题连续性和稳健性更好。这也是为什么工程上用L1而不是直接去求L0我们牺牲了一点点理论上的最优稀疏性换来了可以在大规模数据上高效求解的可能性。4. 贝叶斯视角先验分布决定正则化类型4.1 MAP估计与先验第三个视角来自贝叶斯统计。这个视角对我来说就像打开新世界大门原来L1和L2的区别本质上是你对权重分布的先验假设不一样。在贝叶斯框架下训练模型等价于求解最大后验估计。后验概率正比于似然乘以先验$$ p(\mathbf{w} | D) \propto p(D | \mathbf{w}) \cdot p(\mathbf{w}) $$取负对数之后最大化后验变成最小化两项之和$$ -\log p(\mathbf{w}|D) -\log p(D|\mathbf{w}) - \log p(\mathbf{w}) $$第一项就是普通的损失函数第二项正是正则项。换句话说正则化不是外来的“惩罚”而是先验信念的自然表达。4.2 高斯先验对应L2、拉普拉斯先验对应L1如果假设权重服从均值为0的高斯分布即 w ~ N(0, σ²) 那么负对数先验就是$$ -\log p(w) \frac{w^2}{2\sigma^2} \text{常数} $$这一项正是L2正则的形式。所以L2正则化等价于告诉模型我相信权重都分布在0附近但允许有一些小偏差偏差的平方代价是逐渐增加的。如果假设权重服从拉普拉斯分布即 w ~ Laplace(0, b) 它的概率密度在0处有个尖峰两侧呈指数衰减。负对数先验是$$ -\log p(w) \frac{|w|}{b} \text{常数} $$这一项正是L1正则。拉普拉斯分布和正态分布的一个关键区别是拉普拉斯分布在0处有一个尖锐的峰值概率质量更集中在0附近同时它的尾部比正态分布更厚对远离0的大权重相对宽容。这两个特性放在MAP估计里就对应了“更倾向于精确的0”和“对大权重收缩相对温和”两个行为。4.3 这对实际建模的启示这个视角不仅仅是理论游戏它直接影响一个建模决策选L1还是选L2本质上取决于你对问题结构的理解。如果你认为绝大多数特征都是噪声只有少量特征真正对预测有贡献——比如基因数据、广告特征——那你的先验就是拉普拉斯分布应该用L1。反之如果你认为所有特征都有一定作用只是大小不同——比如一些平稳的物理过程、图像像素——那高斯先验更合理用L2。还有一个值得注意的推论L1的稀疏性错觉。很多人以为L1天然一定比L2更“好”其实只是先验假设不同。某些场景下L1的稀疏解反而有害比如两个强相关特征L1可能随机选一个保留导致模型不稳定。Zou和Hastie提出Elastic Net时正是为了解决这个问题把L1和L2结合起来用L2稳定相关特征的系数用L1产生稀疏性实践效果经常比单独用任何一个都好。5. 工程实践L1、L2怎么选、怎么用、怎么调5.1 场景选择特征稀疏化还是泛化稳定到了落地环节场景决定选择。我按自己的实践经验总结了一个大致规则不一定适用所有情况但作为起点是可靠的。如果你面对的是高维稀疏特征比如广告点击率预估、文本分类、用户画像这类动辄几十万上百万维的场景L1几乎是刚需。原因很简单维度越高模型存储和推理成本越大L1直接砍掉无用特征线上性能收益立竿见影。而且这类场景的特征天然稀疏很多维度的权重确实就应该是0。如果特征是中小规模、维度几百到几千或者你用的是深度神经网络那L2也就是weight decay是更稳的选择。深度学习里参数量巨大L1即使加进去也很难做到真正的稀疏化因为深层网络的权重是层层复合的单个权重是否为0对整体预测影响不大强行加L1常常导致训练不稳定。如果特征之间相关性很强比如两个特征本质上是同一个信号的两种编码这时候用裸的L1会随机丢弃其中一个造成不稳定。这种情况建议用Elastic Net也就是L1和L2一起上。它既享受L1的稀疏性又靠L2把相关特征的系数拉近工程上非常实用。如果模型要求可解释性比如风控评分卡、医疗辅助诊断那L1加逻辑回归或者线性模型是很好的基线。稀疏线性模型可以直接对业务解释“哪些因素最重要、影响方向是什么”比一堆黑盒模型更容易过合规评审。5.2 具体配置与参数调整配置正则化之前有一个前置步骤我几乎每次都强调先做特征标准化。原因藏在一个很容易被忽略的细节里——L2惩罚项中的平方项会让惩罚力度和特征尺度耦合。举个例子假设特征A的取值在0到1之间特征B的取值在0到10000之间。在同一个线性模型里为了产生相同幅度的预测变化B对应的权重只需要A的万分之一。L2对权重平方的惩罚换算到特征尺度上就是对B的惩罚相对A来说被放大了结果模型会更倾向于不使用B这不是因为B不预测而是因为数值尺度坑了它。L1同样存在这类问题只是表现形式略有不同。所以在做L1/L2正则化之前把特征标准化到相近尺度让正则化公平对待每个特征是最基本的准备工作。在代码层面不同框架写起来不一样。PyTorch里L2通常直接在优化器里配L1需要手动加到loss里import torch # L2正则通过weight_decay实现等价于L2正则化 optimizer torch.optim.SGD(model.parameters(), lr0.01, weight_decay1e-4) # L1正则需要在loss里手动加 l1_lambda 1e-5 l1_norm sum(p.abs().sum() for p in model.parameters()) loss ce_loss l1_lambda * l1_normKeras/TensorFlow则可以直接在层上指定正则器from tensorflow.keras import regularizers model.add(Dense(64, kernel_regularizerregularizers.l1(1e-5))) model.add(Dense(1, kernel_regularizerregularizers.l2(1e-4)))调λ的时候我习惯在log尺度上搜索比如按 1e-6、1e-5、1e-4、1e-3、1e-2 这个倍数网格扫。不是只看验证集精度还要同时观察正则化的直接效果L1要监控非零权重的数量变化L2要监控权重整体范数。这两类指标才是正则化真正作用的体现光看loss容易被带偏。5.3 踩坑记录几个容易翻车的点第一个坑是刚才提到的bias被顺带正则化。很多框架默认weight_decay是对所有参数生效的但理论上偏置项不应该被惩罚。实际操作中我不会手动去区分而是在效果不对时检查一下这个问题。如果确实需要精确控制可以按参数组分别设置optimizer torch.optim.SGD([ {params: model.weight, weight_decay: 1e-4}, {params: model.bias, weight_decay: 0} ], lr0.01)第二个坑是L1在Adam类优化器下的行为很怪。Loshchilov等人在2019年那篇AdamW论文里指出L2正则和经典的weight decay在Adam里并不等价因为Adam对每个参数的学习率做了自适应缩放L2正则项会被这个缩放干扰。表现就是正则效果不稳λ明明调大了权重衰减却不明显。解决办法是使用解耦的weight decay也就是AdamW在更新时直接按比例缩小权重而不是往梯度里加正则项。这个细节在工程上影响很大我见过好几个项目换了AdamW之后正则化表现就正常了。第三个坑是L1在深度学习模型里的“假稀疏”。前面说过深层网络权重即使有0也不会表现为特征被剔除因为每一层的0会被后面的矩阵变换传播开。我看到过有人在BERT后面的全连接层加L1结果只是训练速度变慢稀疏性根本没法利用。如果目的是模型压缩和稀疏化考虑结构化剪枝、蒸馏这类专门方法比单纯加L1有效得多。6. 常见问题与排查技巧实录6.1 问题排查速查表把积累的常见问题整理成一张表方便你直接对照排查。现象可能原因解决方案加了L1后所有权重全部变0λ设得过大惩罚超过拟合收益调小λ做log尺度搜索L1稀疏比例很高但精度明显下降λ过大欠拟合调小λ考虑L1L2的Elastic Net加L2后权重仍然很大λ太小或特征未标准化调大λ先标准化再训练加L2后精度不升反降λ过大模型被压得太简单调小λ用验证集监控使用Adam时L2权重衰减效果不稳Adam与L2正则不耦合切换到AdamW用解耦weight decay深度模型加L1没有稀疏效果深层网络权重稀疏不等于特征稀疏改用结构化剪枝或蒸馏L1在固定步数后损失不降学习率过大或阈值λ设置太大降低学习率检查近端更新阈值是ηλ两个强相关特征被L1随机丢弃L1在相关特征前不稳定改用Elastic Net增加L2分量6.2 关于软阈值算子的几个高频疑问软阈值算子作为L1正则化的核心实际工作中被问到的频率很高我把最常见的几个疑问集中答一遍。第一个疑问为什么阈值是ηλ而不是λ我前面推导时已经提过这里再说得更直白一点。近端梯度法考虑的是“在某个点附近做一步近似优化”的局部问题正则项在这个局部问题里的权重系数等于全局λ乘以学习率η。所以在实现ISTA或者近端SGD时软阈值的阈值参数一定是ηλ。如果你直接拿λ当阈值相当于无形中把正则化强度放大了1/η倍在深度学习这种学习率才1e-3的场景里那模型权重会瞬间全部被干掉。第二个疑问软阈值为什么不是直接把小于阈值的系数清零保留大于阈值的原值这个问题就是对硬阈值和软阈值区别的疑问。因为硬阈值对应的优化问题是非凸的求解困难且对噪声敏感。软阈值多做了一个“收缩”操作连续性好而且它是凸问题的精确解。实战中你会发现软阈值的解在留存的系数上做一个向0的收缩这样的系数在后继迭代中一般更稳不会在边界处反复跳动。第三个疑问软阈值操作应该在权重更新之前还是之后顺序必须是先按梯度更新再做软阈值。因为近端梯度法的公式就是这么推导出来的先走一步梯度方向把“拟合”这部分的改善做完再用软阈值去处理“稀疏化”那部分的要求。反过来操作就完全错了相当于先砍权重再学拟合目标函数就对接不上。第四个疑问L1正则化在特征完全共线的时候会怎么表现两个完全相同的特征L1出于稀疏化的惯性会随机把其中一个权重置0另一个保留全部权重。这在特征工程中是个隐患。解决方法也很简单要么做特征去重和相关分析要么用Elastic Net靠L2把两个相关特征的权重拉得相对均匀不至于出现“二选一”的随机性。6.3 一个完整的调试思路示例最后分享一个实际调试案例做个串烧。之前有个二分类模型特征维度大约5万跑L1后稀疏率只有10%远远没达到预期。我按顺序排查先看了特征是否标准化发现数据来自不同业务线有些特征量级差到千倍以上这是L1被干扰的直接原因。标准化后稀疏率从10%提到40%。随后发现λ选太小在log尺度上加了两个档位稀疏率到了65%验证集精度没有明显下滑。接着又发现Adam加L2的耦合问题切换成AdamW后训练曲线稳定了不少最终模型权重的非零率停在58%文件体积从180M降到约75M线上推理耗时下降了约三成。整个过程看起来是在调参实际上每一个步骤背后都是前面讲的那几个数学原理在工作。我个人在这些年踩过不少坑后最深的体会是L1和L2不是谁替代谁的关系而是两把用途不同的工具。理解它们的区别不能停留在背结论要能从几何、梯度、近端算子、贝叶斯这些不同角度都说得通。做到这一步你在模型里加L1或者L2时就不再是“别人都这么加所以我这么加”而是清楚地知道自己在引入什么样的先验、付出什么代价、期待什么收益。最后再补一个小建议如果你在一个新项目里拿不准选哪个先用L2打个底模型能正常收敛了再根据业务是否需要稀疏性谨慎引入L1或者Elastic Net这会省掉很多排查时间。
返回列表