Thomas Piacentini
← Atelier

Exercice Python

CLIP symmetric contrastive loss

Texte original · anglais30 min

CLIP trains an image encoder and a text encoder together. In a batch of N pairs, image i belongs with text i and with no other text. The loss pulls the matched pairs together and pushes the other N^2 - N pairs apart. Zero-shot classification and image search both use the embeddings that this loss trains.

Task

Write three functions.

  1. similarity_logits(image_emb, text_emb, temperature) returns the N \times N logit matrix.
  2. symmetric_infonce(logits) returns the symmetric contrastive loss as a float.
  3. symmetric_infonce_grad(logits) returns the gradient of that loss with respect to the logits.

Logits. Divide each image row and each text row by its L2 norm. Call the results \hat{I} and \hat{T}. The logits are

S = \frac{\hat{I} \hat{T}^\top}{\tau}

where \tau is the temperature. Row i holds image i against every text. Column j holds text j against every image.

Loss. The target of row i and of column i is index i, the diagonal.

\mathcal{L}_{img} = -\frac{1}{N} \sum_i \log \frac{e^{S_{ii}}}{\sum_j e^{S_{ij}}}, \qquad \mathcal{L}_{txt} = -\frac{1}{N} \sum_j \log \frac{e^{S_{jj}}}{\sum_i e^{S_{ij}}}
\mathcal{L} = \frac{\mathcal{L}_{img} + \mathcal{L}_{txt}}{2}

Gradient. Return \partial \mathcal{L} / \partial S with the same shape as logits. Let R be the softmax of each row of S, and C the softmax of each column of S. The gradient of one cross-entropy is its softmax minus the one-hot target.

Input and output

Name Type Shape Meaning
image_emb float array (N, d) one image embedding in each row
text_emb float array (N, d) one text embedding in each row, row i matches image i
temperature float \tau > 0, the logits are divided by it
logits float array (N, N) a logit matrix, rows are images and columns are texts
  • similarity_logits returns a float array of shape (N, N).
  • symmetric_infonce returns a Python float.
  • symmetric_infonce_grad returns a float array of shape (N, N).

Constraints

  • 1 <= N <= 256 and 1 <= d <= 512.
  • No embedding row is all zeros.
  • 0.01 <= temperature <= 1.
  • symmetric_infonce and its gradient get any finite logits, with absolute values up to 1000. The results must stay finite.
  • Do not change the input arrays.
  • Use numpy only.

Examples

python
image_emb = np.array([[1.0, 0.0], [0.0, 2.0], [1.0, 1.0]])
text_emb = np.array([[2.0, 0.0], [1.0, 1.0], [0.0, 3.0]])
logits = similarity_logits(image_emb, text_emb, 0.5)
text
[[2.         1.41421356 0.        ]
 [0.         1.41421356 2.        ]
 [1.41421356 2.         1.41421356]]
python
symmetric_infonce(logits)
symmetric_infonce_grad(logits)
text
0.9905556060000382
[[-0.13632819  0.09873442  0.02666175]
 [ 0.02666175 -0.23459891  0.19700514]
 [ 0.09873442  0.15772852 -0.23459891]]
python
symmetric_infonce(np.zeros((4, 4)))
text
1.3862943611198906
Code et livrables 14
Ce que vous en retenez

Enregistré dans votre carnet sur cet appareil.

Sources et limites

Les repères de lecture sont déclaratifs. Les résultats de tests sont enregistrés séparément ; ils valent pour les cas exécutés.

AI Engineering from Scratch · 3f9715c · MIT

Télécharger ce fichier ↓