Skip to content
Back to skills

Lovasz Hinge Loss

ASecurity

Lovasz hinge loss that directly optimizes IoU for binary segmentation by computing a convex surrogate via sorted prediction errors and cumulative Jaccard gradients.

  • 61 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 12, 2026
datapythongit

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add wenmin-wu/ds-skills --skill lovasz-hinge-loss --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Lovasz Hinge Loss?

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

Security grade badge for Lovasz Hinge Loss
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/wenmin-wu-lovasz-hinge-loss/badge)](https://www.skillsdirectory.com/skills/wenmin-wu-lovasz-hinge-loss)

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-lovasz-hinge-loss
description: >
  Lovasz hinge loss that directly optimizes IoU for binary segmentation by computing a convex surrogate via sorted prediction errors and cumulative Jaccard gradients.
---
# Lovasz Hinge Loss

## Overview

Standard losses (BCE, Dice) are proxies for IoU — they correlate with it but don't optimize it directly. Lovasz hinge loss computes the exact subgradient of the Jaccard index by sorting prediction errors, computing cumulative intersection/union, and using the Lovasz extension of submodular functions. This makes it a tight convex surrogate for 1-IoU. In practice, it consistently outperforms BCE and Dice on IoU-based metrics by 1-3%, especially when mask shapes are irregular or class distributions are skewed.

## Quick Start

```python
import torch
import torch.nn.functional as F

def lovasz_grad(gt_sorted):
    p = len(gt_sorted)
    gts = gt_sorted.sum()
    intersection = gts - gt_sorted.float().cumsum(0)
    union = gts + (1 - gt_sorted).float().cumsum(0)
    jaccard = 1.0 - intersection / union
    if p > 1:
        jaccard[1:p] = jaccard[1:p] - jaccard[0:-1]
    return jaccard

def lovasz_hinge_flat(logits, labels):
    signs = 2.0 * labels.float() - 1.0
    errors = 1.0 - logits * signs
    errors_sorted, perm = torch.sort(errors, dim=0, descending=True)
    gt_sorted = labels[perm.data]
    grad = lovasz_grad(gt_sorted)
    return torch.dot(F.relu(errors_sorted), grad)

# Usage: pass raw logits (before sigmoid)
loss = lovasz_hinge_flat(logits.view(-1), masks.view(-1))
```

## Workflow

1. Compute signed errors: `1 - logit * sign(label)`
2. Sort errors in descending order
3. Compute cumulative Jaccard gradients via `lovasz_grad`
4. Dot product of ReLU'd errors with gradients gives the loss
5. Operates on raw logits — do NOT apply sigmoid first

## Key Decisions

- **Input**: Raw logits, not probabilities — the hinge formulation needs unbounded values
- **Per-image vs batch**: Compute per-image then average for stable gradients
- **Warm-up**: Train with BCE for first few epochs, then switch to Lovasz for fine-tuning
- **Multi-class**: Use `lovasz_softmax` variant for multi-class segmentation

## References

- [Loss Function Library - Keras & PyTorch](https://www.kaggle.com/code/bigironsphere/loss-function-library-keras-pytorch)

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…