Files
microsoft--unilm/LatentLM/metrics/IS.py
T
2026-07-13 13:24:13 +08:00

100 lines
3.8 KiB
Python

"""Utils for Inception Score calculation.
Borrowed from:
PyTorch StudioGAN: https://github.com/POSTECH-CVLab/PyTorch-StudioGAN
The MIT License (MIT)
See license file or visit https://github.com/POSTECH-CVLab/PyTorch-StudioGAN for details
"""
from pathlib import Path
import torch
from torch.utils.data import DataLoader
from tqdm import tqdm
from .fid import get_inception_model, create_dataset_from_files
def inception_softmax(inception_model, images):
with torch.no_grad():
logits = inception_model.get_logits(images)
ps = torch.nn.functional.softmax(logits, dim=1)
return ps
@torch.no_grad()
def calculate_kl_div(ps, splits: int):
scores = []
num_samples = ps.shape[0]
for j in range(splits):
part = ps[(j * num_samples // splits):((j + 1) * num_samples // splits), :]
kl = part * (torch.log(part) - torch.log(torch.unsqueeze(torch.mean(part, 0), 0)))
kl = torch.mean(torch.sum(kl, 1))
kl = torch.exp(kl)
scores.append(kl.unsqueeze(0))
scores = torch.cat(scores, 0)
m_scores = torch.mean(scores).detach().cpu().numpy()
m_std = torch.std(scores).detach().cpu().numpy()
return m_scores, m_std
@torch.no_grad()
def compute_inception_score_from_dataset(dataset,
splits,
batch_size,
device=torch.device('cuda'),
inception_model=None,
disable_tqdm=False):
"""
Args:
- dataset: dataset returning **float (0~1)** images
"""
if inception_model is None:
inception_model = get_inception_model().to(device)
data_loader = DataLoader(dataset, shuffle=True, batch_size=batch_size, num_workers=16)
inception_model.eval()
probs_list = []
for imgs in tqdm(data_loader, disable=disable_tqdm):
imgs = imgs[0].to(device)
logits = inception_model.get_logits(imgs)
probs = torch.nn.functional.softmax(logits, dim=-1)
probs_list.append(probs)
probs_list = torch.cat(probs_list, 0)
m_scores, m_std = calculate_kl_div(probs_list, splits=splits)
return m_scores, m_std
def compute_inception_score_from_files(path,
splits=10,
batch_size=500,
device=torch.device('cuda'),
inception_model=None,
disable_tqdm=False):
dataset = create_dataset_from_files(path)
return compute_inception_score_from_dataset(dataset,
splits,
batch_size,
device,
inception_model,
disable_tqdm)
def compute_inception_score_from_tensor(tensor,
splits=10,
batch_size=500,
device=torch.device('cuda'),
inception_model=None,
disable_tqdm=False):
dataset = torch.utils.data.TensorDataset(tensor)
return compute_inception_score_from_dataset(dataset,
splits,
batch_size,
device,
inception_model,
disable_tqdm)