pytorch-metric-learning Miners 完整指南:在线样本挖掘的原理、配置与自定义实现
人工智能机器学习深度学习计算机视觉【免费下载链接】pytorch-metric-learningThe easiest way to use deep metric learning in your application. Modular, flexible, and extensible. Written in PyTorch.项目地址https://gitcode.com/gh_mirrors/py/pytorch-metric-learning点击查看免费下载在度量学习metric learning中训练效果的好坏很大程度上取决于喂给损失函数哪些样本是从整个 batch 中随机挑选还是刻意挑选那些难hard的、能推动模型学习的样本pytorch-metric-learning用Miners样本挖掘器来回答这个问题。本文以仓库文档 docs/miners.md 为主体结合 src/pytorch_metric_learning/miners 下的全部源码实现系统讲解 miner 的输入输出约定、BaseMiner基类设计、仓库内置的 10 种 minerAngularMiner、BatchEasyHardMiner、BatchHardMiner、DistanceWeightedMiner、EmbeddingsAlreadyPackagedAsTriplets、HDCMiner、MultiSimilarityMiner、PairMarginMiner、TripletMarginMiner、UniformHistogramMiner的参数含义、默认距离、适用场景以及如何编写自定义 miner。读完本文你将能够根据业务数据特性挑选最合适的挖掘策略并把 miner 无缝接入 loss 与训练流程。一、什么是 Miner在线挖掘 vs 离线挖掘Mining 函数接收一个包含n个 embedding 的 batch返回k个用于计算损失的 pair 或 triplet 索引。它回答的是这一个 batch 里哪些样本对/三元组最值得让模型学习。在pytorch-metric-learning中Miner 按输出格式分为两类Pair miner输出一个大小为 4 的元组(anchors, positives, anchors, negatives)即(a1, p, a2, n)。其中(a1, p)构成全部正样本对索引(a2, n)构成全部负样本对索引。Triplet miner输出一个大小为 3 的元组(anchors, positives, negatives)即(a, p, n)。值得强调的是如果不用 miner损失函数默认会使用 batch 中所有可能的 pair/triplet。也就是说 miner 是可选的筛子只有当你希望损失只作用于被挖掘出来的难样本时才有必要引入。关于online与offline两个术语文档给出明确约定本仓库的这些 miner 都是 online 的在训练批次内部即时挖掘offline miner 则应实现为一个 PyTorch Sampler在 DataLoader 层面预生成困难样本。这从侧面说明了 miners 与 samplers 两个子模块的分工前者作用于单次前向的 embedding 张量后者作用于数据集采样。1.1 Miner 与 Loss 的标准配合方式文档给出的标准用法如下这是所有内置 miner 的统一调用约定from pytorch_metric_learning import miners, losses miner_func miners.SomeMiner() loss_func losses.SomeLoss() miner_output miner_func(embeddings, labels) losses loss_func(embeddings, labels, miner_output)先对miner_func(embeddings, labels)做挖掘再把挖掘结果作为第三个参数传入损失函数。此时损失只会计算 miner 输出的那些索引所对应的样本。例如文档在介绍BatchEasyHardMiner时特别指出若要复现论文Improved Embeddings with Easy Positive Triplet MiningWACV 2020中的损失函数应将此 miner 与NTXentLoss(temperature0.1)组合使用。1.2 ref_emb 与 ref_labels挖掘的参照系BaseMiner的mine方法签名是mine(self, embeddings, labels, ref_emb, ref_labels)。默认情况下embeddings ref_emb、labels ref_labels即自己和自己比较在 batch 内挖掘但在forward中见 base_miner.pyref_emb/ref_labels是可选的若传入外部参照 embedding则anchors 从embeddings中取positives/negatives 从ref_emb中取。这在需要用一批新数据去查询一批参照数据的跨批次挖掘场景如近邻检索训练中非常有用也是理解后续自定义 miner 时的关键约定。二、BaseMiner所有 miner 的基类所有内置 miner 都继承自BaseMinerbase_miner.py因此共享以下__init__参数miners.BaseMiner(collect_statsFalse, distanceNone)参数说明collect_stats若为True会收集便于实验分析的各类统计量例如正/负样本对的距离分布、角度统计等若为False则跳过这些计算以提速。若希望全局默认开启可以设置 COLLECT_STATS 标志。distance一个 distance 对象如LpDistance、CosineSimilarity、SNRDistance。若为None则使用该 miner 的默认距离。默认距离绝大多数 miner 的默认距离为LpDistance(normalize_embeddingsTrue, p2, power1)即对 embedding 做 L2 归一化后的欧氏距离MultiSimilarityMiner例外其默认距离是CosineSimilarity()见下文。从源码看距离对象的注入发生在 module_with_records_and_reducer.pyModuleWithRecordsAndDistance.__init__中self.distance self.get_default_distance() if distance is None else distance而get_default_distance默认返回LpDistance(p2)子类可以覆写get_default_distance——例如MultiSimilarityMiner就覆写为CosineSimilarity()见 multi_similarity_miner.py。因此每个 miner 的默认距离并非写死而是可覆写的设计。子类必须实现的两个方法# 返回某种形式的索引 def mine(self, embeddings, labels, ref_emb, ref_labels): raise NotImplementedError # 校验 miner 输出的形状/长度是否合法 def output_assertion(self, output): raise NotImplementedErroroutput_assertion的默认实现base_miner.py做两件事若输出是长度 3 的元组校验其为 (a, p, n) 且三个张量长度相等并记录num_triplets统计量若输出是长度 4 的元组校验其为 (a1, p, a2, n) 且(a1, p)、(a2, n)各自等长并记录num_pos_pairs、num_neg_pairs。任何其他长度的输出会直接抛TypeError。这保证了所有 miner 的输出契约一致损失函数可以放心消费。此外forward中的挖掘过程被包裹在torch.no_grad()中base_miner.py说明挖掘逻辑本身不参与梯度计算——梯度只通过被选中样本的 loss 传播这是 miner 设计的一个重要实现细节。三、内置 Miner 逐个详解3.1 AngularMiner按夹角阈值挖掘三元组论文依据Angular LossarXiv:1708.01682。miners.AngularMiner(angle20, **kwargs)参数angle——返回形成夹角大于该角度的三元组夹角定义与 angular loss 论文一致。angle默认 20度源码中通过np.radians(angle)转为弧度后参与比较见 angular_miner.py。默认距离LpDistance(p2, power1, normalize_embeddingsTrue)并且这是唯一兼容的距离。源码通过c_f.assert_distance_type(self, LpDistance, p2, power1, normalize_embeddingsTrue)angular_miner.py在初始化时就强制校验传入其他距离对象会直接报错。这与该 miner 的几何定义强相关——它依赖 L2 归一化距离计算angles torch.atan(ap_dist / (2 * nc_dist))其中nc_dist是负样本到 anchor-positive 中心的距离见 angular_miner.py。当collect_statsTrue时AngularMiner 还会记录average_angle、min_angle、max_angle、std_of_angle、average_angle_above_threshold、average_angle_below_threshold等统计量便于观察 batch 内夹角分布。3.2 BatchEasyHardMiner可自由组合的正/负策略挖掘器论文依据Improved Embeddings with Easy Positive Triplet MiningWACV 2020。miners.BatchEasyHardMiner( pos_strategyBatchEasyHardMiner.EASY, neg_strategyBatchEasyHardMiner.SEMIHARD, allowed_pos_rangeNone, allowed_neg_rangeNone, **kwargs )参数pos_strategy正样本策略取以下常量之一常量即字符串也可直接写字符串BatchEasyHardMiner.HARD或hard每个 anchor 返回最难的距离最远的正样本BatchEasyHardMiner.SEMIHARD或semihard返回比所选负样本更近的最难正样本BatchEasyHardMiner.EASY或easy返回最容易的正样本距离最近的BatchEasyHardMiner.ALL或all返回所有可能的正样本对。neg_strategy负样本策略取值同上hard每个 anchor 返回最难的距离最近的负样本semihard返回比所选正样本更远的最难负样本easy返回最容易的距离最远的负样本all返回所有可能的负样本对。allowed_pos_range可选的元组限定 anchor-positive 距离/相似度的允许范围例如allowed_pos_range (0.2, 1)为None时不施加范围限制。allowed_neg_range可选的元组限定 anchor-negative 距离/相似度的允许范围例如allowed_neg_range (0.2, 1)为None时不施加范围限制。组合限制源码在__init__中直接抛ValueError见 batch_easy_hard_miner.pypos_strategy与neg_strategy不能同时为semihard若pos_strategy为semihard则neg_strategy不能为all反之亦然。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)。实现层面有几个值得注意的点。第一get_negatives在负样本策略为 hard/semihard 时实际调用的是EASY挖掘函数距离按 inverted 与否取 max/min 的镜像本质上是取距离最近/最远的同一套 min/max 逻辑见 batch_easy_hard_miner.py。第二get_x_per_row通过构造mask并把不满足条件的位置填充为inf或-inf再用torch.min/torch.max按行挑选semihard_thresholds和val_range都通过 mask 施加约束batch_easy_hard_miner.py。第三当两种策略都不是all时输出会被对齐为(a, p, a, n)的 pair 格式batch_easy_hard_miner.py。3.3 BatchHardMiner每个 anchor 一条最难三元组论文依据In Defense of the Triplet Loss for Person Re-IdentificationarXiv:1703.07737。miners.BatchHardMiner(**kwargs)对 batch 中的每个元素该 miner 找出最难的距离最远的正样本和最难的距离最近的负样本组成一条三元组因此 batch size 为 N 时输出 N 条三元组。文档明确指出其等价关系BatchHardMiner等价于BatchEasyHardMiner(pos_strategyhard, neg_strategyhard)并把输出 pair 转换为 triplet。源码证实了这一说法——batch_hard_miner.py 中BatchHardMiner直接继承BatchEasyHardMiner在__init__中固定pos_strategyHARD, neg_strategyHARD并在mine中把父类返回的(a1, p, a2, n)压缩为(a1, p, n)batch_hard_miner.py。这也是同一个挖掘逻辑、两种输出格式的最直观案例。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)。3.4 DistanceWeightedMiner距离加权采样论文依据Sampling Matters in Deep Embedding LearningarXiv:1706.07567。miners.DistanceWeightedMiner(cutoff0.5, nonzero_loss_cutoff1.4, **kwargs)参数cutoff低于该值的 pair 距离会被截断clip为该值避免低距离区间的高方差nonzero_loss_cutoff距离大于该值的 pair 会被丢弃因为对 loss 的贡献接近 0。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)且这是唯一兼容的距离源码同样通过assert_distance_type校验见 distance_weighted_miner.py。重要限制该 miner只在低维 embedding如 64 维且 L2 归一化距离下工作良好。原因是其采样权重公式与维度d直接相关——源码中采样权重为log_weights (2.0 - d) * torch.log(mat) - ((d - 3) / 2) * torch.log(1.0 - 0.25 * (mat**2.0))见 distance_weighted_miner.py即论文第 4 节第一个方程高维下该公式的统计特性会退化。文档建议高维或任意距离度量场景下改用 UniformHistogramMiner下文详述它功能上大致等价但不受维度与距离类型限制。实现细节上该 miner 只采样负样本同类别样本的权重被 mask 置 0权重再乘以距离小于nonzero_loss_cutoff的布尔掩码并做归一化最后通过lmu.get_random_triplet_indices(labels, ref_labelsref_labels, weightsweights)按权重随机抽取三元组distance_weighted_miner.py。注意它输出的是 triplet 格式。3.5 EmbeddingsAlreadyPackagedAsTriplets直接消费预排布好的三元组miners.EmbeddingsAlreadyPackagedAsTriplets()如果你的 embedding 已经按每 3 个一组的顺序排布好anchor, positive, negative用这个 miner 强制损失函数只使用这些现成的三元组。例如 batch size 为 6 时应排布为torch.stack([anchor1, positive1, negative1, anchor2, positive2, negative2], dim0)源码实现非常直白a arange(0, batch_size, 3)、p arange(1, batch_size, 3)、n arange(2, batch_size, 3)见 embeddings_already_packaged_as_triplets.py。它不关心距离矩阵纯索引切片适合与任何损失函数配合使用尤其适合上游 pipeline 已经产出三元组的场景。3.6 HDCMiner级联式困难对过滤论文依据Hard-Aware Deeply Cascaded EmbeddingICCV 2017。miners.HDCMiner(filter_percentage0.5, **kwargs)参数filter_percentage——返回的 pair 所占百分比。例如filter_percentage0.25表示只返回最难的 25% 的 pair。其pair 池既可以是内部自动生成batch 内全部 pair也可以由外部指定见下文。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)。两个重要的公开方法源码见 hdc_miner.py# 把另一个 miner 挖出的 pair/triplet 外部注入 HDCMiner def set_idx_externally(self, external_indices_tuple, labels): self.a1, self.p, self.a2, self.n lmu.convert_to_pairs(external_indices_tuple, labels) self.was_set_externally True # 重置内部状态 def reset_idx(self): self.a1, self.p, self.a2, self.n None, None, None, None self.was_set_externally False级联使用的官方示例先粗挖、再精挖minerA miners.MultiSimilarityMiner(epsilon0.1) minerB miners.HDCMiner(filter_percentage0.25) hard_pairs minerA(embeddings, labels) minerB.set_idx_externally(hard_pairs, labels) very_hard_pairs minerB(embeddings, labels)这条调用链展示了miner 串联的典型玩法MultiSimilarityMiner先按相似度阈值筛出 hard pairsHDCMiner再在这些 pair 中按距离取最难的 25%。实现上mine中会对正/负 pair 的距离分别做torch.topk正样本取最大距离、负样本取最小距离距离is_inverted时方向相反k ceil(filter_percentage * num_pairs)hdc_miner.py。3.7 MultiSimilarityMiner多相似度阈值挖掘论文依据Multi-Similarity Loss with General Pair Weighting for Deep Metric LearningCVPR 2019。miners.MultiSimilarityMiner(epsilon0.1, **kwargs)参数epsilon——基于相似度的两则选择规则负样本对当相似度大于最难的最低的正样本对相似度 − epsilon时被选中正样本对当相似度小于最难的最高的负样本对相似度 epsilon时被选中。默认距离CosineSimilarity()这是内置 miner 中唯一默认使用余弦相似度的因其论文定义在相似度语义上。实现上mine先通过lmu.get_all_pairs_indices拿到全部正/负 pair然后把非目标类位置填充为±inf后分别排序再与每行最难的极值做比较筛选multi_similarity_miner.py。特殊处理当 batch 内没有正样本对或没有负样本对时直接返回空张量multi_similarity_miner.py避免空索引引发崩溃——这是一个值得在自定义 miner 中借鉴的边界处理。3.8 PairMarginMiner按距离/相似度边界筛 pairminers.PairMarginMiner(pos_margin0.2, neg_margin0.8, **kwargs)参数pos_margin正样本对被选中的距离或相似度上界/下界——距离语义下正对距离大于该值才被选中若距离是 inverted 的即相似度则正对相似度小于该值才被选中neg_margin负样本对被选中的距离或相似度下界/上界——距离语义下负对距离小于该值才被选中inverted 时则负对相似度大于该值才被选中。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)。源码中的掩码构造直观展示了inverted分支逻辑pair_margin_miner.pypos_mask ( pos_pair self.pos_margin if self.distance.is_inverted else pos_pair self.pos_margin ) neg_mask ( neg_pair self.neg_margin if self.distance.is_inverted else neg_pair self.neg_margin )即正对太远超过 pos_margin才值得优化、负对太近低于 neg_margin才值得优化。开启collect_stats时还会记录pos_pair_dist、neg_pair_dist的平均距离统计量。3.9 TripletMarginMiner按 margin 违例筛三元组miners.TripletMarginMiner(margin0.2, type_of_tripletsall, **kwargs)参数marginanchor-positive 距离与 anchor-negative 距离之差type_of_triplets四种取值all所有违反 margin的三元组即an_dist − ap_dist marginhardall的子集且负样本比正样本更靠近 anchortriplet_margin 0semihardall的子集且负样本比正样本更远离 anchortriplet_margin 0easy所有不违反 margin的三元组。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)。源码对四种类型给出了精确的阈值条件triplet_margin_miner.pyeasy要求triplet_margin margin其余类型要求triplet_margin margin其中hard额外要求triplet_margin 0semihard额外要求triplet_margin 0。这里的triplet_margin在非 inverted 距离下定义为an_dist − ap_distinverted 时取反。该 miner 是损失函数 TripletMarginLoss 最常用的配套挖掘器。3.10 UniformHistogramMiner直方图分箱的均匀采样这是文档特别推荐的DistanceWeightedMiner 的高维替代品功能大致等价但任意维度 embedding、任意距离度量下都能正常工作。miners.UniformHistogramMiner(num_bins100, pos_per_bin10, neg_per_bin10, **kwargs):参数num_bins把距离划分成的分箱bin数。例如当前 batch 的距离范围是 0 到 2、num_bins100时每个 bin 宽度为 0.02pos_per_bin每个 bin 挖掘的正样本对数量neg_per_bin每个 bin 挖掘的负样本对数量。默认距离LpDistance(normalize_embeddingsTrue, p2, power1)。但因为它不依赖特定的距离公式你可以自由替换任何距离例如文档给出的SNRDistance示例from pytorch_metric_learning.miners import UniformHistogramMiner from pytorch_metric_learning.distances import SNRDistance miner UniformHistogramMiner( num_bins100, pos_per_bin25, neg_per_bin33, distanceSNRDistance(), )工作流程文档明确列出把正样本对距离划分进 100 个 bin每个 bin 返回 25 个正样本对若某 bin 内没有 pair则返回 0 个把负样本对距离划分进 100 个 bin每个 bin 返回 33 个负样本对同理空 bin 返回 0 个。实现上get_bins用torch.linspace(min, max, stepsnum_bins 1)生成分箱边界filter_by_bin逐 bin 用torch.multinomial做有放回随机抽取最后torch.cat拼接所有 bin 的索引uniform_histogram_miner.py。这样挖掘出的 pair 在距离轴上近似均匀分布避免模型只盯着某一距离区间的样本。四、如何编写自定义 Miner仓库在 docs/extend/miners.md 中给出了自定义 miner 的三步法① 继承BaseMiner② 实现mine方法③ 在mine内返回张量元组。下面是文档中的完整示例。Pair miner 示例返回(a1, p, a2, n)from pytorch_metric_learning.miners import BaseMiner from pytorch_metric_learning.utils import loss_and_miner_utils as lmu class ExamplePairMiner(BaseMiner): def __init__(self, margin0.1, **kwargs): super().__init__(**kwargs) self.margin margin def mine(self, embeddings, labels, ref_emb, ref_labels): mat self.distance(embeddings, ref_emb) a1, p, a2, n lmu.get_all_pairs_indices(labels, ref_labels) pos_pairs mat[a1, p] neg_pairs mat[a2, n] pos_mask ( pos_pairs self.margin if self.distance.is_inverted else pos_pairs self.margin ) neg_mask ( neg_pairs self.margin if self.distance.is_inverted else neg_pairs self.margin ) return a1[pos_mask], p[pos_mask], a2[neg_mask], n[neg_mask]Triplet miner 示例返回(a, p, n)from pytorch_metric_learning.miners import BaseMiner from pytorch_metric_learning.utils import loss_and_miner_utils as lmu class ExampleTripletMiner(BaseMiner): def __init__(self, margin0.1, **kwargs): super().__init__(**kwargs) self.margin margin def mine(self, embeddings, labels, ref_emb, ref_labels): mat self.distance(embeddings, ref_emb) a, p, n lmu.get_all_triplets_indices(labels, ref_labels) pos_pairs mat[a, p] neg_pairs mat[a, n] triplet_margin pos_pairs - neg_pairs if self.distance.is_inverted else neg_pairs - pos_pairs triplet_mask triplet_margin self.margin return a[triplet_mask], p[triplet_mask], n[triplet_mask]示例使用方式miner ExamplePairMiner() embeddings torch.randn(128, 512) labels torch.randint(0, 10, size(128,)) pairs miner(embeddings, labels)两个自定义示例展示了编写 miner 时最常用的工具函数均位于 loss_and_miner_utils.pylmu.get_all_pairs_indices(labels, ref_labels)返回全部正对(a1, p)与全部负对(a2, n)的索引loss_and_miner_utils.pylmu.get_all_triplets_indices(labels, ref_labels)返回全部三元组索引(a, p, n)loss_and_miner_utils.py内部对超大 batch 自动切换向量化/循环实现以规避 INT_MAX 限制self.distance(embeddings, ref_emb)得到距离/相似度矩阵通过self.distance.is_inverted判断语义方向LpDistance等距离非 invertedCosineSimilarity等相似度 inverted。自定义 miner 无需自己实现output_assertion——BaseMiner的默认实现会按输出长度自动区分 pair4 元组与 triplet3 元组并校验长度一致性。五、从源码与测试看 Miner 的工程细节5.1 统计量收集机制BaseMiner.__init__会注册三个统计属性num_pos_pairs、num_neg_pairs、num_tripletsbase_miner.py各子类在此基础上追加自己的统计量如BatchEasyHardMiner的easiest_triplet/hardest_triplet、AngularMiner的average_angle等。这些统计量仅在collect_statsTrue时计算且全部在torch.no_grad()下执行。文档也提示若希望默认开启统计可设置全局 COLLECT_STATS 标志。5.2 默认距离与兼容性校验综合前文内置 miner 的默认距离可以归纳为一张速查表Miner默认距离距离限制绝大多数 minerLpDistance(p2, power1, normalize_embeddingsTrue)无AngularMiner同上仅此一种初始化时强校验DistanceWeightedMiner同上仅此一种初始化时强校验MultiSimilarityMinerCosineSimilarity()无可在**kwargs中传入自定义距离UniformHistogramMinerLpDistance(...)无可换任意距离如SNRDistance距离对象的注入统一发生在 module_with_records_and_reducer.py 的ModuleWithRecordsAndDistance中子类通过覆写get_default_distance()改变默认值。5.3 测试覆盖仓库为每个内置 miner 都提供了独立测试例如 tests/miners/test_angular_miner.py、test_batch_easy_hard_miner.py、test_batch_hard_miner.py、test_distance_weighted_miner.py、test_hdc_miner.py、test_multi_similarity_miner.py、test_pair_margin_miner.py、test_triplet_margin_miner.py、test_uniform_histogram_miner.py。其中 test_batch_easy_hard_miner_labels.py 专门验证BatchEasyHardMiner在ref_emb/ref_labels跨批次挖掘外部参照场景下的标签处理。阅读这些测试可以快速确认每个 miner 的输出格式、策略组合合法性与边界行为。六、选型建议与总结综合文档与源码内置 miner 的选型可以按如下思路追求稳定基线、希望正/负策略可自由组合用BatchEasyHardMiner其pos_strategy/neg_strategy/allowed_pos_range/allowed_neg_range提供了极高的定制自由度只需最经典的最难三元组直接使用BatchHardMiner等价于 hard/hard 组合的 pair 转 triplet低维 embedding L2 归一化距离DistanceWeightedMiner能给出论文原生的距离加权采样高维 embedding 或自定义距离度量改用UniformHistogramMiner分箱均匀采样对维度和距离类型无特殊要求按 margin 违例定义困难样本TripletMarginMiner配合 Triplet 类损失或PairMarginMiner配合 Pair 类损失基于相似度语义MultiSimilarityMiner默认余弦相似度配合 MultiSimilarityLoss 使用需要级联的困难中的困难HDCMiner的set_idx_externally可以把任一 miner 的输出作为下一级挖掘的输入池数据已预排布为三元组EmbeddingsAlreadyPackagedAsTriplets零成本直通几何敏感的任务如人脸角度AngularMiner按夹角阈值筛选三元组但需注意其仅兼容 L2 归一化欧氏距离。最后重申文档开篇的核心结论miner 是可选的——不传 miner 时损失函数默认使用 batch 内全部 pair/triplet传入 miner 后损失只作用于被挖掘出的k个样本。掌握好这层筛选语义再结合 losses 文档、distances 文档 与 samplers 文档 一起阅读你就能针对自己的数据分布设计出一套完整的挖掘 加权 损失训练管线。赞分享人工智能机器学习深度学习计算机视觉【免费下载链接】pytorch-metric-learningThe easiest way to use deep metric learning in your application. Modular, flexible, and extensible. Written in PyTorch.项目地址https://gitcode.com/gh_mirrors/py/pytorch-metric-learning点击查看免费下载相关推荐PyTorch Metric Learning挖掘器指南如何高效选择困难样本对PyTorch Metric Learning挖掘器指南如何高效选择困难样本对 PyTorch Metric Learning是一个强大的深度学习度量学习库人工智能机器学习深度学习计算机视觉PyTorch Metric Learning 安装与配置完全指南PyTorch Metric Learning 安装与配置完全指南 项目基础介绍与编程语言 PyTorch Metric Learning 是一个深度度量学习领人工智能机器学习深度学习计算机视觉PaddleSeg 语义分割损失函数详解OhemCrossEntropyLoss 在线难样本挖掘交叉熵的源码原理与配置实战PaddleSeg 语义分割损失函数详解OhemCrossEntropyLoss 在线难样本挖掘交叉熵的源码原理与配置实战 本文围绕 PaddleSeg 仓库人工智能计算机视觉预训练上一篇ReClass.NET完全指南终极内存逆向工程工具入门下一篇EMQX 客户端消息分页 API 修复max_payload_bytes 截断后 meta.position 游标语义修正创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

