Download scripts/valuate.py from vegagoto123/Live3DPortrait: direct link, hf CLI and curl.
- Browser
- Download file 5.5 kB
-
https://huggingface.co/vegagoto123/Live3DPortrait/resolve/main/scripts/valuate.py
- Command line
-
hf download hf://vegagoto123/Live3DPortrait/scripts/valuate.py
-
curl -L -o valuate.py https://huggingface.co/vegagoto123/Live3DPortrait/resolve/main/scripts/valuate.py
5.5 kB
| import os | |
| os.environ['CUDA_VISIBLE_DEVICES'] = '3' | |
| import torch | |
| import numpy as np | |
| from scipy import linalg | |
| from tqdm import tqdm | |
| import sys | |
| sys.path.append(".") | |
| sys.path.append("..") | |
| from configs.paths_config import val_paths | |
| from models.Inception.inception import InceptionV3 | |
| from models.triencoder import TriEncoder | |
| from datasets.dataset import ImageFolderDataset | |
| from torch.utils.data import DataLoader | |
| from configs.paths_config import dataset_paths, val_paths | |
| # valuate each pretrain weight... | |
| # self used script ... | |
| device = 'cuda' | |
| def gen_rand_pose(pitch_range=26, yaw_range=36, cx_range=0.2, cy_range=0.2, fov_range=4.8, mode="yaw"): | |
| # set range | |
| # pitch: +-26, yaw: +-36/+-49 | |
| if mode == "yaw": | |
| return (torch.rand(1, device=device) - 0.5) * (pitch_range / 180 * torch.pi) + torch.pi/2 | |
| elif mode == "pitch": | |
| return (torch.rand(1, device=device) - 0.5) * (yaw_range / 180 * torch.pi) + torch.pi/2 | |
| else: | |
| raise NotImplementedError | |
| def calc_fid(sample_mean, sample_cov, real_mean, real_cov, eps=1e-6): | |
| cov_sqrt, _ = linalg.sqrtm(sample_cov @ real_cov, disp=False) | |
| if not np.isfinite(cov_sqrt).all(): | |
| print("product of cov matrices is singular") | |
| offset = np.eye(sample_cov.shape[0]) * eps | |
| cov_sqrt = linalg.sqrtm((sample_cov + offset) @ (real_cov + offset)) | |
| if np.iscomplexobj(cov_sqrt): | |
| if not np.allclose(np.diagonal(cov_sqrt).imag, 0, atol=1e-3): | |
| m = np.max(np.abs(cov_sqrt.imag)) | |
| raise ValueError(f"Imaginary component {m}") | |
| cov_sqrt = cov_sqrt.real | |
| mean_diff = sample_mean - real_mean | |
| mean_norm = mean_diff @ mean_diff | |
| trace = np.trace(sample_cov) + np.trace(real_cov) - 2 * np.trace(cov_sqrt) | |
| fid = mean_norm + trace | |
| return fid | |
| def compute_fid(net, inception, model_path, dataloader, batch_size, n_sample=10000): | |
| basename = os.path.basename(model_path) | |
| n_batch = n_sample // batch_size | |
| resid = n_sample - (n_batch * batch_size) | |
| batch_sizes = [batch_size] * n_batch | |
| batch_sizes += [resid] if resid > 0 else [] | |
| sample_mean = np.load(val_paths['ffhq_mean']) | |
| sample_cov = np.load(val_paths['ffhq_cov']) | |
| mean_savepath = f"assets/temp/{basename}_fid_pred_sample_mean{n_sample}.npy" | |
| cov_savepath = f"assets/temp/{basename}_fid_pred_sample_cov{n_sample}.npy" | |
| if os.path.isfile(mean_savepath) and os.path.isfile(cov_savepath): | |
| pred_sample_mean = np.load(mean_savepath) | |
| pred_sample_cov = np.load(cov_savepath) | |
| else: | |
| print("pred.....") | |
| pred_features = [] | |
| # pred_features = np.zeros((n_sample, 2048)) | |
| # for idx, batch in enumerate(tqdm(batch_sizes)): | |
| for batch in tqdm(batch_sizes): | |
| # _, encoder_input, camera_param, ws = net.sample_triplane(batch, gen_rand_pose(pitch_range=26, mode='pitch'), gen_rand_pose(yaw_range=49, mode='yaw')) | |
| # gen_triplanes = net.encoder(encoder_input['image']) | |
| # render_res = net.triplane_renderer(gen_triplanes, camera_param) | |
| # img = render_res['image'] | |
| image, label = next(iter(dataloader)) | |
| image = image.to(device) # [B, 3, 512, 512] range: (0, 255) -> (-1, 1) should divide 127.5 and sub 1 | |
| label = label.to(device) # [B, 25] | |
| gen_triplanes = net.encoder((image.float()/127.5 - 1)) | |
| render_res = net.triplane_renderer(gen_triplanes, label) | |
| img = render_res['image'] | |
| feat = inception(img)[0].view(img.shape[0], -1) | |
| pred_features.append(feat.to("cpu")) | |
| # pred_features[idx * batch_size: idx * batch_size + batch] = feat.to("cpu").numpy() | |
| # import pdb; pdb.set_trace() | |
| pred_features = torch.cat(pred_features, 0).numpy() | |
| pred_sample_mean = np.mean(pred_features, 0) | |
| pred_sample_cov = np.cov(pred_features, rowvar=False) | |
| np.save(f"assets/temp/{basename}_fid_pred_sample_mean{n_sample}.npy", pred_sample_mean) | |
| np.save(f"assets/temp/{basename}_fid_pred_sample_cov{n_sample}.npy", pred_sample_cov) | |
| print("pred done") | |
| print("calc fid....") | |
| # --------------------------------------------------------------------------------------------------------- | |
| fid = calc_fid(pred_sample_mean, pred_sample_cov, sample_mean, sample_cov) | |
| print("fid:", fid) | |
| pass | |
| def testfid50k(model_path): | |
| # load model | |
| batch_size=16 | |
| model_dict = torch.load(model_path) | |
| net = TriEncoder(mode="Normal").to(device) | |
| net.encoder.load_state_dict(model_dict['encoder_state_dict']) | |
| net.triplane_renderer.load_state_dict(model_dict['renderer_state_dict']) | |
| path = dataset_paths["ffhq512"] | |
| image_datasets = ImageFolderDataset(path=path, resolution=None, use_labels=True) | |
| dataloader = DataLoader(dataset=image_datasets, batch_size=batch_size, shuffle=True, num_workers=8) | |
| inception = InceptionV3([3], normalize_input=False).to(device) | |
| inception.eval() | |
| compute_fid(net, inception, model_path, dataloader, batch_size=batch_size, n_sample=50000) | |
| del net, inception | |
| def main(): | |
| ckpt_path = "exp10/checkpoints" | |
| ckpt_list = os.listdir(ckpt_path) | |
| ckpt_list = ['iteration_140000.pt'] | |
| for ckpt in ckpt_list: | |
| if ckpt.endswith(".pt"): | |
| model_path = os.path.join(ckpt_path, ckpt) | |
| print(model_path) | |
| print("test fid 50k...") | |
| testfid50k(model_path) | |
| pass | |
| if __name__ == '__main__': | |
| main() | |
| pass | |