| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| """ Calculate Inception Moments |
| This script iterates over the dataset and calculates the moments of the |
| activations of the Inception net (needed for FID), and also returns |
| the Inception Score of the training data. |
| |
| Note that if you don't shuffle the data, the IS of true data will be under- |
| estimated as it is label-ordered. By default, the data is not shuffled |
| so as to reduce non-determinism. """ |
| import os |
| import numpy as np |
| import torch |
| import torch.nn as nn |
| import torch.nn.functional as F |
|
|
| import sys |
|
|
| sys.path.insert(1, os.path.join(sys.path[0], "..")) |
| import data_utils.utils as utils |
| import data_utils.inception_utils as inception_utils |
| from tqdm import tqdm |
| from argparse import ArgumentParser |
|
|
|
|
| def prepare_parser(): |
| usage = "Calculate and store inception metrics." |
| parser = ArgumentParser(description=usage) |
| parser.add_argument( |
| "--resolution", |
| type=int, |
| default=128, |
| help="Which Dataset resolution, out of 64, 128, 256" " (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--split", |
| type=str, |
| default="train", |
| help="Which Dataset to convert: train, val (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--stratified_moments", |
| action="store_true", |
| default=False, |
| help="Compute moments for FID computation stratifying by many, medium and few-shot classes" |
| " (ImageNet-LT)", |
| ) |
| parser.add_argument( |
| "--data_root", |
| type=str, |
| default="data", |
| help="Default location where data is stored and where dataset hdf5 is found" |
| " (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--out_path", |
| type=str, |
| default="data", |
| help="Default location where data in hdf5 format will be stored (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--batch_size", |
| type=int, |
| default=64, |
| help="Default overall batchsize (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--parallel", |
| action="store_true", |
| default=False, |
| help="Use multiple GPUs (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--num_workers", |
| type=int, |
| default=8, |
| help="Number of dataloader workers (default: %(default)s)", |
| ) |
| parser.add_argument( |
| "--shuffle", |
| action="store_true", |
| default=False, |
| help="Shuffle the data? (default: %(default)s)", |
| ) |
| parser.add_argument("--seed", type=int, default=0, help="Random seed to use.") |
| parser.add_argument( |
| "--load_in_mem", |
| action="store_true", |
| default=False, |
| help="Load all data into memory? (default: %(default)s)", |
| ) |
|
|
| parser.add_argument( |
| "--which_dataset", |
| type=str, |
| default="imagenet", |
| choices=["imagenet", "imagenet_lt", "coco"], |
| help="Dataset choice.", |
| ) |
|
|
| return parser |
|
|
|
|
| def run(config): |
| |
| kwargs = { |
| "num_workers": config["num_workers"], |
| "pin_memory": False, |
| "drop_last": False, |
| "load_in_mem": config["load_in_mem"], |
| } |
| if config["which_dataset"] in ["imagenet", "imagenet_lt"]: |
| dataset_name_prefix = "ILSVRC" |
| elif config["which_dataset"] == "coco": |
| dataset_name_prefix = "COCO" |
| test_part = False |
| if config["which_dataset"] == "coco" and config["split"] == "val": |
| test_part = True |
|
|
| |
| dataset = utils.get_dataset_hdf5( |
| config["resolution"], |
| data_path=config["data_root"], |
| longtail=config["which_dataset"] == "imagenet_lt" |
| and config["split"] == "train", |
| split=config["split"], |
| load_in_mem=config["load_in_mem"], |
| which_dataset=config["which_dataset"], |
| test_part=test_part, |
| ) |
|
|
| loader = utils.get_dataloader( |
| dataset, config["batch_size"], shuffle=False, **kwargs |
| ) |
|
|
| |
| net = inception_utils.load_inception_net(parallel=config["parallel"]) |
| device = "cuda" |
|
|
| |
| pool, logits, labels = [], [], [] |
| for i, batch in enumerate(tqdm(loader)): |
| (x, y) = (batch[0], batch[1]) |
| x = x.to(device) |
| with torch.no_grad(): |
| pool_val, logits_val = net(x) |
| pool += [np.asarray(pool_val.cpu())] |
| logits += [np.asarray(F.softmax(logits_val, 1).cpu())] |
| labels += [np.asarray(y.cpu())] |
|
|
| pool, logits, labels = [np.concatenate(item, 0) for item in [pool, logits, labels]] |
|
|
| print("Calculating inception metrics...") |
| IS_mean, IS_std = inception_utils.calculate_inception_score(logits) |
| print( |
| "Training data from dataset %s has IS of %5.5f +/- %5.5f" |
| % (config["which_dataset"], IS_mean, IS_std) |
| ) |
| |
| |
| print("Calculating means and covariances...") |
| mu, sigma = np.mean(pool, axis=0), np.cov(pool, rowvar=False) |
| print("Saving calculated means and covariances to disk...") |
| if config["which_dataset"] in ["imagenet", "imagenet_lt"]: |
| dataset_name_prefix = "I" |
| elif config["which_dataset"] == "coco": |
| dataset_name_prefix = "COCO" |
| np.savez( |
| os.path.join( |
| config["out_path"], |
| "%s%i_%s%s%s_inception_moments.npz" |
| % ( |
| dataset_name_prefix, |
| config["resolution"], |
| "longtail" |
| if config["which_dataset"] == "imagenet_lt" |
| and config["split"] == "train" |
| else "", |
| "_val" if config["split"] == "val" else "", |
| "_test" if test_part else "", |
| ), |
| ), |
| **{"mu": mu, "sigma": sigma} |
| ) |
| |
| if config["stratified_moments"]: |
| samples_per_class = np.load( |
| "BigGAN_PyTorch/imagenet_lt/imagenet_lt_samples_per_class.npy", |
| allow_pickle=True, |
| ) |
| for strat_name in ["_many", "_low", "_few"]: |
| if strat_name == "_many": |
| logits_ = logits[samples_per_class[labels] >= 100] |
| pool_ = pool[samples_per_class[labels] >= 100] |
| elif strat_name == "_low": |
| logits_ = logits[samples_per_class[labels] < 100] |
| pool_ = pool[samples_per_class[labels] < 100] |
| labels_ = labels[samples_per_class[labels] < 100] |
| logits_ = logits_[samples_per_class[labels_] > 20] |
| pool_ = pool_[samples_per_class[labels_] > 20] |
| elif strat_name == "_few": |
| logits_ = logits[samples_per_class[labels] <= 20] |
| pool_ = pool[samples_per_class[labels] <= 20] |
| print( |
| "Calculating inception metrics for strat ", |
| strat_name, |
| " with number of samples ", |
| len(logits_), |
| "...", |
| ) |
| IS_mean, IS_std = inception_utils.calculate_inception_score(logits_) |
| print( |
| "Training data from dataset %s has IS of %5.5f +/- %5.5f" |
| % (config["which_dataset"], IS_mean, IS_std) |
| ) |
| |
| |
| print("Calculating means and covariances...") |
| mu, sigma = np.mean(pool_, axis=0), np.cov(pool_, rowvar=False) |
| print("Saving calculated means and covariances to disk...") |
| np.savez( |
| os.path.join( |
| config["data_root"], |
| "%s%i__val%s_inception_moments.npz" |
| % (dataset_name_prefix, config["resolution"], strat_name), |
| ), |
| **{"mu": mu, "sigma": sigma} |
| ) |
|
|
|
|
| def main(): |
| |
| parser = prepare_parser() |
| config = vars(parser.parse_args()) |
| print(config) |
| run(config) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|