EasyLoss Functions

Cosine Embedding Loss

Loss Functions

Easy

Problem

Cosine embedding loss measures whether two vectors are similar or dissimilar based on a label. It is commonly used in metric learning and siamese networks to learn embeddings where similar items are close and dissimilar items are far apart in cosine space.

Given two vectors, a label (+1 for similar, -1 for dissimilar), and a margin, compute the cosine embedding loss.

Formula

First compute the cosine similarity:

\cos(x_1, x_2) = \frac{x_1 \cdot x_2}{\|x_1\| \cdot \|x_2\|}

Then compute the loss based on the label:

L = 1 - \cos(x_1, x_2) \quad \text{if label} = 1

L = \max(0, \cos(x_1, x_2) - \text{margin}) \quad \text{if label} = -1

Return the cosine embedding loss as a float.

Theory

Cosine similarity measures the angle between two vectors:

\cos(\theta) = \frac{a \cdot b}{||a|| \cdot ||b||}

Where:

Range:


Cosine Embedding Loss

Cosine embedding loss trains embeddings using cosine similarity instead of Euclidean distance:

L = \begin{cases} 1 - \cos(e_1, e_2) & \text{if } y = 1 \\ \max(0, \cos(e_1, e_2) - m) & \text{if } y = -1 \end{cases}

Where:

Note: the label convention (y \in \{-1, 1\}) differs from standard contrastive loss.


Breaking Down the Two Cases

Case 1: Similar pair (y = 1)

L = 1 - \cos(e_1, e_2)

Case 2: Dissimilar pair (y = -1)

L = \max(0, \cos(e_1, e_2) - m)


The Role of the Margin

The margin m sets the threshold for dissimilar pairs:

m = 0:

m = 0.5:

m = -0.5:

Common choice: m = 0 or m = 0.1


Numerical Examples

Example 1: Similar pair, aligned

Example 2: Similar pair, orthogonal

Example 3: Dissimilar pair, similar direction (with m = 0)

Example 4: Dissimilar pair, opposite direction (with m = 0)


Cosine vs. Euclidean Distance

Euclidean distance (L2):

Cosine similarity:

When to use cosine:

When to use Euclidean:


Relationship to L2 Distance

For L2-normalized vectors (unit vectors on hypersphere):

||e_1 - e_2||_2^2 = 2(1 - \cos(e_1, e_2))

This means:


The Gradient

For similar pairs (y = 1):

\frac{\partial L}{\partial e_1} = -\frac{e_2 - (e_1 \cdot e_2) e_1 / ||e_1||^2}{||e_1|| \cdot ||e_2||}

This points in the direction that increases cosine similarity.

For dissimilar pairs (y = -1) when \cos > m:

\frac{\partial L}{\partial e_1} = \frac{e_2 - (e_1 \cdot e_2) e_1 / ||e_1||^2}{||e_1|| \cdot ||e_2||}

This points in the direction that decreases cosine similarity.


Implementation Notes

Normalization:

Numerical stability:

Temperature scaling:


Where Cosine Embedding Loss Is Used

Examples

Example 1

Input
x1 = [1, 0, 0], x2 = [1, 0, 0], label = 1, margin = 0
Output
0.0
Explanation
Identical vectors have cosine similarity 1, so the similar-pair loss is 0.

Example 2

Input
x1 = [1, 0, 0], x2 = [0, 1, 0], label = 1, margin = 0
Output
1.0

Hints

  1. Use zip with sum to compute the dot product and each squared norm.
  2. Choose the loss branch from label after computing cosine similarity.

Requirements

Constraints

Starter Code

import math

def cosine_embedding_loss(x1: list, x2: list, label: int, margin: float) -> float:
    """
    Returns the cosine embedding loss as a float.
    """
    # Write code here
    pass

Test Cases

CaseMatches
Same direction, positivepublic
Orthogonal, positivepublic