Here is another type of  error calculation and this seems to work fine:
def error(preds, targets):
    assert preds.size() == targets.size()
    bs, d, h, w = preds.size()
    n_pixels = bs*d*h*w
    
    incorrect = preds.ne(targets).cpu().sum()       
    # Divide the number of incorrectly classified pixel by the number of all pixels.
    err = incorrect.numpy()/n_pixels           
    # return err
    return round(err, 5)

This is returning an error value that seems to be working.
Isnt this doing the same thing as the dot operation in the IoU function?