MLE Ads · Coding Screen

Apple MLE 逻辑回归损失:从 Logit 到稳定 BCE

推导二分类负对数似然,并用 softplus 分段计算避免大 logit 的溢出和消差。

题目重点:推导二分类负对数似然,并用 softplus 分段计算避免大 logit 的溢出和消差。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 本文取二分类标签 y∈{0,1},输入为模型原始 logit z=w·x+b,返回 n 个样本的平均负对数似然;题目只说 loss,需现场确认 reduction 与 regularization。
  • 不在本文损失中额外加入 L1/L2 或样本权重;输入须有限且非空。

解题路线

  1. sigmoid 概率 p=1/(1+exp(−z));单样本交叉熵为 −y log p−(1−y)log(1−p)。
  2. 代数整理得 `softplus(z)−yz`,其中 softplus(z)=log(1+exp(z)),直接计算 exp(z) 在大正数时会溢出。
  3. 若 z≥0,稳定写作 `log1p(exp(−z))+(1−y)z`;若 z<0,写作 `log1p(exp(z))−yz`。两支指数的自变量都≤0,且避免大数相减。
  4. 累加各样本再除以 n;对中等 logit 与直接概率公式 202 组独立核对,±1000 极端 logit 另测数值稳定。

手动走一遍

z=0 时 p=1/2,不论 y=0 或 1,loss=ln2。z=1000 且 y=1 时正确损失接近 0;y=0 时损失接近 1000。直接算 `exp(1000)` 会溢出,本分段公式不会。

Python 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

from math import exp, isfinite, log1p


def mean_logistic_loss(logits: list[float], labels: list[int]) -> float:
    """Numerically stable binary cross-entropy from raw logits."""
    if not logits or len(logits) != len(labels):
        raise ValueError("non-empty, equal-length logits and labels required")
    total = 0.0
    for z, y in zip(logits, labels):
        if y not in (0, 1) or not isfinite(z):
            raise ValueError("binary labels and finite logits required")
        if z >= 0:
            total += log1p(exp(-z)) + (1 - y) * z
        else:
            total += log1p(exp(z)) - y * z
    return total / len(logits)

复杂度

给定 n 个 logit 的损失 O(n) 时间、O(1) 额外空间;若从稀疏特征算 z,还需各样本非零特征数的点积成本。

易错点与追问

容易失分的边界

  • 把 logit 当概率直接取 log。
  • 用 `log(sigmoid(z))` 导致 z 很负时下溢到 log(0)。
  • 直接计算 `log(1+exp(z))`,z 很大时溢出。
  • 未声明 mean/sum、标签是 0/1 还是 ±1、是否加正则化。
  • 把训练损失低等同于线上广告排序指标好,不做离线/线上评估。

继续深挖

  • 从 loss 推出对 z 的梯度为何是 sigmoid(z)−y?
  • 类别不平衡时样本权重怎样进入公式?
  • L2 正则化放在平均损失前还是后,λ 的含义如何变化?
  • 多分类 softmax cross-entropy 如何用 log-sum-exp 稳定计算?
✓已复制微信号!