3

I found a code snippet, which is a custom metric for tensorboard (pytorch training)

def specificity(output, target, t=0.5):
    
    tp, tn, fp, fn = tp_tn_fp_fn(output, target, t)

    if fp == 0:
        return 1
    s = tn / (tn + fp)

    if s != s:
        s = 1

    return s

def tp_tn_fp_fn(output, target, t):
    with torch.no_grad():
        preds = output > t  # torch.argmax(output, dim=1)
        preds = preds.long()
        num_true_neg = torch.sum((preds == target) & (target == 0), dtype=torch.float).item()
        num_true_pos = torch.sum((preds == target) & (target == 1), dtype=torch.float).item()
        num_false_pos = torch.sum((preds != target) & (target == 1), dtype=torch.float).item()
        num_false_neg = torch.sum((preds != target) & (target == 0), dtype=torch.float).item()

    return num_true_pos, num_true_neg, num_false_pos, num_false_neg

In terms of the calculation itself it is easy enough to understand.

What I don't understand is s != s. What does that check do, how can the two s even be different?

PrimuS
  • 2,505
  • 6
  • 33
  • 66
  • 1
    It is a way to handle division by 0. It is true with NaN. Check `np.nan != np.nan` for instance. – Remi Cuingnet Jan 25 '23 at 11:07
  • When `s` is `NaN`, proabably? – Tom Lord Jan 25 '23 at 11:07
  • A bit more about `NaN`s: https://stackoverflow.com/a/944712/9288580 – Nikolaj Š. Jan 25 '23 at 11:11
  • 2
    NaN is not the result of every division by zero; according to the IEEE 754 spec for floating-point arithmetic, `x / 0.0` will be positive or negative infinity when `x` is not also zero, but `0.0 / 0.0` is NaN. However, in this case `0.0 / 0.0` is impossible because `fp` is not zero, so if the numerator is zero then the denominator can't be. However, a NaN can still occur from dividing one infinity by another. Also worth noting that in Python particularly, `0.0 / 0.0` with the built-in `float` type will not give NaN, it will raise an error. – kaya3 Jan 25 '23 at 11:11
  • 1
    This is in my opinion bad code. If it's `NaN` values what it's meant to check, there are proper methods that do this verification which will make the code readable. The only way `s` can be NaN is if `tn == 0` so that check can be done before: `if fp == 0 or tn == 0: return 1` – Sembei Norimaki Jan 25 '23 at 11:11

1 Answers1

2

Since it's ML-related, I'll assume the data are all numbers. The only number where s != s is true is the special not-a-number value nan. Any comparison with nan is always false, so from that follows that nan is not equal to itself.

Simon Lundberg
  • 1,413
  • 2
  • 11
  • 23