Claude Code加装Superpowers:核心Skills与实战组合

Claude Code加装Superpowers:核心Skills与实战组合

开头直接进入情景。这个“superpowers”不是超能力,而是GitHub上那个名为superpowers的Claude Code skills集合。很多朋友在热词里搜“superpowers 具体使用”“有那些skills”“怎么引入这些技能”“想要安装superpowers”,其实就是想搞清楚这套技能框架…

2026/10/12 19:45:00 阅读更多 →
代码审查总变吵架现场?这套沟通话术让同事心甘情愿改Bug

代码审查总变吵架现场?这套沟通话术让同事心甘情愿改Bug

1. 为什么代码审查总变成“吵架现场”——先把问题定性干过几年开发的人都懂,代码审查这事,技术难度从来不是最大的坎,最大的坎是“人”。我见过太多团队,明明都是为项目好,一开审查会就剑拔弩张,最后不是讨…

2026/10/15 8:20:01 阅读更多 →
为什么降分辨率能区分 CPU 和 GPU 瓶颈

为什么降分辨率能区分 CPU 和 GPU 瓶颈

核心逻辑就两条: ① CPU 和 GPU 是并行工作的,帧时间取两者里慢的那个帧时间 max(CPU 耗时, GPU 耗时) ← 不是相加② 分辨率只影响 GPU 的像素工作量对 CPU 的工作量几乎没有任何影响所以降分辨率相当于单独给 GPU 减负,CPU 一动不动。减负之后帧率变没变,就暴露了到底是…

