Path: blob/master/Face-Recognition-with-ArcFace/tsne.py
3118 views
import argparse1import os2import random34import cv25import matplotlib.pyplot as plt6import numpy as np7import torch8from embeddings import get_embeddings9from sklearn.manifold import TSNE10from tqdm import tqdm111213def fix_random_seeds():14seed = 1015random.seed(seed)16torch.manual_seed(seed)17np.random.seed(seed)181920# scale and move the coordinates so they fit [0; 1] range21def scale_to_01_range(x):22# compute the distribution range23value_range = np.max(x) - np.min(x)2425# move the distribution so that it starts from zero26# by extracting the minimal value from all its values27starts_from_zero = x - np.min(x)2829# make the distribution fit [0; 1] by dividing by its range30return starts_from_zero / value_range313233def scale_image(image, max_image_size):34image_height, image_width, _ = image.shape3536scale = max(1, image_width / max_image_size, image_height / max_image_size)37image_width = int(image_width / scale)38image_height = int(image_height / scale)3940image = cv2.resize(image, (image_width, image_height))41return image424344def compute_plot_coordinates(image, x, y, image_centers_area_size, offset):45image_height, image_width, _ = image.shape4647# compute the image center coordinates on the plot48center_x = int(image_centers_area_size * x) + offset4950# in matplotlib, the y axis is directed upward51# to have the same here, we need to mirror the y coordinate52center_y = int(image_centers_area_size * (1 - y)) + offset5354# knowing the image center, compute the coordinates of the top left and bottom right corner55tl_x = center_x - int(image_width / 2)56tl_y = center_y - int(image_height / 2)5758br_x = tl_x + image_width59br_y = tl_y + image_height6061return tl_x, tl_y, br_x, br_y626364def visualize_tsne_images(tx, ty, images, plot_size=1000, max_image_size=100):65# we'll put the image centers in the central area of the plot66# and use offsets to make sure the images fit the plot67offset = max_image_size // 268image_centers_area_size = plot_size - 2 * offset6970tsne_plot = 255 * np.ones((plot_size, plot_size, 3), np.uint8)7172# now we'll put a small copy of every image to its corresponding T-SNE coordinate73for image, x, y in tqdm(74zip(images, tx, ty), desc="Building the T-SNE plot", total=len(images),75):7677# scale the image to put it to the plot78image = scale_image(image, max_image_size)7980# compute the coordinates of the image on the scaled plot visualization81tl_x, tl_y, br_x, br_y = compute_plot_coordinates(82image, x, y, image_centers_area_size, offset,83)8485# put the image to its TSNE coordinates using numpy subarray indices86tsne_plot[tl_y:br_y, tl_x:br_x, :] = image8788plt.figure('Embeddings projection with t-SNE')89plt.axis('off')90plt.imshow(tsne_plot[:, :, ::-1])91plt.savefig('tsne_plot.jpg')92plt.show()939495def visualize_tsne(tsne, images, plot_size=1000, max_image_size=100):96# extract x and y coordinates representing the positions of the images on T-SNE plot97tx = tsne[:, 0]98ty = tsne[:, 1]99100# scale and move the coordinates so they fit [0; 1] range101tx = scale_to_01_range(tx)102ty = scale_to_01_range(ty)103104# visualize the plot: samples as images105visualize_tsne_images(106tx, ty, images, plot_size=plot_size, max_image_size=max_image_size,107)108109110def main():111parser = argparse.ArgumentParser()112parser.add_argument(113"--tags",114help="specify your tags for aligned faces datasets",115default="test",116nargs='+',117required=True118)119args = parser.parse_args()120tags = args.tags121parser.add_argument(122"--input_size",123help="specify size of aligned faces, align and crop with padding",124default=112,125choices=[112, 224],126type=int,127)128args = parser.parse_args()129130fix_random_seeds()131132# predict embeddings for each small dataset133all_images = []134all_embeddings = []135tags = args.tags136input_size = args.input_size137for tag in tags:138images, embeddings = get_embeddings(139data_root=f"data/{tag}_aligned",140model_root="checkpoint/backbone_ir50_ms1m_epoch120.pth",141input_size=[input_size, input_size],142)143all_images.append(images)144all_embeddings.append(embeddings)145146# concatenate images and embeddings from different persons into matrices147all_images = np.vstack(all_images)148all_embeddings = np.vstack(all_embeddings)149# perplexity is lower than default, because number of samples is small150tsne_results = TSNE(n_components=2, perplexity=8).fit_transform(all_embeddings)151visualize_tsne(tsne_results, all_images, plot_size=1000, max_image_size=112)152153154if __name__ == "__main__":155fix_random_seeds()156main()157158159