Skip to content

Migrating from version 2 to version 3

Find the version 2 import, class, method, argument, or behavior in the table. Rows are sorted alphabetically. Names are relative to pytorch_metric_learning unless another package is named. A removed class's direct module import follows the same replacement as its package export. Version 3 has no compatibility aliases. The release notes explain the changes and corrected numerical behavior; the examples below run in the test suite.

v2 symbol or call v3 replacement Note
A non-DivisorReducer on ProxyAnchorLoss, MarginLoss, or SparseCentersRegularizer DivisorReducer, or MultipleReducers routing those terms to it Terms with a divisor raise ValueError in other reducers.
A subclass's automatically discovered calculate_* method AccuracyCalculator(custom_metrics={"name": RetrievalMetric(function, neighbors=...)}) function(inputs: RetrievalInputs) returns one value per query (NaN where undefined); the calculator drops lone queries and reduces. See custom accuracy metrics.
accuracy_calculator.get_label_match_counts / get_lone_query_labels RetrievalInputs.relevant_counts in a custom metric Counts honor custom comparators; the calculator excludes lone queries before reducing.
accuracy_calculator.precision_at_k(knn_labels, gt_labels, k, avg_of_avgs, return_per_class, label_comparison_fn) evaluation.precision_at_k(inputs, k) Returns per-query float64 values; reduction belongs to the calculator.
accuracy_calculator.r_precision / mean_average_precision / mean_reciprocal_rank(..., avg_of_avgs, return_per_class, ...) evaluation.r_precision(inputs), evaluation.mean_average_precision(inputs), evaluation.mean_average_precision_at_r(inputs), evaluation.mean_reciprocal_rank(inputs) Per-query float64 values.
AccuracyCalculator fixed k larger than a gallery k capped at the available neighbors of each call The configured k is unchanged, so one calculator serves galleries of different sizes.
AccuracyCalculator() with implicit Faiss Default PyTorch squared-Euclidean search Pass knn_func=FaissKNN() explicitly to retain Faiss; tie order may differ.
AccuracyCalculator(device=None) selecting CUDA The query tensor's device Move query/reference tensors explicitly or pass device.
AccuracyCalculator(label_comparison_fn=..., include=("NMI",)) raising NotImplementedError ValueError Clustering metrics still require the default comparison.
AccuracyCalculator(return_per_class=True) calculator.get_accuracy_per_class(...) Returns per-class values keyed by label, with NaN for classes without relevant references.
AccuracyCalculator.description() Application-owned metric/run labels Read avg_of_avgs if the application needs that setting in its label.
AccuracyCalculator.get_accuracy casting labels to float32 Labels keep their dtype Large integer labels no longer collide; embeddings keep their floating dtype.
AccuracyCalculator.get_accuracy returning lists for per-class metrics get_accuracy returning dict[str, float] Per-class values come only from get_accuracy_per_class.
AccuracyCalculator.get_curr_metrics() calculator.metrics A tuple of the metric names selected at construction.
AccuracyCalculator.requires_knn() / requires_clustering() overrides The registration type: RetrievalMetric or ClusteringMetric(function) ClusteringMetric functions take (query_labels, cluster_labels) and return a float.
AngularLoss.set_stats Compute diagnostics in caller code No recorded avg_angle state remains.
AngularMiner(angle=...) AngularMiner(alpha=...) Degrees, like AngularLoss(alpha=...); angles use normalized embeddings.
AngularMiner.set_stats Diagnostics computed from returned indices No stored miner statistics remain.
ArcFaceLoss(margin=28.6) and SubCenterArcFaceLoss(margin=28.6) in degrees margin=0.5 in radians The paper's unit; convert with math.radians.
ArcFaceLoss.cast_types .to(device, dtype) Placement belongs to the caller.
Automatic parameter movement/casting during forward loss_func.to(device, dtype) before use Include loss parameters in the optimizer; see the example below.
BaseDistance(is_inverted=True) Set is_inverted = True on the custom similarity class The constructor no longer accepts this flag; p still controls normalization.
BaseDistance(normalize_embeddings, p, power) positionally Keyword-only options For example LpDistance(normalize_embeddings=False, power=2).
BaseDistance.set_default_stats Application diagnostics No recorded norm statistics remain.
BaseDistance.smallest_dist torch.minimum/torch.maximum chosen by is_inverted BaseDistance.pairwise(query, ref) computes normalized, powered row-wise values.
BaseMetricLossFunction.all_regularization_loss_names() regularization_terms(embeddings) Regularization is composed explicitly after objective reduction.
BaseMetricLossFunction.get_default_distance() / get_default_reducer() default_distance() / default_reducer() The same applies to miners and regularizers.
BaseMetricLossFunction.sub_loss_names / zero_losses(embeddings) Return {} when there is nothing to compute Reducers sum an empty dictionary to a differentiable zero.
BaseMiner.output_assertion Validation in BaseMiner.forward Custom miners implement mine(embeddings, labels, indices_tuple, ref_emb, ref_labels); see custom miners.
BaseReducer.forward requiring exactly one term forward reduces every term and sums them An empty term dictionary reduces to a differentiable zero; MultipleReducers chooses a reducer per term name.
BaseReducer.pos_pair_reduction, neg_pair_reduction, triplet_reduction element_reduction(losses, anchors, embeddings, labels) Every term is reduced through its anchor indices.
BaseReducer.set_losses_size_stat Compute counts from the loss dictionary No recorded reducer statistics remain.
BatchEasyHardMiner.get_func_for_stats Explicit application reductions Choose min, max, or mean for the desired diagnostic.
BatchEasyHardMiner.HARD, SEMIHARD, EASY, ALL The strings "hard", "semihard", "easy", "all" Typed as types.MiningStrategy.
BatchEasyHardMiner.set_stats Diagnostics computed from returned indices No stored miner statistics remain.
BatchedDistance(..., iter_fn=callback) Iterate over distance(query, ref) Each item is (mat, start, end); no callback is involved.
Catching AssertionError for invalid arguments Catch TypeError or ValueError Validation remains active under python -O.
CenterInvariantRegularizer.compute_loss(weights=...) compute_loss(x=...) Prefer calling the regularizer on the tensor directly.
CircleLoss(m=...) CircleLoss(margin=...) Same value and default (0.4).
ClassWeightedReducer moving weights to the losses' device reducer.to(device) A device mismatch raises ValueError.
ClassWeightedReducer.element_reduction_helper element_reduction(losses, anchors, embeddings, labels) Every term is reduced through its anchor indices.
collect_stats=True on losses, miners, distances, reducers, or regularizers Compute diagnostics from returned tensors or use PyTorch forward hooks Recorded statistic attributes were removed; see statistics.
CosFaceLoss.cast_types .to(device, dtype) Placement belongs to the caller.
CosineSimilarity(normalize_embeddings=..., p=..., power=...) CosineSimilarity(), or DotProductSimilarity(normalize_embeddings=True, p=..., power=...) for other norms or powers Losses and regularizers that require CosineSimilarity rely on signed unit-L2 cosines, so it takes no options.
CrossBatchMemory checkpoint _extra_state A v3 checkpoint with queue_state Old queue metadata is not loaded through a compatibility path.
CrossBatchMemory moving its queue during forward Place the wrapper with .to(device, dtype) label_dtype is keyword-only and defaults to torch.long.
CrossBatchMemory storing labels after torch.can_cast Exact label conversion to label_dtype Labels that change value, such as 2**32 in int32, raise ValueError.
CrossBatchMemory.add_to_memory / curr_batch_idx CrossBatchMemory.forward The queue is updated only after the miner and loss succeed.
CrossBatchMemory.check_loss_support / supported_losses() Any BaseMetricLossFunction that accepts ref_emb Losses that reject references, such as LiftedStructureLoss and the proxy losses, raise ValueError on the first call.
Custom already_reduced handling of regularization penalties Customize the loss's regularization_terms() A reducer never receives those penalties; loss_terms() returns them in the dictionary.
datasets.BaseDataset torch.utils.data.Dataset Applications own downloads, transforms, labels, and split selection.
datasets.Cars196 An application dataset for Cars196 Preserve the published split and citation.
datasets.CUB An application dataset for CUB-200-2011 Preserve the published split and citation.
datasets.INaturalist2018 An application dataset for iNaturalist 2018 Preserve the published split and citation.
datasets.StanfordOnlineProducts An application dataset for Stanford Online Products Preserve the published split and citation.
Default NMI and AMI metrics Explicit include plus kmeans_func Install [clustering] and choose a clustering backend.
DistributedLossWrapper warning without a process group Silent delegation to the wrapped loss One-process and uninitialized runs return the wrapped loss unchanged.
DistributedLossWrapper(loss, efficient=False) DistributedLossWrapper(loss, objective="global") The default full-batch objective. Version 2 multiplied the gathered loss by the world size; the global objective returns the unscaled loss, and DDP's gradient average recovers the single-process gradient.
DistributedLossWrapper(loss, efficient=True) DistributedLossWrapper(loss, objective="local_anchor") A different objective and gradient; memory losses support only "global".
DistributedMinerWrapper(miner, efficient=...) DistributedMinerWrapper(miner, objective=...) Use the same objective as the loss wrapper.
DotProductSimilarity() normalizing embeddings DotProductSimilarity(normalize_embeddings=True) The default is now a plain dot product. NPairsLoss and NormalizedSoftmaxLoss keep their normalized default.
DynamicSoftMarginLoss moving its histogram during forward Place the loss with .to(device, dtype) Its checkpointed histogram keeps its configured precision.
DynamicSoftMarginLoss.hist_ DynamicSoftMarginLoss.hist A buffer saved in state_dict.
Empty mined tuples treated as unweighted (convert_to_weights returning ones) Pass indices_tuple=None for no restriction A supplied tuple with no indices selects nothing: miner-weighted losses return a differentiable zero.
Evaluation with string labels Convert labels to integer tensors in caller code Use one mapping shared by query and reference sets.
Fixed MarginLoss.beta outside its state dictionary A checkpointed buffer that follows .to() Account for the added beta key when importing an old checkpoint.
Float, bool, or uint8 index tensors in indices_tuple int64 or int32 tensors Other dtypes raise TypeError.
Forwarded attributes such as batched_distance.normalize_embeddings batched_distance.distance.normalize_embeddings Only is_inverted is exposed directly for search ordering.
GenericPairLoss(mat_based_loss=...) with _compute_loss(...) GenericPairLoss(**options) with pair_loss(mat, pairs) Use pair_values or pair_masks; return {} when nothing is valid; see pair-based losses.
HDCMiner.filter_original_indices Use the tuple returned by the miner Pass candidates as indices_tuple; filtering never mutates them.
HDCMiner.reset_idx() Omit indices_tuple The miner keeps no candidate state between calls.
HDCMiner.set_idx_externally(indices_tuple, labels) miner(embeddings, labels, indices_tuple=pairs) Every built-in miner accepts candidate tuples.
HDCMiner.should_select_largest The miner handles orientation from distance.is_inverted Selection follows distance.is_inverted.
HierarchicalSampler.reshuffle() Begin a new iteration over the sampler Batch generation occurs during iteration, not construction or len().
HistogramLoss(n_bins=..., delta=...) HistogramLoss(num_bins=...) delta is 2 / num_bins; the default remains 100 bins.
Implicit scikit-learn installation pytorch-metric-learning[clustering] Required for NMI and AMI, alongside an explicit clustering backend.
InferenceModel.train_indexer evaluation.FaissKNN.train(embeddings) Extract the reference embeddings first; use add, save, and load on the same backend.
Labels on another device moved automatically Labels on the embeddings' device A device mismatch raises ValueError; place labels with .to(embeddings.device).
LargeMarginSoftmaxLoss(margin=4.0) float margins An int margin Non-integer margins raise ValueError instead of being truncated.
LargeMarginSoftmaxLoss.cast_types .to(device, dtype) This also applies to inherited classification losses.
LiftedStructureLoss with ref_emb, CrossBatchMemory, or asymmetric SelfSupervisedLoss A loss that supports reference embeddings It compared query and reference indices incorrectly and now raises ValueError.
LiftedStructureLoss(neg_margin, pos_margin) / GeneralizedLiftedStructureLoss(neg_margin, pos_margin) positionally (pos_margin, neg_margin) Same order as ContrastiveLoss and PairMarginMiner; keyword calls are unchanged.
Loss terms with reduction_type Terms with losses, indices, and optional divisor Kinds follow from indices: None, a tensor, a pair tuple, or a triplet tuple.
loss.W, loss.proxies, loss.fc parameters loss.weight with shape (num_classes, embedding_size) One row per class or center; see learnable weights. ManifoldLoss.proxies keeps its name because its rows are unlabeled points, not classes.
losses.BaseLossWrapper torch.nn.Module CrossBatchMemory and SelfSupervisedLoss inherit it directly.
losses.dynamic_soft_margin_loss.find_hard_negatives DynamicSoftMarginLoss for its built-in mining, or an explicit miner The loss no longer exposes a separate mining helper.
losses.EmbeddingRegularizerMixin embedding_regularizer and embedding_reg_weight on the loss The same removal applies to losses.mixins.EmbeddingRegularizerMixin.
losses.large_margin_softmax_loss.CosineMarginSoftmaxLoss losses.BaseProxyLoss for new proxy losses The cosine-margin base is private.
losses.mixins.WeightMixin A loss parameter plus regularization_terms() when needed Weight initialization accepts an in-place callable.
losses.proxy_losses.ProxyNCALoss losses.ProxyNCALoss Import loss classes from losses; submodule paths are not public.
losses.smooth_ap, losses.tcm_loss, losses.signal_to_noise_ratio_losses modules losses.SmoothAPLoss, losses.ThresholdConsistentMarginLoss, losses.SignalToNoiseRatioContrastiveLoss Import loss classes from losses; submodule paths are not public.
losses.WeightRegularizerMixin Keyword-only weight_regularizer and weight_reg_weight The same removal applies to losses.mixins.WeightRegularizerMixin.
LpRegularizer(..., distance=...) / ZeroMeanRegularizer(distance=...) Omit it These regularizers never used a distance; the argument now raises TypeError.
LpRegularizer.compute_loss(embeddings=...) compute_loss(x=...) Positional calls are unchanged.
ManifoldLoss(...)(embeddings, indices_tuple=assignments) loss(embeddings, assignments) Proxy assignments are passed as labels; indices_tuple raises ValueError.
ManifoldLoss(l=..., K=..., lambdaC=...) ManifoldLoss(embedding_size=..., num_proxies=..., lambda_c=...) Parameter meanings are unchanged.
MarginLoss term "margin_loss" Term "loss" Rename MultipleReducers keys; beta_reg_loss is unchanged.
MatchFinder.get_matching_pairs(..., return_tuples=True) MatchFinder.get_match_indices(...) A (num_matches, 2) torch.long tensor; use .tolist() for Python pairs.
MatchFinder.get_matching_pairs(query_emb, ref_emb) MatchFinder.get_match_matrix(query_emb, ref_emb) A boolean tensor on the input device instead of a NumPy array.
MatchFinder.is_match(...) A boolean tensor on the input device Normalization and distance power now match matrix comparisons.
Metric-method keyword arguments (knn_labels, label_counts, not_lone_query_mask, cluster_labels, ...) RetrievalInputs fields matches, relevant_counts, query_labels, knn_labels matches already applies the label comparison; neighbor distances are not passed.
Mined tuples as plain tuples types.PairIndices and types.TripletIndices named tuples They unpack like tuples; plain tuples remain accepted as inputs.
miner(...) or DistributedMinerWrapper(...)(embeddings, labels, ref_emb, ref_labels) positionally miner(embeddings, labels, ref_emb=..., ref_labels=...) The third positional argument is indices_tuple, as for losses.
miners.EmbeddingsAlreadyPackagedAsTriplets Construct the three index tensors directly See the packed-triplet example below.
DataLoader(dataset, batch_size=32, sampler=MPerClassSampler(labels, m, 32)) DataLoader(dataset, batch_sampler=MPerClassSampler(labels, m, 32)) The sampler yields whole batches, so batch_size is required and the DataLoader cannot break the per-class grouping. len() counts batches.
MPerClassSampler(length_before_new_iter=...) MPerClassSampler(labels, m, batch_size, num_batches=...) Counts batches instead of indices. The default covers every example at least once.
MultipleLosses containing CrossBatchMemory or another module CrossBatchMemory(MultipleLosses({...}), ...) losses values must be BaseMetricLossFunction or MultipleLosses; others raise TypeError.
MultipleLosses([loss_a, loss_b], weights=[1, 0.5]) MultipleLosses({"a": loss_a, "b": loss_b}, weights={"a": 1, "b": 0.5}) Mappings only; see MultipleLosses.
MultipleLosses.assertions_if_not_none Constructor validation Invalid keys raise explicit exceptions.
MultipleLosses.forward(embeddings, labels, indices_tuple=None) forward(embeddings, labels=None, indices_tuple=None, ref_emb=None, ref_labels=None) Reference arguments are passed to every loss and miner.
MultipleLosses.get_indices_tuple Pass a shared indices_tuple to forward, configure per-loss miners, or both Per-loss miners select from a supplied indices_tuple as candidates; MultipleLosses contract.
MultipleReducers entries named embedding_reg_loss or weight_reg_loss Configure regularizers on the loss Penalties are added after objective reduction; these entries are no longer used.
NormalizedSoftmaxLoss.cast_types .to(device, dtype) Placement belongs to the caller.
NumPy-seeded FixedSetOfTriplets Pass a keyword-only torch.Generator Seeded sequences differ from version 2.
NumPy-seeded HierarchicalSampler Pass a keyword-only torch.Generator Seeded sequences differ from version 2.
NumPy-seeded MPerClassSampler Pass a keyword-only torch.Generator torch.manual_seed also controls its default generator.
P2SGradLoss(..., distance=...) Omit it The distance was ignored and now raises TypeError.
P2SGradLoss(descriptors_dim, num_classes) P2SGradLoss(num_classes, embedding_size) Argument order matches the other classification losses.
PairMarginMiner.set_stats Diagnostics computed from returned indices No stored miner statistics remain.
PerAnchorReducer(aggregation_func=...) PerAnchorReducer(aggregation="mean") or aggregation="sum" Losses are aggregated by anchor; the mean averages over anchors that have losses instead of over every row.
PNPLoss.VARIANTS types.PNPVariant typing.get_args(PNPVariant.__value__) lists the variants.
ProxyAnchorLoss miner weights adding w - 1 to exponents Weights multiply the exponential terms Unmined samples (w = 0) are excluded; unweighted results are unchanged.
ProxyAnchorLoss.cast_types .to(device, dtype) Placement belongs to the caller.
ProxyAnchorLoss.get_default_weight_init_func The weight_init_func constructor argument Omit it to retain the loss's default initializer.
ProxyNCALoss miner weights counting only anchors Weights count every position in the mined tuples This matches the other classification losses; a mined triplet also weights its positive and negative rows.
Python 3.10 or 3.11 Python 3.12 or newer Minimum tested runtimes are PyTorch 2.14.0 and NumPy 2.5.3.
pytorch-metric-learning[dev] The frozen development environment See development setup.
pytorch-metric-learning[docs] The frozen development environment See development setup.
pytorch-metric-learning[with-hooks-cpu] Application-owned logging; install [faiss] separately when needed record-keeper and TensorBoard integration were removed.
pytorch-metric-learning[with-hooks] Application-owned logging; install [faiss] separately when needed record-keeper and TensorBoard integration were removed.
pytorch_metric_learning.__version__ importlib.metadata.version("pytorch-metric-learning") The installed distribution metadata is the single version source.
r_precision or mean_average_precision_at_r with an integer k below the relevant count k="max_bin_count" The configuration logs a warning. R-precision now divides by the relevant count instead of by k.
RankedListLoss(margin, Tn, ..., Tp=...) RankedListLoss(margin, neg_temperature, ..., pos_temperature=...) Weighted means are exact; the 1e-5 offset and the overflow warning are gone.
reducer= deep-copied and wrapped in MultipleReducers for multi-term losses The reducer object is used as given for every term Pass a MultipleReducers to vary reducers per term.
reducer= on DynamicSoftMarginLoss, HistogramLoss, ManifoldLoss, P2SGradLoss, PNPLoss, ThresholdConsistentMarginLoss Omit it These return one reduced value; the reducer was ignored and now raises TypeError.
reducers.DoNothingReducer loss_func.loss_terms(...) Reducers always return a tensor; terms carry losses, indices, and an optional divisor.
reducers.DoNothingReducer() to get the loss dictionary loss_func.loss_terms(embeddings, labels, ...) forward always returns a tensor; see unreduced terms.
ref_emb=embeddings (the same tensor) meaning self-comparison Omit ref_emb Passing ref_emb always describes a separate reference set, so the diagonal is kept.
RegularFaceRegularizer.compute_loss(weights=...) compute_loss(x=...) Positional calls are unchanged.
samplers.TuplesToWeightsSampler convert_to_weights plus torch.utils.data.WeightedRandomSampler Compute full-dataset weights in caller code; weighted-sampling recipe.
SelfSupervisedLoss cloning labels to force a separate set ref_emb is a separate set by construction No identity workaround is needed.
SelfSupervisedLoss.check_loss_support / supported_losses() Any BaseMetricLossFunction; asymmetric mode needs ref_emb support Other modules raise TypeError at construction.
SmoothAPLoss term "ap_loss" Term "loss" Matches every single-term loss for MultipleReducers.
SoftTripleLoss.cast_types .to(device, dtype) Placement belongs to the caller.
SoftTripleLoss.gamma storing 1 / gamma SoftTripleLoss.gamma storing gamma The objective is unchanged.
SoftTripleLoss.get_default_weight_init_func The weight_init_func constructor argument Omit it to retain the loss's default initializer.
SomeLoss(..., **kwargs) forwarding distance, reducer, and regularizer arguments SomeLoss(..., **options) typed by types.LossOptions The same four keyword-only options; see loss options.
SomeMiner(..., **kwargs) forwarding distance SomeMiner(..., *, distance=None) distance is the only miner option.
SomeRegularizer(..., **kwargs) forwarding distance and reducer SomeRegularizer(..., **options) typed by types.RegularizerOptions Both options are keyword-only.
SparseCentersRegularizer.compute_loss(weights=...) compute_loss(x=...) Positional calls are unchanged.
SparseCentersRegularizer.set_stats Application diagnostics Its same-class mask is now a non-persistent buffer that follows .to().
SubCenterArcFaceLoss.get_outliers(embeddings, labels, threshold=75, return_dominant_centers=...) get_outliers(embeddings, labels, threshold_radians=math.radians(75)) Always returns types.SubCenterOutliers(outliers, dominant_centers); the threshold is in radians like margin.
SupConLoss returning zero for a batch without negatives The paper's value Each anchor's positives are still contrasted with every other sample.
testers.BaseTester Extract embeddings, then call evaluation.AccuracyCalculator Embedding extraction.
testers.GlobalEmbeddingSpaceTester Explicit query/reference split composition Split composition.
testers.GlobalTwoStreamEmbeddingSpaceTester Evaluate one stream against the other Two-stream evaluation.
testers.WithSameParentLabelTester Evaluate each parent-conditioned gallery explicitly Hierarchical retrieval.
ThresholdReducer boolean indexing Masked sum and count Values are unchanged; the reduction no longer synchronizes with the host.
ThresholdReducer.element_reduction_helper element_reduction(losses, anchors, embeddings, labels) Every term is reduced through its anchor indices.
ThresholdReducer.set_stats Compute diagnostics from caller-owned loss terms No stored num_past_filter remains.
trainers.BaseTrainer An ordinary PyTorch training loop Applications own data loading, optimizers, schedules, freezing, and checkpoints.
trainers.CascadedEmbeddings Pass mined pairs as indices_tuple to successive HDCMiner calls Cascaded mining recipe.
trainers.deep_adversarial_metric_learning.NegativeLpDistance Form the adversarial distance objective in caller code The adversarial recipe specifies signs and gradient ownership.
trainers.DeepAdversarialMetricLearning Explicit metric, classifier, and adversarial objectives Adversarial recipe.
trainers.MetricLossOnly Compute embeddings, call the loss, then backward and step Metric training recipe.
trainers.TrainWithClassifier Add classifier and metric objectives in caller code Classifier recipe.
trainers.TwoStreamMetricLoss Pass explicit query and reference embeddings to the loss Two-stream recipe.
TripletMarginLoss() with margin=0.05 TripletMarginLoss(margin=0.05) The default is 0.2, matching TripletMarginMiner.
TripletMarginMiner.set_stats Diagnostics computed from returned indices No stored miner statistics remain.
TupletMarginLoss.set_stats Compute diagnostics in caller code The loss returns the objective without statistics side effects.
utils.accuracy_calculator evaluation from pytorch_metric_learning.evaluation import AccuracyCalculator.
utils.common_functions Removed from the public API Helpers used by the library are private; the rows below name replacements.
utils.common_functions.add_to_recordable_attributes Application diagnostics or forward hooks The record-keeper attribute registry was removed.
utils.common_functions.append_map A Python comprehension or map Apply the application's transformation directly.
utils.common_functions.assert_distance_type An isinstance check on self.distance in your module The library's distance checks are private; see custom losses.
utils.common_functions.COLLECT_STATS Application diagnostics No global statistics flag remains.
utils.common_functions.delete_dict_of_models pathlib.Path.unlink on chosen checkpoint files The application owns retention rules.
utils.common_functions.EmbeddingDataset torch.utils.data.TensorDataset(embeddings, labels) DataLoader returns the paired tensors.
utils.common_functions.exclude A Python comprehension Make the filtering rule explicit.
utils.common_functions.get_eval_dataloader torch.utils.data.DataLoader Choose evaluation batching and ordering explicitly.
utils.common_functions.get_hierarchy_label Select the desired label column explicitly For a label matrix, use labels[:, level].
utils.common_functions.get_label_map Construct one mapping per hierarchy level The library no longer owns dataset metadata.
utils.common_functions.get_labels_to_indices Group indices with label comparisons For label c, use (labels == c).nonzero(as_tuple=True)[0].
utils.common_functions.get_train_dataloader torch.utils.data.DataLoader Pass a sampler or batch sampler according to its PyTorch contract.
utils.common_functions.is_list_or_tuple isinstance(value, (list, tuple)) Use Python directly.
utils.common_functions.LabelMapper Application-owned label mapping Do not build independent query/reference encodings.
utils.common_functions.latest_version Application checkpoint selection Select naming, best-model, and resume rules explicitly.
utils.common_functions.list_of_recordable_attributes_list_names Application-owned metric names The recordable-attribute lists were removed.
utils.common_functions.load_dict_of_models Load each state dictionary explicitly The application owns missing-key and resume policy.
utils.common_functions.load_model model.load_state_dict(torch.load(path, map_location=device, weights_only=True)) Handle legacy key conversions explicitly outside the library.
utils.common_functions.LOGGER logging.getLogger("pytorch_metric_learning") Application logging setup.
utils.common_functions.LOGGER_NAME The standard pytorch_metric_learning logger namespace Individual modules use their own module names.
utils.common_functions.make_label_to_rank_dict {label: i for i, label in enumerate(sorted(unique_labels))} Persist the mapping if later data must use it.
utils.common_functions.map_labels Application-owned label mapping Share one mapping across evaluated splits.
utils.common_functions.modelpath_creator pathlib.Path and application naming rules The application owns checkpoint paths.
utils.common_functions.NUMPY_RANDOM A torch.Generator passed to a sampler Seeded sequences differ from version 2.
utils.common_functions.numpy_to_torch torch.as_tensor(array) Specify device and dtype when needed.
utils.common_functions.operate_on_dict_of_models Iterate over the application's model dictionary No generic checkpoint-operation dispatcher remains.
utils.common_functions.process_label Select the label column and apply the application mapping Hierarchy handling is explicit.
utils.common_functions.regex_replace re.sub Apply replacement rules explicitly.
utils.common_functions.regex_wrapper Python's re module No library wrapper remains.
utils.common_functions.reset_stats Reset application-owned accumulators Modules no longer retain statistics.
utils.common_functions.return_input Return the value directly Use torch.nn.Identity when a module is required.
utils.common_functions.safe_random_choice torch.randperm or torch.randint Select without or with replacement explicitly.
utils.common_functions.save_dict_of_models Save a dictionary of model state_dict() values Include optimizer and schedule state when resuming training.
utils.common_functions.save_model torch.save(model.state_dict(), path) For a DDP-wrapped model, save the underlying model.module state.
utils.common_functions.set_layers_to_eval Call .eval() on explicitly selected modules Select modules by reference or type, not class-name substrings.
utils.common_functions.set_logger_name Configure Python logging handlers and levels No library logging configuration helper remains.
utils.common_functions.set_requires_grad module.requires_grad_(enabled) Manage optimizer membership and model mode separately.
utils.common_functions.shift_indices_tuple Offset reference indices explicitly For triplets shift positive/negative indices; for pairs shift their second/fourth tensors.
utils.common_functions.sqlite_obj_to_dict Application database handling SQLite/record-keeper integration was removed.
utils.common_functions.to_device tensor.to(device=device, dtype=dtype) Omit dtype to preserve it.
utils.common_functions.to_dtype tensor.to(dtype=dtype) Explicit conversions also apply inside autocast.
utils.common_functions.to_numpy tensor.detach().cpu().numpy() Omit detach() only for tensors without gradients.
utils.common_functions.torch_arange_from_size(x) torch.arange(len(x), device=x.device) Write the index tensor directly.
utils.common_functions.torch_standard_scaler Explicit centering and scaling Fit statistics on the reference/training data and reuse them for queries.
utils.common_functions.TorchInitWrapper An in-place torch.nn.init callable Bind options with functools.partial; see parameter placement.
utils.common_functions.try_next_on_generator Own the iterator and handle StopIteration Recreate the iterator when the application wants another pass.
utils.common_functions.unslice_by_n torch.stack(parts, dim=1).flatten(0, 1) Interleave equal-shaped streams along the batch dimension.
utils.common_functions.use_cuda_if_available Select a torch.device in caller code Library defaults no longer choose CUDA globally.
utils.distributed distributed from pytorch_metric_learning.distributed import DistributedLossWrapper.
utils.distributed.all_gather PyTorch collectives for raw tensors; library distributed wrappers for losses/miners Distributed contracts specify gradient ownership.
utils.distributed.all_gather_embeddings_and_labels distributed.DistributedLossWrapper or distributed.DistributedMinerWrapper Use the wrappers to preserve their batch, label, and gradient contracts.
utils.inference.add_to_index_and_search FaissKNN(...) calls, or FaissKNN.search(index, query, reference, k) The helper is private.
utils.inference.convert_to_cpu_index FaissKNN.to_cpu_index(index) Use the backend instance that owns the index.
utils.inference.convert_to_gpu_index FaissKNN.to_gpu_index(index) Configure the backend's gpus in its constructor.
utils.inference.CustomKNN evaluation.CustomKNN Exact PyTorch search; no Faiss dependency.
utils.inference.FaissKMeans evaluation.FaissKMeans Install [faiss]; pass this backend explicitly for clustering metrics.
utils.inference.FaissKNN evaluation.FaissKNN Install [faiss] explicitly.
utils.inference.InferenceModel Extract embeddings in caller code, then use evaluation Evaluation recipe; preprocessing and model mode belong to the application.
utils.inference.MatchFinder evaluation.MatchFinder Supply a threshold in the constructor or call.
utils.inference.return_results The FaissKNN or CustomKNN result Both return results with self-matches already removed when the query is in the reference set.
utils.inference.run_pca Application-owned PCA, such as torch.pca_lowrank Center and project query/reference embeddings with the same fitted basis.
utils.inference.try_gpu FaissKNN.search(index, query, reference, k) Backend selection belongs to the backend.
utils.key_checker.default_important Application validation rules This trainer-schema callback was removed.
utils.key_checker.KeyChecker Explicit application argument validation Trainer key schemas were removed.
utils.key_checker.KeyCheckerDict Ordinary dictionaries and explicit validation No trainer schema container remains.
utils.logging_presets.EmptyContainer Omit callbacks that are not needed No no-op hook container is required.
utils.logging_presets.get_hook_container Application callbacks See the training recipes.
utils.logging_presets.get_record_keeper Configure the application's chosen logger record-keeper is no longer a dependency.
utils.logging_presets.HookContainer Application callbacks and logging The library no longer owns training events.
utils.loss_and_miner_utils utils.indexing Public pair, triplet, and weight utilities accept plain or named index tuples; internals are private.
utils.loss_and_miner_utils.convert_to_triplets default t_per_anchor=100 utils.indexing.convert_to_triplets(..., t_per_anchor=100) The default is now every triplet.
utils.loss_and_miner_utils.get_all_triplets_indices_loop_method utils.indexing.get_all_triplets_indices(labels, ref_labels) The implementation bounds intermediate memory automatically.
utils.loss_and_miner_utils.get_all_triplets_indices_vectorized_method utils.indexing.get_all_triplets_indices(labels, ref_labels) Call the label-based API instead of choosing an enumeration implementation.
utils.loss_and_miner_utils.get_random_triplet_indices(t_per_anchor=None) utils.indexing.get_random_triplet_indices(t_per_anchor=None) Vectorized sampling; None draws one triplet per positive of each anchor.
utils.loss_and_miner_utils.matched_size_indices Choose positive/negative pairing in caller code There is no automatic repetition helper.
utils.loss_and_miner_utils.remove_self_comparisons(indices, idx, ref_size) CrossBatchMemory, or filter with positives != curr_batch_idx[anchors] CrossBatchMemory excludes each anchor's queued copy before mining.
utils.loss_and_miner_utils.repeat_to_match_size tensor.repeat(repeats)[:size] when repetition is intended Handle empty inputs explicitly; repeated entries change weighting.
utils.loss_tracker.LossTracker Retain returned loss values in caller code Detach values intended only for logging.
utils.module_with_records.ModuleWithRecords torch.nn.Module Statistics registration was removed.
utils.module_with_records_and_reducer.ModuleWithRecordsAndDistance torch.nn.Module with a keyword-only distance option BaseMiner declares distance directly.
utils.module_with_records_and_reducer.ModuleWithRecordsAndReducer torch.nn.Module with a keyword-only reducer option BaseRegularizer declares distance and reducer directly.
utils.module_with_records_and_reducer.ModuleWithRecordsReducerAndDistance BaseMetricLossFunction keyword-only options See loss options; no composition mixins remain.
utils.retrieval evaluation CustomKNN, FaissKNN, FaissKMeans, and MatchFinder are exported by evaluation.
VICRegLoss with a one-row batch A batch of at least 2 rows Returned NaN; now raises ValueError.
VICRegLoss(...)(embeddings, ref_emb=ref_emb) with reducer or distance VICRegLoss(...)(embeddings, ref_emb) A plain module without loss options; the value is unchanged.
ZeroMeanRegularizer.compute_loss(embeddings=...) compute_loss(x=...) Positional calls are unchanged.

