| 10 | return string |
| 11 | |
| 12 | class CLIPEvaluator(object): |
| 13 | def __init__(self, device, clip_model='ViT-B/32') -> None: |
| 14 | self.device = device |
| 15 | self.model, clip_preprocess = clip.load(clip_model, device=self.device) |
| 16 | |
| 17 | self.clip_preprocess = clip_preprocess |
| 18 | |
| 19 | self.preprocess = transforms.Compose([transforms.Normalize(mean=[-1.0, -1.0, -1.0], std=[2.0, 2.0, 2.0])] + # Un-normalize from [-1.0, 1.0] (generator output) to [0, 1]. |
| 20 | clip_preprocess.transforms[:2] + # to match CLIP input scale assumptions |
| 21 | clip_preprocess.transforms[4:]) # + skip convert PIL to tensor |
| 22 | |
| 23 | def tokenize(self, strings: list): |
| 24 | return clip.tokenize(strings).to(self.device) |
| 25 | |
| 26 | @torch.no_grad() |
| 27 | def encode_text(self, tokens: list) -> torch.Tensor: |
| 28 | return self.model.encode_text(tokens) |
| 29 | |
| 30 | @torch.no_grad() |
| 31 | def encode_images(self, images: torch.Tensor) -> torch.Tensor: |
| 32 | images = self.preprocess(images).to(self.device) |
| 33 | return self.model.encode_image(images) |
| 34 | |
| 35 | def get_text_features(self, text: str, norm: bool = True) -> torch.Tensor: |
| 36 | |
| 37 | tokens = clip.tokenize(text).to(self.device) |
| 38 | |
| 39 | text_features = self.encode_text(tokens).detach() |
| 40 | |
| 41 | if norm: |
| 42 | text_features /= text_features.norm(dim=-1, keepdim=True) |
| 43 | |
| 44 | return text_features |
| 45 | |
| 46 | def get_image_features(self, img: torch.Tensor, norm: bool = True) -> torch.Tensor: |
| 47 | image_features = self.encode_images(img) |
| 48 | |
| 49 | if norm: |
| 50 | image_features /= image_features.clone().norm(dim=-1, keepdim=True) |
| 51 | |
| 52 | return image_features |
| 53 | |
| 54 | def img_to_img_similarity(self, src_images, generated_images): |
| 55 | src_img_features = self.get_image_features(src_images) |
| 56 | gen_img_features = self.get_image_features(generated_images) |
| 57 | |
| 58 | return (src_img_features @ gen_img_features.T).mean() |
| 59 | |
| 60 | def txt_to_img_similarity(self, text, generated_images): |
| 61 | text_features = self.get_text_features(text) |
| 62 | gen_img_features = self.get_image_features(generated_images) |
| 63 | |
| 64 | return (text_features @ gen_img_features.T).mean() |
| 65 | |
| 66 | |
| 67 | # class LDMCLIPEvaluator(CLIPEvaluator): |
nothing calls this directly
no outgoing calls
no test coverage detected