一张图里背景很多、裂纹很少普通分类损失容易花大量更新去处理已经分对的背景。Focal Loss 的用途是改变训练时各样本的贡献部署后推理通常只执行前向网络并不逐点计算这个损失。把它描述成 NPU 上线以后必跑的“定点加速算子”会把训练和部署混在一起。原始依据是 2017 年的 Focal Loss 论文。它不是 2026 年的新方法。近期 RKNN Toolkit2 v2.5.0列出了 QAT 等能力实际使用仍要核对目标平台、转换算子和量化流程不能由此推断设备支持在线反向传播。调制因子会改变梯度不只是乘一个权重二分类标签取y∈{0,1}psigmoid(z)。令正样本的ptp负样本的pt1-p损失为L-αt(1-pt)^γ ln(pt)。当 γ 为 0它退化为带类别权重的交叉熵。对 logit 求导时(1-pt)^γ本身也随 z 变化。只写αt(1-pt)^γ(p-y)会漏掉一项。先用浮点参考和数值微分核对解析式再决定是否值得做定点近似比先写 LUT 更容易定位错误。import math def focal(z, y, gamma2.0, alpha0.25): p 1.0 / (1.0 math.exp(-z)) pt, a (p, alpha) if y 1 else (1.0 - p, 1.0-alpha) return -a * (1.0-pt)**gamma * math.log(pt) def gradient(z, y, gamma2.0, alpha0.25): p 1.0 / (1.0 math.exp(-z)) pt, a (p, alpha) if y 1 else (1.0-p, 1.0-alpha) dpt p*(1.0-p) * (1 if y 1 else -1) dL a*(gamma*(1.0-pt)**(gamma-1)*math.log(pt) - (1.0-pt)**gamma/pt) return dL*dpt worst 0.0 for y in (0, 1): for z in (-6.0, -2.0, 0.0, 2.0, 6.0): h 1e-5 numeric (focal(zh, y)-focal(z-h, y))/(2*h) worst max(worst, abs(numeric-gradient(z, y))) assert worst 1e-8 assert abs(focal(0, 1, gamma0)-0.25*math.log(2)) 1e-12 print(gradient finite-difference max error: %.3g % worst)例子只覆盖中等范围的 logit。生产训练应使用稳定的 logits 形式避免极端概率导致log(0)混合精度、梯度缩放和 reduction 规则也要纳入测试。这里没有训练任何检测器。先判断是样本失衡还是缺陷根本没有被看见如果原图上的裂纹只有两三个像素失焦、曝光和缩放就可能改变标签含义。增加高分辨率特征层可能保留空间信息也会增加显存和计算量它不能恢复采集时已经丢失的光学细节。训练集还容易出现相邻帧泄漏。按图随机切分可能让同一零件的几乎相同图像同时进入训练和验证。应按工件、批次或产线时间切分并单独保留新材质、新光照的验证样本。验收时分别报告缺陷召回、误剔除率和复核成本。mAP 需要明确 IoU、类别和置信阈值不能把一个固定阈值下的召回率叫 mAP。损失下降只说明优化目标变化不能自动解释漏检减少。只有在浮点参考、数据划分和检测指标都稳定之后定点损失才值得讨论。本文验证的是导数尚未验证训练收敛、量化感知训练、转换兼容性或板端性能。