Skip to content
Back to skills

Lap Hard Negative Mining

ASecurity

Use linear assignment problem (LAP/lapjv) on a score matrix to select globally optimal hard-negative pairs for metric learning

  • 61 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
ai-agentspythongoc++

Security analysis

A92/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill lap-hard-negative-mining --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lap Hard Negative Mining?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Lap Hard Negative Mining
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-lap-hard-negative-mining/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-lap-hard-negative-mining)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cv-lap-hard-negative-mining
description: Use linear assignment problem (LAP/lapjv) on a score matrix to select globally optimal hard-negative pairs for metric learning
---

# LAP Hard Negative Mining

## Overview

In metric learning, hard negatives (close but different-class examples) drive the most learning. Random negatives are too easy; per-anchor hardest negatives cause collapse. LAP (linear assignment problem) via the Jonker-Volgenant algorithm finds a globally optimal one-to-one assignment that maximizes overall difficulty across the entire batch, avoiding degenerate pairings.

## Quick Start

```python
import numpy as np
from lap import lapjv

def mine_hard_negatives(score_matrix, labels, t2i):
    cost = -score_matrix.copy()
    # Block same-class pairs with high cost
    for cls_indices in labels.values():
        idxs = [t2i[t] for t in cls_indices]
        for i in idxs:
            for j in idxs:
                cost[i, j] = 10000.0

    _, _, col_assignment = lapjv(cost)
    hard_pairs = []
    for j, i in enumerate(col_assignment):
        hard_pairs.append((i, j))
        cost[i, j] = 10000.0
        cost[j, i] = 10000.0
    return hard_pairs
```

## Workflow

1. Compute pairwise similarity/score matrix from current embeddings
2. Mask same-class pairs with large cost to prevent them being selected
3. Run `lapjv` to find optimal one-to-one hard negative assignment
4. Use assigned pairs for contrastive/siamese training
5. Recompute assignments periodically as embeddings evolve

## Key Decisions

- **LAP vs random**: LAP finds globally hard negatives; random wastes training on easy pairs
- **LAP vs per-anchor hardest**: per-anchor can cause model collapse; LAP distributes difficulty
- **Recompute frequency**: every epoch or every N batches — stale assignments degrade quality
- **`lap` package**: `pip install lap` for fast C++ Jonker-Volgenant solver

## References

- [Siamese (pretrained) 0.822](https://www.kaggle.com/code/seesee/siamese-pretrained-0-822)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…