2026/10/13 17:30:54 阅读更多 →

最新新闻

AIO Sandbox 实战:容器化 AI Agent 开发环境搭建与避坑指南

AIO Sandbox 实战:容器化 AI Agent 开发环境搭建与避坑指南

1. 为什么要把一堆工具塞进同一个容器第一次看到 AIO Sandbox 这个项目的时候,我的反应是:这不就是把所有东西都堆在一起吗?浏览器、Shell、文件系统、MCP 服务、VSCode Server,五个东西塞进一个容器里,听起来像是偷懒…

2026/10/15 8:19:29 阅读更多 →
从零自建AI工程:数据、建模、部署到上线的完整复盘

从零自建AI工程:数据、建模、部署到上线的完整复盘

近几年大模型和各类Agent框架把AI的门槛压得很低,随便拖拽几下、调两个API,就能拼出一个看起来像模像样的Demo。但我心里一直有个不安:如果我只会当“搬运工”,哪天底层框架一换、接口一变,我还能不能独立把一个AI项目…

2026/10/15 8:19:29 阅读更多 →
SRM+AI智能寻源:10分钟完成一轮供应商寻源的实战拆解

SRM+AI智能寻源:10分钟完成一轮供应商寻源的实战拆解

干了十几年采购数字化,最近一年被问得最多的一个词就是“智能寻源”。过去大家谈SRM,聊的是采购订单协同、供应商档案、对账开票这些“管”的层面。现在不同了,企业手里都有了些数据,上了SRM基础模块,开始琢磨怎么把“…

