人工智能机器学习深度学习计算机视觉【免费下载链接】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),仅供参考