def test_multiclass_jaccard_loss(): criterion = losses.JaccardLoss(mode="multiclass", from_logits=False, eps=1e-4) # Ideal case y_pred = torch.tensor([[[1.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 1.0]]]) y_true = torch.tensor([[0, 0, 1, 1]]) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) # Worst case y_pred = torch.tensor([[[1.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 1.0]]]) y_true = torch.tensor([[1, 1, 0, 0]]) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(1.0, abs=EPS) # 1 - 1/3 case y_pred = torch.tensor([[[1.0, 0.0, 1.0, 0.0], [0.0, 1.0, 0.0, 1.0]]]) y_true = torch.tensor([[1, 1, 0, 0]]) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(1.0 - 1.0 / 3.0, abs=EPS)
def test_binary_jaccard_loss(): criterion = losses.JaccardLoss(mode="binary", from_logits=False) # Ideal case y_pred = torch.tensor([1.0]).view(1, 1, 1, 1) y_true = torch.tensor(([1])).view(1, 1, 1, 1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) y_pred = torch.tensor([1.0, 0.0, 1.0]).view(1, 1, 1, -1) y_true = torch.tensor(([1, 0, 1])).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) y_pred = torch.tensor([0.0, 0.0, 0.0]).view(1, 1, 1, -1) y_true = torch.tensor(([0, 0, 0])).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) # Worst case y_pred = torch.tensor([1.0, 1.0, 1.0]).view(1, 1, -1) y_true = torch.tensor([0, 0, 0]).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) # It returns 1. due to internal smoothing assert float(loss) == pytest.approx(1.0, abs=EPS) y_pred = torch.tensor([1.0, 0.0, 1.0]).view(1, 1, -1) y_true = torch.tensor([0, 1, 0]).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(1.0, EPS) y_pred = torch.tensor([0.0, 0.0, 0.0]).view(1, 1, -1) y_true = torch.tensor([1, 1, 1]).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(1.0, EPS)
def test_binary_jaccard_loss(): criterion = losses.JaccardLoss(mode="binary", from_logits=False, eps=1e-4) # Ideal case y_pred = torch.tensor([1.0]).view(1, 1, 1, 1) y_true = torch.tensor(([1])).view(1, 1, 1, 1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) y_pred = torch.tensor([1.0, 0.0, 1.0]).view(1, 1, 1, -1) y_true = torch.tensor(([1, 0, 1])).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) y_pred = torch.tensor([0.0, 0.0, 0.0]).view(1, 1, 1, -1) y_true = torch.tensor(([0, 0, 0])).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(0.0, abs=EPS) # Worst case y_pred = torch.tensor([1.0, 1.0, 1.0]).view(1, 1, -1) y_true = torch.tensor([0, 0, 0]).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) # It zeros loss if there is no y_true assert float(loss) == pytest.approx(0.0, abs=EPS) y_pred = torch.tensor([1.0, 0.0, 1.0]).view(1, 1, -1) y_true = torch.tensor([0, 1, 0]).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(1.0, EPS) y_pred = torch.tensor([0.0, 0.0, 0.0]).view(1, 1, -1) y_true = torch.tensor([1, 1, 1]).view(1, 1, 1, -1) loss = criterion(y_pred, y_true) assert float(loss) == pytest.approx(1.0, EPS)
def test_multilabel_jaccard_loss_reduction(): criterion = losses.JaccardLoss(mode="multilabel", reduction="none", from_logits=False, eps=1e-4) y_pred = torch.tensor([[[0.0, 1.0, 0.0, 0.0], [0.0, 1.0, 1.0, 0.0]]]) y_true = torch.tensor([[[1.0, 1.0, 0.0, 0.0], [1.0, 1.0, 0.0, 0.0]]]) loss = criterion(y_pred, y_true) assert torch.allclose(loss, torch.tensor([1 / 2, 2 / 3]), atol=EPS)