Examples

Explicit query and reference evaluation

import torch
from pytorch_metric_learning.evaluation import AccuracyCalculator

reference = torch.tensor([[0.0, 0.0], [0.1, 0.0], [3.0, 0.0], [3.1, 0.0]])
reference_labels = torch.tensor([0, 0, 1, 1])
query = torch.tensor([[0.05, 0.0], [3.05, 0.0]])
query_labels = torch.tensor([0, 1])
calculator = AccuracyCalculator(include=("precision_at_1",), k=10)
metrics = calculator.get_accuracy(query, query_labels, reference, reference_labels)
assert metrics["precision_at_1"] == 1.0

Loss parameter placement

from functools import partial
from itertools import chain

import torch
from pytorch_metric_learning import losses, regularizers

torch.manual_seed(7)
model = torch.nn.Linear(4, 3).to(dtype=torch.float64)
loss_func = losses.ProxyNCALoss(
    num_classes=2,
    embedding_size=3,
    weight_regularizer=regularizers.LpRegularizer(),
    weight_reg_weight=0.01,
    weight_init_func=partial(torch.nn.init.normal_, std=0.1),
).to(dtype=torch.float64)
optimizer = torch.optim.SGD(chain(model.parameters(), loss_func.parameters()), lr=0.01)
inputs = torch.randn(4, 4, dtype=torch.float64)
labels = torch.tensor([0, 0, 1, 1])
optimizer.zero_grad(set_to_none=True)
loss = loss_func(model(inputs), labels)
loss.backward()
assert torch.isfinite(loss)
assert torch.isfinite(model.weight.grad).all()
assert torch.isfinite(next(loss_func.parameters()).grad).all()
optimizer.step()

