168 lines
6.7 KiB
Python
168 lines
6.7 KiB
Python
# ------------------------------------------
|
|
# TextDiffuser: Diffusion Models as Text Painters
|
|
# Paper Link: https://arxiv.org/abs/2305.10855
|
|
# Code Link: https://github.com/microsoft/unilm/tree/master/textdiffuser
|
|
# Copyright (c) Microsoft Corporation.
|
|
# This file provides the inference script.
|
|
# ------------------------------------------
|
|
|
|
import json
|
|
import os
|
|
import numpy as np
|
|
import argparse
|
|
from clipscore import cal_clipscore
|
|
from fid_score import calculate_fid_given_paths
|
|
|
|
|
|
def eval_clipscore(root_eval, root_res, dataset, device="cuda:0", num_images_per_prompt=4):
|
|
with open(os.path.join(root_eval, dataset, dataset + '.txt'), 'r') as fr:
|
|
text_list = fr.readlines()
|
|
text_list = [_.strip() for _ in text_list]
|
|
clip_scores = []
|
|
scores = []
|
|
for seed in range(num_images_per_prompt):
|
|
if 'stablediffusion' in root_res:
|
|
format = '.png'
|
|
else:
|
|
format = '.jpg'
|
|
image_list = [os.path.join(root_res, dataset, 'images_' + str(seed),
|
|
str(idx) + '_' + str(seed) + format) for idx in range(len(text_list))]
|
|
image_ids = [str(idx) + '_' + str(seed) + format for idx in range(len(text_list))]
|
|
score = cal_clipscore(image_ids=image_ids, image_paths=image_list, text_list=text_list, device=device)
|
|
clip_score = np.mean([s['CLIPScore'] for s in score.values()])
|
|
clip_scores.append(clip_score)
|
|
scores.append(score)
|
|
print("clip_score:", np.mean(clip_scores), clip_scores)
|
|
return np.mean(clip_scores), scores
|
|
|
|
|
|
def MARIOEval_evaluate_results(root, datasets_with_images, datasets, methods, gpu,
|
|
eval_clipscore_flag=True, eval_fid_flag=True, num_images_per_prompt=4):
|
|
root_eval = os.path.join(root, "MARIOEval")
|
|
method_res = {}
|
|
device = "cuda:" + str(gpu)
|
|
for method_idx, method in enumerate(methods):
|
|
if method_idx != gpu: # running in different gpus simultaneously to save time
|
|
continue
|
|
print("\nmethod:", method)
|
|
dataset_res = {}
|
|
root_res = os.path.join(root, 'generation', method)
|
|
for dataset in datasets:
|
|
print("dataset:", dataset)
|
|
dataset_res[dataset] = {}
|
|
if eval_clipscore_flag:
|
|
dataset_res[dataset]['clipscore'], dataset_res[dataset]['scores'] =\
|
|
eval_clipscore(root_eval, root_res, dataset, device, num_images_per_prompt)
|
|
if eval_fid_flag and dataset in datasets_with_images:
|
|
gt_path = os.path.join(root_eval, dataset, 'images')
|
|
fids = []
|
|
for idx in range(num_images_per_prompt):
|
|
gen_path = os.path.join(root_res, dataset, 'images_' + str(idx))
|
|
fids.append(calculate_fid_given_paths(paths=[gt_path, gen_path]))
|
|
print("fid:", np.mean(fids), fids)
|
|
dataset_res[dataset]['fid'] = np.mean(fids)
|
|
|
|
if eval_clipscore_flag:
|
|
method_clipscores = []
|
|
for seed in range(num_images_per_prompt):
|
|
clipscore_list = []
|
|
for dataset in dataset_res.keys():
|
|
clipscore_list += [_['CLIPScore'] for _ in dataset_res[dataset]['scores'][seed].values()]
|
|
method_clipscores.append(np.mean(clipscore_list))
|
|
method_clipscore = np.mean(method_clipscores)
|
|
dataset_res['clipscore'] = method_clipscore
|
|
if eval_fid_flag:
|
|
method_fids = []
|
|
for idx in range(num_images_per_prompt):
|
|
gt_paths = []
|
|
gen_paths = []
|
|
for dataset in dataset_res.keys():
|
|
if dataset in datasets_with_images:
|
|
gt_paths.append(os.path.join(root_eval, dataset, 'images'))
|
|
gen_paths.append(os.path.join(root_res, dataset, 'images_' + str(idx)))
|
|
if len(gt_paths):
|
|
method_fids.append(calculate_fid_given_paths(paths=[gt_paths, gen_paths]))
|
|
print("fid:", np.mean(method_fids), method_fids)
|
|
method_fid = np.mean(method_fids)
|
|
dataset_res['fid'] = method_fid
|
|
|
|
method_res[method] = dataset_res
|
|
with open(os.path.join(root_res, 'eval.json'), 'w') as fw:
|
|
json.dump(dataset_res, fw)
|
|
|
|
print(method_res)
|
|
with open(os.path.join(root, 'generation', 'eval.json'), 'w') as fw:
|
|
json.dump(method_res, fw)
|
|
|
|
|
|
def merge_eval_results(root, methods):
|
|
method_res = {}
|
|
for method_idx, method in enumerate(methods):
|
|
root_res = os.path.join(root, 'generation', method)
|
|
with open(os.path.join(root_res, 'eval.json'), 'r') as fr:
|
|
dataset_res = json.load(fr)
|
|
for k, v in dataset_res.items():
|
|
if type(v) is dict:
|
|
del v['scores'] # too long
|
|
method_res[method] = dataset_res
|
|
|
|
with open(os.path.join(root, 'generation', 'eval.json'), 'w') as fw:
|
|
json.dump(method_res, fw)
|
|
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(description="Simple example of a training script.")
|
|
parser.add_argument(
|
|
"--dataset",
|
|
type=str,
|
|
default='TMDBEval500',
|
|
required=False,
|
|
choices=['TMDBEval500', 'OpenLibraryEval500', 'LAIONEval4000',
|
|
'ChineseDrawText', 'DrawBenchText', 'DrawTextCreative']
|
|
)
|
|
parser.add_argument(
|
|
"--root",
|
|
type=str,
|
|
default="/path/to/data/TextDiffuser/evaluation/",
|
|
required=True,
|
|
)
|
|
parser.add_argument(
|
|
"--method",
|
|
type=str,
|
|
default='controlnet',
|
|
required=False,
|
|
choices=['controlnet', 'deepfloyd', 'stablediffusion', 'textdiffuser']
|
|
)
|
|
parser.add_argument(
|
|
"--gpu",
|
|
type=int,
|
|
default=0,
|
|
required=False,
|
|
)
|
|
parser.add_argument(
|
|
"--split",
|
|
type=int,
|
|
default=0,
|
|
required=False,
|
|
)
|
|
parser.add_argument(
|
|
"--total_split",
|
|
type=int,
|
|
default=1,
|
|
required=False,
|
|
)
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
|
|
if __name__ == "__main__":
|
|
args = parse_args()
|
|
os.environ['CUDA_VISIBLE_DEVICES'] = str(args.gpu)
|
|
datasets_with_images = ['TMDBEval500', 'OpenLibraryEval500', 'LAIONEval4000']
|
|
datasets = datasets_with_images + ['ChineseDrawText', 'DrawBenchText', 'DrawTextCreative']
|
|
methods = ['textdiffuser', 'controlnet', 'deepfloyd', 'stablediffusion']
|
|
|
|
MARIOEval_evaluate_results(args.root, datasets_with_images, datasets, methods, args.gpu,
|
|
eval_clipscore_flag=True, eval_fid_flag=True, num_images_per_prompt=4)
|
|
merge_eval_results(args.root, methods)
|