2026/10/15 8:19:29 阅读更多 →
2026年薪酬设计性价比之王,这三家藏不住了

2026年薪酬设计性价比之王,这三家藏不住了

又是一年金三银四,HR圈子里弥漫着一股焦虑——薪酬设计,到底该怎么搞?老板要控成本,员工要涨工资,竞争对手在抢人,数据报告却总让人一头雾水。更扎心的是,市面上那些薪酬产品,要么价…

2026/10/15 8:19:29 阅读更多 →
artcraft 工作台:参数化生成与素材管理的高效创作流程

artcraft 工作台:参数化生成与素材管理的高效创作流程

1. 从“artcraft”这个名字说起:它到底想解决什么问题第一次看到“artcraft”这个项目标题,我的直觉是:这大概率是一个把“艺术(art)”和“手工艺/工程(craft)”揉在一起的工具型项目。事实也确…

2026/10/15 8:19:29 阅读更多 →
Spring Boot实战:高校学生电子履历管理系统设计与实现

Spring Boot实战:高校学生电子履历管理系统设计与实现

折腾完这套高校学生电子履历管理平台,最大的感觉就是:简历系统看着不起眼,实际做起来比想象中复杂得多。这个项目虽然以毕业设计的形式展开,但功能覆盖了学生端、企业端、管理员端的完整闭环,既要把 Java Web 环境下常…

2026/10/15 8:18:28 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →