class

TripletMarginLoss

extendsModule
TripletMarginLoss(margin: float = 1.0, p: float = 2.0, eps: float = 1e-06, swap: bool = False, reduction: str = 'mean')
source

Triplet margin loss for metric learning.

Trains an embedding such that an anchor sample is closer to a positive (same-class) sample than to a negative (different-class) sample by at least margin. Given embeddings (a,p,n)(a, p, n):

L(a,p,n)=max ⁣(d(a,p)d(a,n)+margin,  0)\mathcal{L}(a, p, n) = \max\!\bigl(d(a, p) - d(a, n) + \text{margin},\; 0\bigr)

where the distance is the LpL_p norm:

d(x,y)=xypd(x, y) = \left\| x - y \right\|_p

The swap option: if enabled, the loss also considers d(p,n)d(p, n) as an alternative negative distance and uses the smaller of d(a,n)d(a, n) and d(p,n)d(p, n).

Parameters

marginfloat= 1.0
Minimum required distance gap. Default 1.0.
pfloat= 2.0
The norm degree for the distance computation. Default 2.0 (L2).
epsfloat= 1e-06
Small value added inside the norm to avoid zero-division. Default 1e-6.
swapbool= False
If True, uses the triangle-inequality-based swap. Default False.
reductionstr= 'mean'
'none' | 'mean' (default) | 'sum'.

Attributes

marginfloat
The margin threshold.
pfloat
The norm degree.
epsfloat
Numerical stabilisation constant.
swapbool
Whether the distance swap is active.
reductionstr
The reduction mode.

Notes

  • anchor : (N,D)(N, D).
  • positive : (N,D)(N, D).
  • negative : (N,D)(N, D).
  • Output : scalar for 'mean' / 'sum'; (N,)(N,) for 'none'.
  • Used extensively in face verification, image retrieval, and few-shot learning.
  • For variable distance functions (e.g. cosine distance), see TripletMarginWithDistanceLoss.
  • Choosing margin depends on the scale of the embedding space; 0.2 to 1.0 is typical for L2-normalised embeddings.

Examples

Basic triplet training step:
>>> import lucid
>>> import lucid.nn as nn
>>> criterion = nn.TripletMarginLoss(margin=1.0)
>>> anchor   = lucid.tensor([[1.0, 2.0, 3.0]])
>>> positive = lucid.tensor([[1.1, 2.1, 3.1]])
>>> negative = lucid.tensor([[5.0, 6.0, 7.0]])
>>> loss = criterion(anchor, positive, negative)
With L1 distance and larger margin:
>>> import lucid
>>> import lucid.nn as nn
>>> criterion = nn.TripletMarginLoss(margin=2.0, p=1.0)
>>> anchor   = lucid.tensor([[0.0, 0.0]])
>>> positive = lucid.tensor([[0.2, 0.2]])
>>> negative = lucid.tensor([[3.0, 3.0]])
>>> loss = criterion(anchor, positive, negative)

Methods (3)

dunder

__init__

None
__init__(margin: float = 1.0, p: float = 2.0, eps: float = 1e-06, swap: bool = False, reduction: str = 'mean')
source

Initialise the TripletMarginLoss module. See the class docstring for parameter semantics.

fn

forward

Tensor
forward(anchor: Tensor, positive: Tensor, negative: Tensor)
source

Compute the loss between predictions and targets.

Parameters

anchorTensor
Input tensor.
positiveTensor
Input tensor.
negativeTensor
Input tensor.

Returns

Tensor

Scalar loss (or unreduced tensor depending on reduction).

fn

extra_repr

str
extra_repr()
source

Return a string representation of the layer's configuration.