ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Cleanlab 内部标签质量工具:`label_quality_utils` 模块源码级解析

Cleanlab 内部标签质量工具:`label_quality_utils` 模块源码级解析 Cleanlab 内部标签质量工具label_quality_utils模块源码级解析【免费下载链接】cleanlabCleanlabs open-source library is the standard>项目地址: https://gitcode.com/GitHub_Trending/cl/cleanlab导读label_quality_utils是 Cleanlab 中用于内部计算标签质量分数label quality scores的辅助模块是 confident learning 流水线的关键一环。本篇文章将以 docs/source/cleanlab/internal/label_quality_utils.rst 所指向的模块为骨架逐行拆解其两个核心函数——_subtract_confident_thresholds置信阈值减法与get_normalized_entropy归一化熵——的数学原理、代码实现并结合仓库源码展示它们在rank、outlier、多标签评分等模块中的真实调用场景。读完本文你将能从源码层面理解 Cleanlab 是如何度量预测不确定性与标签质量以及如何在实践中复现与验证这些内部工具。一、模块定位隐藏在评分函数背后的底层工具箱在 Cleanlab 的开源仓库中cleanlab/internal/label_quality_utils.py是一个内部internal模块模块 docstring 只有一句话Helper methods used internally for computing label quality scores.它的定位非常明确仅为内部计算标签质量分数提供辅助方法属于 Cleanlab 数据质量分析体系中最底层的基础设施之一。与之对应的 Sphinx 文档 docs/source/cleanlab/internal/label_quality_utils.rst 通过automodule指令自动生成 API 文档.. automodule:: cleanlab.internal.label_quality_utils :autosummary: :members: :undoc-members: :show-inheritance:这意味着该.rst文件本身并不包含实现代码而是把 cleanlab/internal/label_quality_utils.py 中的公开成员:members:、未文档化成员:undoc-members:以及继承关系:show-inheritance:全部拉取进文档页面。因此理解这个文档文件的关键在于理解它背后的源码模块。该模块仅导出两个函数函数可见性作用_subtract_confident_thresholds(labels, pred_probs, multi_label, confident_thresholds)内部以下划线开头减去类别置信阈值并重新归一化预测概率用于处理类别不平衡get_normalized_entropy(pred_probs, min_allowed_prob)公开计算预测概率的归一化熵0~1度量模型预测的不确定性这两个函数虽然体量不大却是 Cleanlab 众多公开 API如 cleanlab/rank.py 中的get_label_quality_scores、cleanlab/outlier.py 中的 OOD 评分内部实现的基础。二、_subtract_confident_thresholds用类别平均自信度校正类别不平衡2.1 函数签名与输入输出def _subtract_confident_thresholds( labels: Optional[np.ndarray], pred_probs: np.ndarray, multi_label: bool False, confident_thresholds: Optional[np.ndarray] None, ) - np.ndarray:核心参数说明labels与cleanlab.count.get_confident_thresholds()期望相同格式的标签数组。如果为None则必须传入confident_thresholds否则函数无法自行计算阈值pred_probs形状为(N, K)的预测概率矩阵N 为样本数K 为类别数每行表示模型预测某个样本属于各类别的概率P(labelk|x)confident_thresholds形状为(K,)的预计算置信阈值。若传入则跳过计算直接使用否则用labels和pred_probs现场计算multi_label布尔值默认False。当为True时labels应为可迭代的迭代器如 list of lists每个样本可拥有一个或多个标签例如[[0,1], [1], [0,2], [0,1,2], [0], [1], ...]。函数返回pred_probs_adj即调整后的预测概率矩阵。2.2 数学原理什么是置信阈值代码 docstring 给出了定义The confident class threshold for a class j is the expected (average) self-confidence for class j.即类别 j 的置信阈值 所有被标注为类别 j 的样本其模型预测概率中类别 j 那一维的平均值。if confident_thresholds is None: if labels is None: raise ValueError( Cannot calculate confident_thresholds without labels. Pass in either labels or already calculated confident_thresholds parameter. ) confident_thresholds get_confident_thresholds(labels, pred_probs, multi_labelmulti_label)这里直接复用了 cleanlab/count.py 中的get_confident_thresholds。从count.py的源码可以看到单标签情况下的精确计算方式confident_thresholds [ np.mean(pred_probs[:, k][labels k]) if k in unique_classes else BIG_VALUE for k in all_classes ] confident_thresholds np.clip( confident_thresholds, a_minCONFIDENT_THRESHOLDS_LOWER_BOUND, a_maxNone )值得注意的两个细节缺失类别用BIG_VALUE 2兜底如果某个类别没有出现在训练标签中k not in unique_classes则其阈值为 2。由于概率最大值不超过 1任何样本都不可能超过这个阈值从而保证缺失类别的样本永远不会被计入下限裁剪CONFIDENT_THRESHOLDS_LOWER_BOUND来自 cleanlab/internal/constants.py对阈值做了下限保护避免极端小概率下计算出病态的阈值。对于多标签场景count.py中的_get_confident_thresholds_multilabel采用one-vs-rest方式为每个类别返回形状为(K, 2)的二元阈值。2.3 减法与重归一化算法的三步走拿到阈值后函数执行减 → 平移 → 归一化三步# Subtract the class confident thresholds pred_probs_adj pred_probs - confident_thresholds # Re-normalize by shifting data to take care of negative values from the subtraction pred_probs_adj confident_thresholds.max() pred_probs_adj / pred_probs_adj.sum(axis1, keepdimsTrue) return pred_probs_adj减法pred_probs_adj pred_probs - confident_thresholds。对每个样本、每个类别都减去该类别的平均自信度。这样某类别概率高于该类别平均水平的样本会得到正的调整值相对更突出低于平均水平的则得到负值平移pred_probs_adj confident_thresholds.max()。由于减法会引入负值直接归一化会出问题因此先整体平移confident_thresholds.max()把数据全部抬到非负区间重归一化pred_probs_adj / pred_probs_adj.sum(axis1, keepdimsTrue)。按行求和做除法保证调整后的每行概率之和仍为 1保持概率分布语义。这样处理的核心动机在 docstring 中写明The purpose of this adjustment is to handle class imbalance处理类别不平衡。在类别分布严重倾斜的数据集中稀有类别的绝对概率天然偏低直接比较不同类别的概率会产生系统性偏差减去各类别自身的平均自信度后相当于把每个类别放到相对自己平均水平的尺子上衡量。2.4 测试用例佐证tests/test_rank.py 中的test__subtract_confident_thresholds验证了该函数的两条关键不变量pred_probs_adj _subtract_confident_thresholds(labels, pred_probs) assert (pred_probs_adj 0).all() # all pred_prob are positive numbers assert ( abs(1 - pred_probs_adj.sum(axis1)) 1e-6 ).all() # all pred_prob sum to 1 with some small precision error即调整后的概率全部为正、每行之和为 1允许1e-6量级的浮点误差。这从测试层面印证了平移 重归一化的设计意图。2.5 在仓库中的真实调用链从源码搜索可以确认_subtract_confident_thresholds被三个模块引用cleanlab/rank.py——_compute_label_quality_scores中当adjust_pred_probsTrue时调用if adjust_pred_probs: if method confidence_weighted_entropy: raise ValueError(fadjust_pred_probs is not currently supported for {method}.) pred_probs _subtract_confident_thresholds( labelslabels, pred_probspred_probs, confident_thresholdsconfident_thresholds )这是get_label_quality_scores(..., adjust_pred_probsTrue)的内部实现路径。注意confidence_weighted_entropy方法不支持该调整会直接抛出ValueError这一点在使用时需留意。cleanlab/outlier.py—— 计算 OODout-of-distribution评分时若adjust_pred_probsTrue则先计算get_confident_thresholds再传入_subtract_confident_thresholds(None, pred_probs, multi_labelFalse, confident_thresholds...)。这里演示了预计算阈值传入的用法——当调用方已持有阈值时可以传入labelsNone避免重复计算。cleanlab/internal/multilabel_scorer.py—— 多标签评分器ClassLabelScorer._adjust_pred_probs中对SELF_CONFIDENCE和NORMALIZED_MARGIN两种方法支持阈值调整if kwargs.get(adjust_pred_probs, False) is True: if self ClassLabelScorer.CONFIDENCE_WEIGHTED_ENTROPY: raise ValueError(fadjust_pred_probs is not currently supported for {self}.) pred_probs _subtract_confident_thresholds(labels, pred_probs)从这些调用点可以看出减去类别置信阈值是 Cleanlab 在 rank标签质量排序与 outlier分布外检测两大场景中共用的校准手段是模块复用的典型范例。三、get_normalized_entropy归一化熵与不确定性度量3.1 函数签名与返回值def get_normalized_entropy( pred_probs: np.ndarray, min_allowed_prob: Optional[float] None ) - np.ndarray:pred_probs形状(N, K)的预测概率矩阵每行是模型预测某样本属于各类别的概率P(labelk|x)min_allowed_prob已被弃用deprecated since 2.5.0的旧参数默认None。若传入非None值会把pred_probs中低于该值的条目裁剪clip到该值并触发DeprecationWarning返回形状(N,)的数组每个元素是对应样本预测概率的归一化熵。3.2 数学公式熵为什么能归一化到 0~1标准Shannon熵定义为H(p) -Σ_k p_k · log(p_k)而 Cleanlab 的实现使用了 SciPy 的xlogy即x * log(y)且约定0 * log(0) 0避免对零概率取对数产生 NaNreturn -np.sum(xlogy(pred_probs, pred_probs), axis1) / np.log(num_classes)除以log(num_classes)等价于把自然对数换成以num_classes为底的对数从而把熵缩放到 0 到 1 之间当预测完全确定one-hot 分布时熵为 0当预测在 K 个类别上完全均匀分布时熵为 1因为-Σ (1/K)·log(1/K) log(K)。代码注释也明确了这一意图# Note that dividing by log(num_classes) changes the base of the log which rescales entropy to 0-1 range与标签质量分数的关键区别docstring 原话Unlike label-quality scores, entropy only depends on the models predictions, not the given label. 即熵只依赖模型预测不依赖给定标签。这让熵成为纯粹的模型不确定性度量而不含标签是否正确的信息——正因如此它特别适合作为 OOD分布外检测与主动学习不确定性采样的基础。3.3 输入校验与弃用参数函数首先校验输入概率的合法性if np.any(pred_probs 0) or np.any(pred_probs 1): raise ValueError(All probabilities are required to be in the interval [0, 1].)任何概率超出[0, 1]区间都会抛出ValueError。对于min_allowed_prob参数2.5.0 版本起标记为弃用并发出警告if min_allowed_prob is not None: warnings.warn( Using min_allowed_prob is not necessary anymore and will be removed., DeprecationWarning, ) pred_probs np.clip(pred_probs, a_minmin_allowed_prob, a_maxNone)弃用理由是即使pred_probs包含 0熵函数本身也表现良好xlogy处理了0·log(0)的情形裁剪反而会轻微改变计算结果。新代码应直接省略该参数。3.4 测试用例佐证tests/test_util.py 中的test_normalized_entropy从三个维度验证了函数的正确性极小数值稳定性对np.float16 / float32 / float64三种 dtype分别测试eps、最小正规数smallest normal、最小次正规数smallest subnormal以及 0 值断言熵始终落在[0, 1]区间内——这验证了xlogy对退化输入的稳健处理基本区间性质对[[0.0, 1.0], [0.5, 0.5]]计算断言所有熵值在[0, 1]非法输入报错对包含负数[[-1.0, 0.5]]和大于 1 的值[[2.0, 0.5]]的输入断言抛出ValueError。3.5 在仓库中的真实调用场景get_normalized_entropy同样是复用率极高的内部工具cleanlab/rank.py——get_confidence_weighted_entropy_for_each_label中confidence weighted entropy置信加权熵定义为归一化熵除以 self-confidenceself_confidence get_self_confidence_for_each_label(labels, pred_probs) self_confidence np.clip(self_confidence, a_minCLIPPING_LOWER_BOUND, a_maxNone) label_quality_scores get_normalized_entropy(pred_probs) / self_confidence clipped_scores np.clip(label_quality_scores, a_minCLIPPING_LOWER_BOUND, a_maxNone) label_quality_scores np.log(label_quality_scores 1) / clipped_scores这是get_label_quality_scores(methodconfidence_weighted_entropy)的底层实现高熵模型不确定且低自信标签概率低的样本会得到较低的分数即更可能是标签错误。其中CLIPPING_LOWER_BOUND来自 cleanlab/internal/constants.py。cleanlab/outlier.py—— OOD 评分方法entropy中将归一化熵取反得到分布内in-distribution置信度# Scores are flipped so ood scores are closer to 0. Scores reflect confidence example is in-distribution. if method entropy: ood_predictions_scores 1.0 - get_normalized_entropy(pred_probs)分数越接近 1 表示样本越像分布内数据越接近 0 表示越可能是 OOD 样本。主动学习/不确定性采样docstring 中提到归一化熵常用于主动学习的 uncertainty sampling不确定性采样。由于熵与标签无关它天然适合在无标签或待标注场景下挑选模型最拿不准的样本。四、从源码结构推断的设计准则结合 cleanlab/internal/label_quality_utils.py 及其调用方可以总结出该模块体现的三条设计准则内部模块与公开 API 分层清晰以单下划线开头的_subtract_confident_thresholds明确标识内部使用不承诺对外 API 稳定性而get_normalized_entropy作为公开函数具备完整的 docstring、参数校验与弃用策略。文档中:undoc-members:指令也保证了内部成员在文档中可见但不宣示为稳定接口。计算可缓存、可注入_subtract_confident_thresholds支持传入预计算的confident_thresholds允许调用方如 cleanlab/outlier.py在多次调用间复用阈值避免重复计算get_confident_thresholds。这一设计在批量场景下能显著减少开销。数值稳健性优先xlogy处理零概率、平移-重归一化处理负值、测试覆盖 float16/32/64 与次正规数——处处体现在真实、杂乱数据上不崩溃的工程目标这与 Cleanlab data-centric AI、messy real-world data 的项目定位一脉相承。五、实践要点速查关注点结论何时使用_subtract_confident_thresholds需要通过get_label_quality_scores(adjust_pred_probsTrue)或outlier模块的adjust_pred_probs校正类别不平衡时何时不该用它confidence_weighted_entropy评分方法不支持该调整会抛出ValueErrorlabels与confident_thresholds二选一二者必须至少提供一个预计算阈值可加速多次调用归一化熵的取值含义0 预测完全确定1 完全均匀最大不确定归一化熵与标签质量分数的区别熵只依赖pred_probs与给定标签无关min_allowed_prob已弃用2.5.0 起新代码不要使用非法输入概率超出[0, 1]会抛ValueError如果你想深入这些工具的实际效果可以直接运行仓库测试验证不变量tests/test_rank.py中的test__subtract_confident_thresholds与tests/test_util.py中的test_normalized_entropy都是无需外部数据的单元测试是理解这两个函数行为最直接的可执行文档。【免费下载链接】cleanlabCleanlabs open-source library is the standard>项目地址: https://gitcode.com/GitHub_Trending/cl/cleanlab创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表