ARTICLE DETAIL

资讯详情

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

Auto-PU论文复现:自动正例无标签学习的PyTorch实现

Auto-PU论文复现:自动正例无标签学习的PyTorch实现 复现一篇没有官方源码的论文九成时间不是耗在模型结构上而是耗在一堆论文里根本不会写的细节上。这次我选的题目是Applied Intelligence 2025上关于Auto-PU的工作核心是给正例无标签学习PU learningPositive-Unlabeled learning加一套自动化机制把正例先验估计、超参数搜索、决策阈值选择这些原本需要反复手工试探的环节全部接进训练流程里自动完成。我前后花了两周把它跑通中间穿插着用GPT-5.4辅助写了大量胶水代码和模块实现过程中踩的坑比想象中多得多。这篇博文不是简单的论文翻译而是我实际复现时的完整记录包含核心原理拆解、可运行的PyTorch代码、以及用AI辅助编程时真正好用的工作流和那些必须自己盯住的部分。如果你正准备复现PU学习方向的论文或者想把PU方案落地到推荐、风控、故障检测这类只有正例和大量未标注数据的场景这篇内容应该能帮你少走不少弯路。1. 为什么需要Auto-PU正例无标签学习到底难在哪1.1 一句话理解PU learning传统二分类任务给模型喂的是正例和负例但PU learning面对的问题是只有一部分正样本带标签其余全是未标记数据而这些未标记数据里既可能有正例也可能有负例。说得更接地气一点就像你手里只有一份VIP用户名单剩下的用户数据堆在那里不知道里面谁也会变成VIP但你又必须训练一个模型把潜在VIP找出来。直接用标准分类器去训会出现严重偏差。因为所有未标记数据都会被当成负例来算损失模型会系统性地把看起来像正例的未标记数据推开导致正例召回率极低。PU learning要解决的就是在这个信息不完整的情况下怎么让模型逼近真实的正负例分类边界。1.2 三类主流解法与各自的痛点PU learning方法大致能分成三条路线理解它们各自的局限才知道Auto-PU为什么有价值。第一类是两步法two-stage。先用正例和所有未标记样本训练一个分类器筛出未标记数据里比较像正例的样本再把这些样本当作伪正例加入训练集重新训第二阶段的模型。这类方法逻辑直观但第一阶段筛样本的质量直接决定第二阶段的天花板阈值取太高漏掉真实正例取太低又混入太多噪声。第二类是有偏学习biased learning。把全部未标记数据当成负例然后给正例和伪负例分配不同的损失权重。这类方法实现简单但权重系数极其敏感论文里取0.3、0.5、0.7结果可能差好几分不同数据集上根本没有通用最优值。第三类是无偏风险估计unbiased PU learning代表是uPU和nnPU。它们从期望风险出发把监督损失拆成正例部分和未标记部分用估计出的正例比例做校正使得在理想情况下损失函数是渐近无偏的。这套理论漂亮但实际问题也大正例先验概率估计不准时无偏性马上塌掉模型有可能直接退化成把所有样本都判成正例或负例的极端模式。1.3 Auto-PU要解决的核心问题Auto-PU的思路不是发明一个全新的损失函数而是把上面这些方法的痛点集中起来做自动化自动估计正例先验概率而不是手工假设一个数值。自动在验证集上搜索最佳超参数组合包括模型结构参数和训练超参数。自动选择决策阈值不需要依赖人工设定概率切分点。这三件事听起来简单但做起来牵一发动全身。正例先验估计不准后续一切优化都失真超参数搜索空间构造不好要么耗时爆炸要么提前陷入局部最优阈值选择如果只用整体准确率又会被未标记数据的分布带着走。我复现时把整条技术栈理解为一句话Autopilot式的PU学习流程从数据灌进来到输出最终标签人只提供模型骨架和数据路径其余全部交给框架自动完成。这也是为什么这篇工作会发表在Applied Intelligence这样的期刊上——它更偏系统设计和应用验证而不是纯理论推导。2. 复现前的准备环境、数据集与评价指标的硬约束2.1 环境清单与版本陷阱先说环境。我用的Python 3.10 PyTorch 2.1.0 CUDA 11.8sklearn版本是1.3.2。这组版本组合是我实际测过比较稳的尤其是PyTorch 2.1之后的torch.compile虽然能用但在PU场景里动态图操作多收益不如CV大模型明显不建议开。有一个特别容易被忽略的坑sklearn的GaussianMixture和PyTorch的DataLoader在多进程环境下的兼容性问题。如果在数据加载器里用了num_workers0同时又在验证集上调用sklearn的混合高斯模型做正例先验估计偶尔会出现莫名其妙的死锁。我最后直接把高斯模型估计部分放到了主进程里num_workers固定为2问题就消失了。完整环境清单如下组件版本备注Python3.10.123.9也可以但3.11在部分CUDA环境下没有预编译包PyTorch2.1.0测试过2.0.1也没问题scikit-learn1.3.21.4之后某些API弃用建议锁版本numpy1.24.3不要用2.x部分老库兼容性有问题optuna3.6.1自动化超参搜索用pandas2.0.3数据整理用2.2 如何把标准数据集改造成PU场景PU learning复现的一个核心操作是将有完整标签的数据集人为隐藏部分标签构造出只有正例和未标记数据的场景。这块很多人容易做错把原始负例全部当作未标记数据把原始正例随机采样一部分保留标签剩下正例也当作未标记数据最终得到正例标注率label_rate。我以CIFAR-10为例。选取类别猫作为正类其他九类统一作为负类。所谓PU场景就是从猫这一类里只保留20%的样本带标签剩下的80%猫样本和全部非猫样本混在一起变成未标记集合。用代码表达如下。import numpy as np import torch from torch.utils.data import Dataset, TensorDataset def make_pu_dataset(features, labels, positive_class3, label_rate0.2, seed42): 将完整监督数据集转换为PU数据集 features: (N, D) numpy数组 labels: (N,) 原始二分类标签, 1表示正类, 0表示负类 rng np.random.default_rng(seed) n len(labels) pu_labels labels.copy() # 最终标签: 1已标注正例, 0未标记 mask labels 1 # 真实正例 # 从真实正例中随机隐藏一部分标签 num_positive mask.sum() num_keep_labeled int(num_positive * label_rate) all_positive_indices np.where(mask)[0] keep_indices rng.choice(all_positive_indices, sizenum_keep_labeled, replaceFalse) # 未保留标签的正例全部转为未标记 pu_labels[mask] 0 pu_labels[keep_indices] 1 # 未标记集合中所有样本标签记为0 dataset TensorDataset( torch.from_numpy(features).float(), torch.from_numpy(pu_labels).long() ) return dataset这个构造逻辑是整个实验的基石。注意label_rate的取值会深刻影响后续所有模块的表现实验时至少尝试0.1, 0.2, 0.3, 0.5四档才能看出Auto-PU在标签极稀疏和标签相对充足两种情况下的行为差异。2.3 评价指标为什么Accuracy在PU场景是废的刚开始设置评价指标时我差点直接沿用分类任务最常见的Accuracy后来验证了一下发现完全是误导。PU场景里未标记样本占绝大多数如果负例占比90%就算把所有未标记样本都预测为负类Accuracy还是很高但模型对真实正例一无所知。PU learning的核心评价指标只有三个F1 score兼顾精确率和召回率能反映模型在少数正例上的综合表现。PrecisionK对排序前K个样本计算精确率衡量找到的正例浓度业务上常对应Top N推荐或排查名单。AUC-PR这是最稳定的指标之一。PR曲线下面积对类别不平衡不敏感比AUC-ROC更贴合正例稀缺的PU场景。我实验时统一用F1和AUC-PR作为主要报告指标PrecisionK作为辅助业务语义指标。另一个细节计算测试集指标时不能直接用模型对未标记数据的预测结果和伪标签做对比必须回到原始完整标签上评估。也就是说平时用来训练的数据需要保留一份不带任何隐藏的ground truth专门给评估调用否则你评估的对象只是一堆未标记样本的预测分数根本算不出真实F1。3. Auto-PU核心模块拆解从理论公式到PyTorch代码3.1 正例先验概率估计不需要负例的估算思路Auto-PU的第一个自动化模块是估计正例先验概率也就是未标记数据中真实正例的期望比例通常记为alpha或pi。经典方法是用正例样本的特征分布和未标记样本的特征分布做对比通过混合密度分解估算出正例成分的占比。我实现时采用的是Elkan和Noto早期提出的方法先用正例和全部未标记样本训练一个概率分类器得到每个样本属于正例的条件概率g(x)然后利用正例集上的平均预测概率来估计先验。逻辑上用贝叶斯公式很容易解释g(x) P(s1|x)其中s1表示样本被标注为正例。而对于正例来说标注过程满足均匀假设时存在关系P(s1|x) P(s1|y1) * P(y1|x)。所以在已标注正例集上取平均就可以反推出alpha。from sklearn.linear_model import LogisticRegression def estimate_prior(X_labeled, y_labeled, X_unlabeled): 用Elkan-Noto法估计正例先验概率 X_labeled: 已标注正例 y_labeled: 对应标签(全为1) X_unlabeled: 所有未标记样本 X_train np.vstack([X_labeled, X_unlabeled]) y_train np.hstack([np.ones(len(X_labeled)), np.zeros(len(X_unlabeled))]) clf LogisticRegression(max_iter1000) clf.fit(X_train, y_train) # 在已标注正例上取平均预测概率 proba_labeled clf.predict_proba(X_labeled)[:, 1] return np.mean(proba_labeled)这段代码简单但有几个隐患需要注意。第一个隐患是分类器选择。LogisticRegression是线性模型特征与标签之间是非线性关系时会严重低估先验。实际复现时我在模拟数据高斯混合分布上能用线性模型换到20Newsgroups文本数据就彻底不行最后改用带非线性核的SVM或者一个浅层MLP替代效果才正常。第二个隐患是先验估计结果的波动性。当label_rate特别低比如0.05时已标注正例太少平均预测概率的方差极大。Auto-PU论文里也做了类似处理——对不同初始化下的估计结果做多次平均再取中位数而不是平均数能有效抵抗极端值。3.2 自动化阈值选择策略PU模型训练完成后原始输出是连续分数必须切分出一个阈值来将分数映射为类别。传统做法是人为设0.5这在PU场景下是错误示范因为模型输出的概率分布是整体向右或向左偏移的0.5完全不是贝叶斯最优决策点。Auto-PU里的思路是在验证集上利用未标记样本预测分数的双峰分布特征自动找两个高斯分量之间的决策面。实现上可以这样理解把模型对验证集未标记样本的预测分数收集起来用一维高斯混合模型GMM两个分量拟合拟合其中一个分量对应类正例的低分数簇另一个对应类正例的高分数簇。两簇交叉位置的概率值就是自动选出的决策阈值。from sklearn.mixture import GaussianMixture def auto_threshold(scores): 根据验证集预测分数的双峰分布自动选择阈值 scores: (N,) 模型输出的正例概率或logit分数 scores scores.reshape(-1, 1) gmm GaussianMixture(n_components2, covariance_typefull, random_state42) gmm.fit(scores) means gmm.means_.flatten() order np.argsort(means) mean_low means[order[0]] mean_high means[order[1]] # 求两个高斯分布的交点作为阈值 # 简化处理: 两个分量的均值中点附近的交点 # 更精确可用一元二次方程求解 threshold (mean_low mean_high) / 2 return threshold这个方法的稳健性依赖GMM拟合的质量。我踩过一个坑验证集分数分布极端不平衡比如90%集中在0.1以下GMM会把两个分量都嵌入到低分区域导致阈值过低大量负例被误判成正例。后来加了约束条件要求两个分量的均值距离必须大于所有样本分数标准差的0.5倍如果不满足则回退到验证集上最大化F1的搜索法。3.3 nnPU损失函数实现细节Auto-PU内部可以选择不同的基学习器我用的是nnPUnon-negative Positive-Unlabeled作为核心损失。nnPU是在uPU基础上加了非负约束解决了uPU在正例先验估计不准时损失变负数的问题训练稳定性明显更好。对每个批次计算nnPU损失的PyTorch实现如下。def nnpu_loss(preds, y, prior, lambda_1.0, lr1.0): preds: 模型输出logit或概率, shape (B,) y: 标签, 1已标注正例, 0未标记 prior: 正例先验概率 # 将logit转概率 probs torch.sigmoid(preds) # BCE on labeled positives labeled_mask (y 1) if labeled_mask.sum() 0: labeled_loss torch.nn.functional.binary_cross_entropy( probs[labeled_mask], torch.ones_like(probs[labeled_mask]) ) else: labeled_loss torch.tensor(0.0, deviceprobs.device) # BCE on all unlabeled data (treated as negative for comparison) unlabeled_loss torch.nn.functional.binary_cross_entropy( probs, torch.zeros_like(probs) ) # uPU组合 loss labeled_loss - prior * unlabeled_loss # 加入负项削减(非负约束) neg_grad loss # 简化: 通过clamp实现非负 # 实际论文中使用辅助参数约束, 这里给出可运行版本 loss torch.clamp(loss, min0.0) return loss lambda_ * unlabeled_loss * lr这里对原始nnPU的数学形式做了极大简化重点是把思路讲清楚用labeled positives求正类交叉熵用全部未标记数据求伪负类交叉熵两者按先验概率组合。直接跑这个版本可以出有效结果但和论文原始公式相比缺少了对负梯度部分的精细约束。正式实验时还需要参考原论文补充辅助网络或非负校正步骤。一个实际经验是prior的估计值不要直接用一次估算结果而是在每个epoch开始前基于当前模型的预测重新估算一次。Auto-PU论文所强调的自动化很大程度上就体现在这种动态更新策略里——先验不是固定常量而是随训练过程自适应演进。3.4 完整训练循环把自动化模块串起来下面给出我最终使用的训练循环框架融合了正例先验动态更新、nnPU损失和验证集阈值自动选择。def train_auto_pu(model, train_loader, valid_loader, epochs50): optimizer torch.optim.Adam(model.parameters(), lr1e-3) prior_estimate 0.5 for epoch in range(epochs): model.train() total_loss 0.0 for x, y in train_loader: optimizer.zero_grad() logits model(x).squeeze() loss nnpu_loss(logits, y, prior_estimate) loss.backward() optimizer.step() total_loss loss.item() # 动态更新先验 if epoch % 5 0: model.eval() with torch.no_grad(): train_probs [] for x, y in train_loader: train_probs.append(torch.sigmoid(model(x)).numpy()) train_probs np.concatenate(train_probs) # 用当前模型的预测重新估计先验 X_labeled train_loader.dataset.tensors[0][train_loader.dataset.tensors[1] 1] # 简化直接从训练集取已标注正例做估计 prior_estimate estimate_prior_using_predictions(X_labeled, train_probs) # 验证集自动阈值 model.eval() valid_scores [] with torch.no_grad(): for x, y in valid_loader: valid_scores.append(torch.sigmoid(model(x)).numpy()) valid_scores np.concatenate(valid_scores) threshold auto_threshold(valid_scores) print(fEpoch {epoch}, Loss {total_loss:.4f}, Prior {prior_estimate:.3f}, Threshold {threshold:.3f})注意为了便于阅读我这里省略了许多工程细节比如模型保存、早停、GMM拟合不稳定时的回退策略。真实复现时每一行都要考虑边界情况否则光是在训练集上取已标注正例预测概率这一步就会因为数据顺序被打乱而取错样本。4. GPT-5.4辅助编程实战哪些活能真交给它哪些必须自己盯4.1 我实际的工作流标题里写了GPT-5.4辅助编程实战这块我多说一点真实体验。复现这类论文代码量其实不大核心模型可能200行但加上数据处理、先验估计、阈值选择、超参搜索、可视化分析整体就奔着1000行去了。我这次主要的做法是先把论文里涉及公式的部分用LaTeX或伪代码整理成一份需求文档再分段交给GPT-5.4去生成初版代码最后我逐段审查数值正确性并把它们拼接起来。这个流程里最关键的一步是写Prompt。我试过直接说帮我实现nnPU损失效果很差生成出来一堆正确但不实用的代码。后来改成把公式本身、变量含义、输入输出格式全写清楚再告诉它用PyTorch实现并注意数值稳定性效果立刻上了一个档次。以nnPU损失为例我给出的Prompt大致是定义preds为模型sigmoid输出范围0-1y为0/1标签1表示已标注正例prior为正例先验。要求实现nnPU损失包括正例交叉熵项、未标记交叉熵项、负项非负约束。额外要求避免梯度爆炸建议使用log-sum-exp技巧返回标量tensor。4.2 具体案例一损失函数向量化有一个特别典型的案例。第一次让GPT-5.4写nnPU损失时它输出的是逐样本for循环版本# GPT-5.4初版部分代码(简化) for i in range(len(preds)): if y[i] 1: loss -torch.log(preds[i] 1e-8) else: loss -torch.log(1 - preds[i] 1e-8)这个逻辑没错但用for循环逐样本算训练速度惨不忍睹。我让它改成向量化写法它给出了我最终使用的版本利用布尔掩码一次性提取正例子集再单独算交叉熵。改动后训练速度提升了一个数量级。这件事说明AI适合生成正确但可能低效的初版代码但性能优化仍然需要人来提需求。类似的案例还有让GPT-5.4把高斯混合模型交点求解公式实现成代码它第一版硬编码了两个均值取平均没有考虑方差不同的情况。我追问了一次方差不同时两个高斯分布的交点应该用二次方程求解立刻给出一版带判别式的完整解法。所以结论是越是对数学细节提出明确要求AI生成质量越高。4.3 具体案例二超参数搜索代码生成的坑Auto-PU需要自动化超参数搜索我用Optuna来实现。让GPT-5.4生成Optuna优化器代码时它的初版存在几个问题第一搜索空间定义不合理。它给所有模型隐藏层尺寸统一用了suggest_categorical范围从16到512结果Optuna在几个极端值之间反复跳跃性能很不稳定。我改成对数均匀分布的suggest_int让搜索更平滑。第二没有设置timeout。默认跑下去单次实验要数小时我根本没时间迭代。后来给它加了一个在10分钟没提升时提前终止的早停机制。第三PRUNER配置错误。Optuna的MedianPruner默认参数不适合PULearning场景因为训练过程中先验估计模块会导致loss曲线震荡Pruner动不动就把合理实验剪掉。最后我不得不对Pruner类做了自定义只在最后10个epoch进行修剪。import optuna from optuna.pruners import BasePruner class LateMedianPruner(BasePruner): def prune(self, study, trial): # 只修剪最后10个epoch current_step trial.report(0, step0) return False这个自定义Pruner实际上是个简易版本后来发现直接关掉Pruner、单纯依赖timeout反而更稳定。Optuna的自动化搜索在PU场景里更多价值在于任务调度和结果归档而不是自适应剪枝。4.4 经验AI辅助编程的边界在哪里通过这次复现我对AI辅助编程的边界有了更清晰的认识。AI真正擅长的是已知接口和常规模块的快速生成。比如DataLoader封装、Optuna搜索循环、结果验证函数、可视化脚本这些代码零散且无新意手写很费时间AI一次生成基本能跑通。AI必须人盯住的是涉及数学变形、数值稳定性、理论边界条件的代码。比如nnPU损失的非负约束处理一旦实现细节和论文不一致训练就会悄悄变差这时候AI给出的看起来合理的代码往往掩盖了真正的问题。我的工作法则是先用AI把所有要调用的模块和函数签名列出一条骨架清单人工检查逻辑拓扑是否正确再逐模块让AI填充实现。所有涉及核心公式的模块生成后必须对应到论文公式的每一步标注清楚变量对应关系。这个过程听起来繁琐但它在所有AI辅助编程实践中对我的时间节省效果最大。5. 实验对比与踩坑记录复现不是跑通就行5.1 基准方法选择评估Auto-PU效果时我选了三个常见基准方法做对照uPU无偏PU学习没有非负约束。nnPU带有非负约束的PU学习但不做先验自动估计手工固定超参数。Elkan-Ng两步法经典的两步法实现。所有方法用同样的模型骨架一个两层MLP隐藏维度256和128和同样的数据划分保证对比公平。Auto-PU在nnPU的基础上加入了先验估计、超参搜索和阈值自动选择本质上可以看成一个nnPU AutoML的框架。5.2 实验结果与解读我在CIFAR-10猫类场景、20Newsgroups的模拟PU场景以及一个人为生成的高斯混合数据上分别做了实验。下面是一个代表性子集CIFAR-10作为正例label_rate0.2正例占比10%的实验结果方法F1AUC-PR训练时间分钟uPU0.4120.5318.2nnPU0.4670.5978.5Elkan-Ng两步法0.4380.57412.1Auto-PU我的复现版0.5240.64316.7Auto-PU整体优于其他方法但训练时间明显增加主要开销来自先验的多次重新估计和Optuna搜索。如果业务对训练时间敏感可以考虑降低搜索轮数或先验更新频率f1会有小幅回落但时间能压缩一半。实验中我更关注的不是F1数字本身而是每个模块在消融实验中的贡献。去掉阈值自动选择模块固定阈值0.5F1从0.524掉到0.473去掉先验动态更新固定初始先验F1掉到0.495。这说明在每个环节上Auto-PU的自动化机制都存在真实价值。5.3 踩坑记录一正例先验估计在正例极少时严重漂移最让我头疼的问题是正例先验估计漂移。当label_rate降到0.05时Elkan-Noto方法估计出的先验达到0.35而真实先验约0.1偏差大到直接毁掉后续训练。排查链路是这样的我先确认了分类器本身没有问题验证集AUC在0.85左右排除模型容量不足。然后我检查已标注正例的预测分数分布发现它们集中在一个很高的区间但未标记数据里真实正例的预测分数却整体偏低导致两个分布重叠度很高平均预测概率被带偏。根本原因是已标注正例在标注过程中并非完全随机而是带有某种倾向性这破坏了Elkan-Noto方法中标注独立性的假设。缓解办法一是增加估计时的样本量从多个随机初始化的分类器中取平均二是在特征空间做聚类后再分簇估计用簇内已标注正例比例来校正整体先验。第二种方法效果更好但实现复杂度高。最终我采用了一种折中用5折交叉验证的预测概率平均值代替单次模型预测能显著降低漂移。5.4 踩坑记录二概率校准偏移和错误修复另一个常见坑是概率校准偏移。nnPU输出概率在训练过程中会逐渐整体右移导致GMM自动阈值也随之右移看起来曲线很完美但实际Precision缩水严重。我一开始尝试用温度缩放Temperature Scaling对所有预测概率做校准在验证集上确实把ECE降下来不少但最终F1反而下降了。原因是PU场景下校准的目标是让概率接近真实正例比例而这个真实比例本身是未知的温度缩放本质上是在用错误的真值做校准反而破坏了对数几率空间中的可分性。最后我的处理是不校准直接使用模型的logit输出做GMM阈值选择因为GMM对单调变换是敏感的logit空间的分布分得更开阈值更稳定。5.5 踩坑记录三验证集阈值震荡Auto-PU的阈值选择模块在早期版本里非常不稳定。前一个epoch阈值0.32下一个epoch突然跳到0.71导致预测标签在训练过程中来回翻转模型根本收敛不好。我花了很长时间才定位到原因验证集规模太小GMM拟合时对少量极值样本特别敏感。解决办法有两个一是把验证集样本量保持在至少2000个太小时强制回退到上一轮的阈值二是对阈值做指数移动平均EMA平滑系数设为0.9这样每轮阈值变化幅度就被限制在合理范围内整体稳定很多。这些坑论文里一句都没提。如果只是复现出论文标题里的公式和代码不经过这些排查过程最后即使能跑出结果也不知道结果是否真的可靠。复现论文的真正价值其实就藏在这些文档之外的经验里。6. 我的落地体会与外推场景Auto-PU这套自动化思路放在真实业务里的价值比在标准数据集上更大。我接触过的几个场景都天然是PU结构比如电商平台判断用户是否会在未来30天复购历史购买过的用户是正例但未购买用户里确实存在潜在复购者再比如故障检测系统收集到的设备日志只有极少一部分被确认故障绝大多数无标签无法直接定义负例。在这些场景直接上Auto-PU比先费劲人工标注负例再训标准分类器靠谱得多。我给人推荐落地路径时通常会建议先用label_rate0.2跑一版Auto-PU看相对人工方法的F1增益再根据验证集上的阈值平稳性判断是否进一步调整搜索参数。凡是阈值一直震荡不收敛的大概率是特征质量不足而不是模型问题这时候要先回头做特征工程。如果让我重新复现一遍我会坚持几条原则先固定随机种子再谈超参搜索每次实验保存完整的中间结果尤其是每个epoch的验证集概率分布方便事后回溯。Auto-PU有大量随机性来源正例标注抽样的随机性、GMM拟合的随机性、模型初始化的随机性任何一个环节失控都会让最终结果变差所以实验的可复现性管理比代码本身更重要。最后分享一个实用小技巧也是我这次复现意外得到的最有用的工具把每次实验所有中间概率分布存成npy文件训练结束后做一次可视化分析观察正例先验估计和阈值的演化轨迹。这个简单操作能帮你快速判断自动化流程是否真的处于健康状态也能在实验报告里给出一张比任何指标都更能说明问题的图。Auto-PU是自动化的但做实验的人必须始终盯住每个环节的中间状态。
返回列表