ShiftedBronzes / OpenOOD /openood /postprocessors /rotpred_postprocessor.py
AnonymousUser20's picture
Upload 1314 files
178d33b verified
Raw
History Blame Contribute Delete
2.01 kB
from typing import Any
import torch
import torch.nn as nn
import torch.nn.functional as F
from .base_postprocessor import BasePostprocessor
def kl_div(d1, d2):
"""Compute KL-Divergence between d1 and d2."""
dirty_logs = d1 * torch.log2(d1 / d2)
return torch.sum(torch.where(d1 != 0, dirty_logs, torch.zeros_like(d1)),
axis=1)
class RotPredPostprocessor(BasePostprocessor):
def __init__(self, config):
super(RotPredPostprocessor, self).__init__(config)
self.config = config
@torch.no_grad()
def postprocess(self, net: nn.Module, data: Any):
batch_size = len(data)
x_90 = torch.rot90(data, 1, [2, 3])
x_180 = torch.rot90(data, 2, [2, 3])
x_270 = torch.rot90(data, 3, [2, 3])
x_rot = torch.cat([data, x_90, x_180, x_270])
y_rot = torch.cat([
torch.zeros(batch_size),
torch.ones(batch_size),
2 * torch.ones(batch_size),
3 * torch.ones(batch_size),
]).long().cuda()
logits, logits_rot = net(x_rot, return_rot_logits=True)
logits = logits[:batch_size]
preds = logits.argmax(1)
# https://github.com/hendrycks/ss-ood/blob/8051356592a152614ab7251fd15084dd86eb9104/multiclass_ood/test_auxiliary_ood.py#L177-L208
num_classes = logits.shape[1]
uniform_dist = torch.ones_like(logits) / num_classes
cls_loss = kl_div(uniform_dist, F.softmax(logits, dim=1))
rot_one_hot = torch.zeros_like(logits_rot).scatter_(
1,
y_rot.unsqueeze(1).cuda(), 1)
rot_loss = kl_div(rot_one_hot, F.softmax(logits_rot, dim=1))
rot_0_loss, rot_90_loss, rot_180_loss, rot_270_loss = torch.chunk(
rot_loss, 4, dim=0)
total_rot_loss = (rot_0_loss + rot_90_loss + rot_180_loss +
rot_270_loss) / 4.0
# here ID samples will yield larger scores
scores = cls_loss - total_rot_loss
return preds, scores