python实现Inception Score代码(读取自己生成的图片)

利用Inception Score衡量自己的模型生成的图片多样性

代码:

import torch
from torch import nn
from torch.nn import functional as F
import torch.utils.data
from torchvision.models.inception import inception_v3
import numpy as np
from tqdm import tqdm
from PIL import Image
import os
from scipy.stats import entropy

# we should use same mean and std for inception v3 model in training and testing process
# reference web page: https://pytorch.org/hub/pytorch_vision_inception_v3/
mean_inception = [0.485, 0.456, 0.406]
std_inception = [0.229, 0.224, 0.225]

def imread(filename):
    """
    Loads an image file into a (height, width, 3) uint8 ndarray.
    """
    return np.asarray(Image.open(filename), dtype=np.uint8)[..., :3]

def inception_score(batch_size=50, resize=True, splits=10):
    # Set up dtype
    device = torch.device("cuda:0")  # you can change the index of cuda
    # Load inception model
    inception_model = inception_v3(pretrained=True, transform_input=False).to(device)
    inception_model.eval()
    up = nn.Upsample(size=(299, 299), mode='bilinear', align_corners=False).to(device)
    
    def get_pred(x):
        if resize:
            x = up(x)
        x = inception_model(x)
        return F.softmax(x, dim=1).data.cpu().numpy()

    # Get predictions using pre-trained inception_v3 model
    print('Computing predictions using inception v3 model')
    

    files = readDir()
    N = len(files)
    preds = np.zeros((N, 1000))
    if batch_size > N:
        print(('Warning: batch size is bigger than the data size. '
                 'Setting batch size to data size'))

    for i in tqdm(range(0, N, batch_size)):
        start = i
        end = i + batch_size
        images = np.array([imread(str(f)).astype(np.float32)
                           for f in files[start:end]])

        # Reshape to (n_images, 3, height, width)
        images = images.transpose((0, 3, 1, 2))
        images /= 255

        batch = torch.from_numpy(images).type(torch.FloatTensor)
        batch = batch.to(device)
        y = get_pred(batch)
        print(y.shape)
        preds[i :i  + batch_size] = get_pred(batch)
        

    assert batch_size > 0
    assert N > batch_size

    # Now compute the mean KL Divergence
    print('Computing KL Divergence')
    split_scores = []
    for k in range(splits):
        part = preds[k * (N // splits): (k + 1) * (N // splits), :] # split the whole data into several parts
        py = np.mean(part, axis=0)  # marginal probability
        scores = []
        for i in range(part.shape[0]):
            pyx = part[i, :]  # conditional probability
            scores.append(entropy(pyx, py))  # compute divergence
        split_scores.append(np.exp(scores))

    return np.max(split_scores), np.mean(split_scores)

def readDir():
    dirPath = r"F:\experiment\ncsnv2\exp\image_samples\cifar10_50000"
    allFiles = []
    if os.path.isdir(dirPath):
        fileList = os.listdir(dirPath)
        for f in fileList:
            f = dirPath+'/'+f
            if os.path.isdir(f):
                subFiles = readDir(f)
                allFiles = subFiles + allFiles
            else:
                allFiles.append(f)
        return allFiles
    else:
        return 'Error,not a dir'

MAX, IS= inception_score(splits=10)
print('MAX IS is %.4f' % MAX)
print('The IS is %.4f' % IS)

其中路径D:\experiments\standard\metrics\pytorch-fid\cifar10_20000是我的文件夹地址,该文件夹地址包含50000张生成的图片。
原始的读取cifar10数据集的Inception Score计算代码的链接如下:compute_IS_for_GAN

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下面是使用 PyTorch 计算 Inception Score 的示例代码: ```python import torch import torch.nn as nn from torch.utils.data import DataLoader from torchvision import models, transforms, datasets import numpy as np from scipy.stats import entropy def inception_score(imgs, batch_size=32, resize=False): """ Computes the Inception Score of the generated images imgs """ assert (type(imgs) == np.ndarray) assert (imgs.shape[1] == 3) assert (np.min(imgs[0]) >= 0 and np.max(imgs[0]) > 10), 'Image values should be in the range [0, 255]' N = len(imgs) # Set up the Inception model inception_model = models.inception_v3(pretrained=True) inception_model.eval() if resize: # Resize the images to 299x299 transform = transforms.Compose([ transforms.ToPILImage(), transforms.Resize((299, 299)), transforms.ToTensor(), transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) ]) else: # Crop the images to 299x299 transform = transforms.Compose([ transforms.ToPILImage(), transforms.RandomCrop((299, 299)), transforms.ToTensor(), transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) ]) dataset = ImageDataset(imgs, transform) dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=False) # Compute the activations of the Inception model for all batches of images activations = [] for batch in dataloader: pred = inception_model(batch)[0] activations.append(pred.detach().cpu().numpy()) activations = np.concatenate(activations, axis=0) # Compute the mean and covariance of the activations mu = np.mean(activations, axis=0) sigma = np.cov(activations, rowvar=False) # Compute the Inception Score scores = [] for i in range(N // batch_size): batch = torch.from_numpy(imgs[i * batch_size:(i + 1) * batch_size]).float().cuda() pred = inception_model(batch)[0].detach().cpu().numpy() p_yx = np.exp(-0.5 * np.sum((pred - mu) ** 2 * np.linalg.inv(sigma), axis=1)) / np.sqrt( np.linalg.det(sigma) * (2 * np.pi) ** pred.shape[1]) scores.append(p_yx) scores = np.concatenate(scores, axis=0) scores = np.mean(scores.reshape((-1, 1)), axis=0) scores = np.exp(entropy(scores)) return scores class ImageDataset(torch.utils.data.Dataset): def __init__(self, imgs, transform=None): self.imgs = imgs self.transform = transform def __getitem__(self, index): img = self.imgs[index] if self.transform is not None: img = self.transform(img) return img def __len__(self): return len(self.imgs) ``` 这里需要注意的一点是,这个代码中用到了 PyTorch 的 `models.inception_v3` 模型,需要安装 torchvision 库才能使用。另外,在计算 Inception Score 时,建议对生成图片进行大小调整或裁剪,以便与 Inception v3 的输入要求相匹配。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值