Consecutively packed triplets

import torch
from pytorch_metric_learning import losses

embeddings = torch.tensor(
    [[1.0, 0.0], [0.9, 0.1], [0.0, 1.0], [0.0, 1.0], [0.1, 0.9], [1.0, 0.0]],
    requires_grad=True,
)
labels = torch.tensor([0, 0, 1, 1, 1, 0])
indices_tuple = (
    torch.arange(len(embeddings), device=embeddings.device).reshape(-1, 3).unbind(1)
)
loss = losses.TripletMarginLoss(margin=1.4)(embeddings, labels, indices_tuple)
loss.backward()
assert loss > 0
assert torch.isfinite(embeddings.grad).all()

Per-call cascade candidates

import torch
from pytorch_metric_learning import miners
from pytorch_metric_learning.utils import indexing

embeddings = torch.tensor([[1.0, 0.0], [0.8, 0.2], [0.0, 1.0], [0.2, 0.8]])
labels = torch.tensor([0, 0, 1, 1])
candidates = indexing.get_all_pairs_indices(labels)
miner = miners.HDCMiner(filter_percentage=0.5)
pairs = miner(embeddings, labels, indices_tuple=candidates)
assert len(pairs[0]) == 2
assert len(pairs[2]) == 4
assert torch.equal(labels[pairs[0]], labels[pairs[1]])
assert torch.all(labels[pairs[2]] != labels[pairs[3]])

Batched distance blocks

import torch
from pytorch_metric_learning import distances

query = torch.tensor([[0.0, 0.0], [1.0, 0.0], [0.0, 2.0]])
reference = torch.tensor([[0.0, 1.0], [2.0, 0.0]])
output = query.new_empty(len(query), len(reference))

distance = distances.BatchedDistance(
    distances.LpDistance(normalize_embeddings=False), batch_size=2
)
for matrix, start, end in distance(query, reference):
    output[start:end] = matrix
expected = query.new_tensor([[1.0, 2.0], [2**0.5, 1.0], [1.0, 8**0.5]])
torch.testing.assert_close(output, expected)