Implementing contrastive loss and triplet loss in Tensorflow
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.
Introduction
Contrastive loss and triplet loss are standard tools in metric learning. Instead of predicting a class directly, the model learns an embedding space where similar examples land close together and dissimilar examples land farther apart. In TensorFlow, the core implementation is straightforward once the model emits embeddings and you define the right pairwise distance calculation.
Build an Embedding Model First
Both losses operate on embeddings, not raw logits. A simple Keras model can map each input into a low-dimensional vector and normalize it so distance calculations stay stable.
L2 normalization is common because it keeps embedding magnitudes under control and makes distance comparisons easier to interpret.
Contrastive Loss Works on Pairs
For contrastive loss, each training example is a pair of inputs plus a binary label:
- '
1means the pair should be close' - '
0means the pair should be at least a margin apart'
You can wrap that around a Siamese model:
Training then uses pair labels and the custom loss.
Triplet Loss Works on Anchor, Positive, and Negative
Triplet loss uses three inputs:
- an anchor example
- a positive example from the same class
- a negative example from a different class
The goal is to make the anchor closer to the positive than to the negative by at least a margin.
A triplet model can share the same encoder across all three inputs:
This setup is often trained with a custom train_step because the loss depends on multiple outputs at once.
Example Custom Training Step
This is a clean way to keep the training loop close to the mathematics of the triplet objective.
Common Pitfalls
The biggest mistake is feeding raw class labels into contrastive or triplet code without building the required pair or triplet sampling pipeline. These losses depend heavily on how examples are grouped.
Another issue is skipping embedding normalization and then struggling with unstable distance scales. The model can still train without normalization, but the geometry is harder to control.
Margin choice is another source of problems. If the margin is too small, the model may learn weak separation. If it is too large, optimization can become unnecessarily hard.
Finally, data mining matters. Easy pairs and easy triplets quickly stop providing useful gradients. In real systems, careful sampling or hard-negative mining often matters as much as the loss formula itself.
Summary
- Contrastive loss learns from labeled pairs, while triplet loss learns from anchor-positive-negative triples.
- Both losses require an encoder that outputs embeddings rather than class logits.
- L2-normalized embeddings are a common and practical choice.
- In TensorFlow, the loss formulas are short; building the right data pipeline is the harder part.
- Margin selection and triplet or pair sampling strongly affect training quality.
Related reading
- Implementing custom loss function in keras with condition
- Implementing custom loss function in keras with different sizes for y_true and y_pred
- Implementing dropout from scratch
- Implementing Feedback Alignment in Tensorflow
- Implementing high-pass filter in tensorflow
- Implementing im2col in TensorFlow
- Implementing custom loss function in scikit learn
- Implementing Gradient Boosted Regression Trees in production - mathematically describing the learned model
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
ML System Design practice on Codemia
Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.