【深度学习|学习笔记】深度学习里有没有必要用 L1 去“逼稀疏”?何时该用、何时不该用、怎么用才对?(二)

【深度学习|学习笔记】深度学习里有没有必要用 L1 去“逼稀疏”?何时该用、何时不该用、怎么用才对?(二)



欢迎铁子们点赞、关注、收藏!
祝大家逢考必过!逢投必中!上岸上岸上岸!upupup

大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文。详细信息可扫描博文下方二维码 “学术会议小灵通”或参考学术信息专栏:https://blog.csdn.net/2401_89898861/article/details/148877490


前言

  • 下面把问题拆开讲清楚:深度学习里有没有必要用 L1 去“逼稀疏”?何时该用、何时不该用、怎么用才对,以及配上能直接跑的 Python(PyTorch)示例。

3. 代码:如何“正确”地用 L1

3.4 结构化稀疏:对 BN 的 γ 做 L1(Network Slimming)

  • 对每个通道的缩放系数 γ加 L1,训练后按 |γ| 小的通道剪掉:
def bn_gamma_l1(model):
    reg = 0.0
    for m in model.modules():
        if isinstance(m, nn.BatchNorm2d):
            reg = reg + m.weight.abs().sum()   # BN 的 weight 就是 γ
    return reg

# 训练时:
# loss = task_loss + lambda_gamma * bn_gamma_l1(model)

# 训练完:根据 |gamma| 排序,阈值化 → 物理删除对应通道(需要模型重构)

  • 这是结构化的通道稀疏,可带来真正提速(特别是在 CNN 上)。

3.5 表格数据上的 L1 vs L2(小例子)

import torch, torch.nn as nn, torch.optim as optim
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
import numpy as np

# 造一个稀疏真相:只有前 10 个特征有效,其它全噪声
X, y = make_regression(n_samples=20000, n_features=200, n_informative=10, noise=5.0, random_state=0)
X = torch.from_numpy(X).float()
y = torch.from_numpy(y).float().unsqueeze(1)
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, random_state=0)

model = nn.Sequential(nn.Linear(X.shape[1], 1, bias=True))
opt = optim.AdamW(model.parameters(), lr=1e-3, weight_decay=1e-2)  # L2 (wd)
lam_l1 = 1e-5  # 逐步调大看到系数变 0 的过程

for epoch in range(50):
    model.train()
    opt.zero_grad()
    pred = model(Xtr)
    loss = ((pred - ytr)**2).mean()
    # L1:只对权重,不对偏置
    w = model[0].weight
    loss = loss + lam_l1 * w.abs().sum()
    loss.backward()
    opt.step()

with torch.no_grad():
    w = model[0].weight.squeeze()
    k0 = (w.abs() < 1e-6).sum().item()
    print("L1 zeros:", k0, "/", w.numel())

调 lam_l1 可看到多少权重被“推到 0”。同样的数据上,单纯 L2 很少产生精确 0。

4. 什么时候不建议用 L1(或需谨慎)

  • 只求精度且模型大:L1 带来的偏差可能会拉低上限;优先 L2 与数据策略。
  • GPU 提速目标但做的是非结构化稀疏:算子不友好,速度几乎不变。
  • 强相关特征:L1 会随机“挑一丢一”,不稳定;用 Elastic Net 更稳(α·L1 + (1-α)·L2)。
  • AdamW + L1:建议用上面的近端 L1(软阈值)而非把 L1 加到 loss。

5. 替代与互补:更实用的“稀疏化”路线

  • (1)先训一个密集模型(好好调参) →
  • (2)剪枝(大小阈值/Movement Pruning/One-shot/逐步剪)→
  • (3)微调恢复性能 →
  • (4)蒸馏 + 量化。

想要提速:用结构化剪枝(通道/层/块)或 N:M 稀疏(硬件支持时)。
想要解释:L1/Elastic Net + SHAP/LIME 双管齐下。

6. 如果把权重全初始化为 0会怎样?

  • 多层网络中,所有神经元梯度会完全对称,更新永远一样 → 无法打破对称性,网络学不会。
  • 正确做法:用 Xavier/He 初始化 打破对称,让不同通道走不同更新路径;是否再用 L1 与任务目标有关。

7. 快速决策表

目标 建议
只要泛化精度 L2/AdamW + 数据增强 + LR 策略(不必 L1)
特征选择/解释 L1 / Elastic Net;或训练好后做基于特征的重要性筛选
压缩模型体积 训练加 L1 获得稀疏 → 剪枝 → 微调;或直接后剪枝
提速上硬件 结构化稀疏(BN-γ L1 / Group Lasso / 通道剪枝)
稀疏激活表示 激活加 L1 / KL 稀疏约束(稀疏自编码器)
  • 一句话:L1 是“为了稀疏而生”的工具——不是每次都要用,但当你的目标是特征选择、压缩与可解释时,它非常有价值。若追求实际速度和部署,请把 L1 的“稀疏趋势”落地为结构化剪枝并配合微调。
Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