CoolFace
Apppublic

RabbitRUI/ruispace

sourceHugging Facemitupdated 3y agoView on Hugging Face
0likes
eval_ijbc.py484 linesDownload Raw Back to arcface_torch
1# coding: utf-82 3import os4import pickle5 6import matplotlib7import pandas as pd8 9matplotlib.use('Agg')10import matplotlib.pyplot as plt11import timeit12import sklearn13import argparse14import cv215import numpy as np16import torch17from skimage import transform as trans18from backbones import get_model19from sklearn.metrics import roc_curve, auc20 21from menpo.visualize.viewmatplotlib import sample_colours_from_colourmap22from prettytable import PrettyTable23from pathlib import Path24 25import sys26import warnings27 28sys.path.insert(0, "../")29warnings.filterwarnings("ignore")30 31parser = argparse.ArgumentParser(description='do ijb test')32# general33parser.add_argument('--model-prefix', default='', help='path to load model.')34parser.add_argument('--image-path', default='', type=str, help='')35parser.add_argument('--result-dir', default='.', type=str, help='')36parser.add_argument('--batch-size', default=128, type=int, help='')37parser.add_argument('--network', default='iresnet50', type=str, help='')38parser.add_argument('--job', default='insightface', type=str, help='job name')39parser.add_argument('--target', default='IJBC', type=str, help='target, set to IJBC or IJBB')40args = parser.parse_args()41 42target = args.target43model_path = args.model_prefix44image_path = args.image_path45result_dir = args.result_dir46gpu_id = None47use_norm_score = True  # if Ture, TestMode(N1)48use_detector_score = True  # if Ture, TestMode(D1)49use_flip_test = True  # if Ture, TestMode(F1)50job = args.job51batch_size = args.batch_size52 53 54class Embedding(object):55    def __init__(self, prefix, data_shape, batch_size=1):56        image_size = (112, 112)57        self.image_size = image_size58        weight = torch.load(prefix)59        resnet = get_model(args.network, dropout=0, fp16=False).cuda()60        resnet.load_state_dict(weight)61        model = torch.nn.DataParallel(resnet)62        self.model = model63        self.model.eval()64        src = np.array([65            [30.2946, 51.6963],66            [65.5318, 51.5014],67            [48.0252, 71.7366],68            [33.5493, 92.3655],69            [62.7299, 92.2041]], dtype=np.float32)70        src[:, 0] += 8.071        self.src = src72        self.batch_size = batch_size73        self.data_shape = data_shape74 75    def get(self, rimg, landmark):76 77        assert landmark.shape[0] == 68 or landmark.shape[0] == 578        assert landmark.shape[1] == 279        if landmark.shape[0] == 68:80            landmark5 = np.zeros((5, 2), dtype=np.float32)81            landmark5[0] = (landmark[36] + landmark[39]) / 282            landmark5[1] = (landmark[42] + landmark[45]) / 283            landmark5[2] = landmark[30]84            landmark5[3] = landmark[48]85            landmark5[4] = landmark[54]86        else:87            landmark5 = landmark88        tform = trans.SimilarityTransform()89        tform.estimate(landmark5, self.src)90        M = tform.params[0:2, :]91        img = cv2.warpAffine(rimg,92                             M, (self.image_size[1], self.image_size[0]),93                             borderValue=0.0)94        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)95        img_flip = np.fliplr(img)96        img = np.transpose(img, (2, 0, 1))  # 3*112*112, RGB97        img_flip = np.transpose(img_flip, (2, 0, 1))98        input_blob = np.zeros((2, 3, self.image_size[1], self.image_size[0]), dtype=np.uint8)99        input_blob[0] = img100        input_blob[1] = img_flip101        return input_blob102 103    @torch.no_grad()104    def forward_db(self, batch_data):105        imgs = torch.Tensor(batch_data).cuda()106        imgs.div_(255).sub_(0.5).div_(0.5)107        feat = self.model(imgs)108        feat = feat.reshape([self.batch_size, 2 * feat.shape[1]])109        return feat.cpu().numpy()110 111 112# 将一个list尽量均分成n份,限制len(list)==n,份数大于原list内元素个数则分配空list[]113def divideIntoNstrand(listTemp, n):114    twoList = [[] for i in range(n)]115    for i, e in enumerate(listTemp):116        twoList[i % n].append(e)117    return twoList118 119 120def read_template_media_list(path):121    # ijb_meta = np.loadtxt(path, dtype=str)122    ijb_meta = pd.read_csv(path, sep=' ', header=None).values123    templates = ijb_meta[:, 1].astype(np.int)124    medias = ijb_meta[:, 2].astype(np.int)125    return templates, medias126 127 128# In[ ]:129 130 131def read_template_pair_list(path):132    # pairs = np.loadtxt(path, dtype=str)133    pairs = pd.read_csv(path, sep=' ', header=None).values134    # print(pairs.shape)135    # print(pairs[:, 0].astype(np.int))136    t1 = pairs[:, 0].astype(np.int)137    t2 = pairs[:, 1].astype(np.int)138    label = pairs[:, 2].astype(np.int)139    return t1, t2, label140 141 142# In[ ]:143 144 145def read_image_feature(path):146    with open(path, 'rb') as fid:147        img_feats = pickle.load(fid)148    return img_feats149 150 151# In[ ]:152 153 154def get_image_feature(img_path, files_list, model_path, epoch, gpu_id):155    batch_size = args.batch_size156    data_shape = (3, 112, 112)157 158    files = files_list159    print('files:', len(files))160    rare_size = len(files) % batch_size161    faceness_scores = []162    batch = 0163    img_feats = np.empty((len(files), 1024), dtype=np.float32)164 165    batch_data = np.empty((2 * batch_size, 3, 112, 112))166    embedding = Embedding(model_path, data_shape, batch_size)167    for img_index, each_line in enumerate(files[:len(files) - rare_size]):168        name_lmk_score = each_line.strip().split(' ')169        img_name = os.path.join(img_path, name_lmk_score[0])170        img = cv2.imread(img_name)171        lmk = np.array([float(x) for x in name_lmk_score[1:-1]],172                       dtype=np.float32)173        lmk = lmk.reshape((5, 2))174        input_blob = embedding.get(img, lmk)175 176        batch_data[2 * (img_index - batch * batch_size)][:] = input_blob[0]177        batch_data[2 * (img_index - batch * batch_size) + 1][:] = input_blob[1]178        if (img_index + 1) % batch_size == 0:179            print('batch', batch)180            img_feats[batch * batch_size:batch * batch_size +181                                         batch_size][:] = embedding.forward_db(batch_data)182            batch += 1183        faceness_scores.append(name_lmk_score[-1])184 185    batch_data = np.empty((2 * rare_size, 3, 112, 112))186    embedding = Embedding(model_path, data_shape, rare_size)187    for img_index, each_line in enumerate(files[len(files) - rare_size:]):188        name_lmk_score = each_line.strip().split(' ')189        img_name = os.path.join(img_path, name_lmk_score[0])190        img = cv2.imread(img_name)191        lmk = np.array([float(x) for x in name_lmk_score[1:-1]],192                       dtype=np.float32)193        lmk = lmk.reshape((5, 2))194        input_blob = embedding.get(img, lmk)195        batch_data[2 * img_index][:] = input_blob[0]196        batch_data[2 * img_index + 1][:] = input_blob[1]197        if (img_index + 1) % rare_size == 0:198            print('batch', batch)199            img_feats[len(files) -200                      rare_size:][:] = embedding.forward_db(batch_data)201            batch += 1202        faceness_scores.append(name_lmk_score[-1])203    faceness_scores = np.array(faceness_scores).astype(np.float32)204    # img_feats = np.ones( (len(files), 1024), dtype=np.float32) * 0.01205    # faceness_scores = np.ones( (len(files), ), dtype=np.float32 )206    return img_feats, faceness_scores207 208 209# In[ ]:210 211 212def image2template_feature(img_feats=None, templates=None, medias=None):213    # ==========================================================214    # 1. face image feature l2 normalization. img_feats:[number_image x feats_dim]215    # 2. compute media feature.216    # 3. compute template feature.217    # ==========================================================218    unique_templates = np.unique(templates)219    template_feats = np.zeros((len(unique_templates), img_feats.shape[1]))220 221    for count_template, uqt in enumerate(unique_templates):222 223        (ind_t,) = np.where(templates == uqt)224        face_norm_feats = img_feats[ind_t]225        face_medias = medias[ind_t]226        unique_medias, unique_media_counts = np.unique(face_medias,227                                                       return_counts=True)228        media_norm_feats = []229        for u, ct in zip(unique_medias, unique_media_counts):230            (ind_m,) = np.where(face_medias == u)231            if ct == 1:232                media_norm_feats += [face_norm_feats[ind_m]]233            else:  # image features from the same video will be aggregated into one feature234                media_norm_feats += [235                    np.mean(face_norm_feats[ind_m], axis=0, keepdims=True)236                ]237        media_norm_feats = np.array(media_norm_feats)238        # media_norm_feats = media_norm_feats / np.sqrt(np.sum(media_norm_feats ** 2, -1, keepdims=True))239        template_feats[count_template] = np.sum(media_norm_feats, axis=0)240        if count_template % 2000 == 0:241            print('Finish Calculating {} template features.'.format(242                count_template))243    # template_norm_feats = template_feats / np.sqrt(np.sum(template_feats ** 2, -1, keepdims=True))244    template_norm_feats = sklearn.preprocessing.normalize(template_feats)245    # print(template_norm_feats.shape)246    return template_norm_feats, unique_templates247 248 249# In[ ]:250 251 252def verification(template_norm_feats=None,253                 unique_templates=None,254                 p1=None,255                 p2=None):256    # ==========================================================257    #         Compute set-to-set Similarity Score.258    # ==========================================================259    template2id = np.zeros((max(unique_templates) + 1, 1), dtype=int)260    for count_template, uqt in enumerate(unique_templates):261        template2id[uqt] = count_template262 263    score = np.zeros((len(p1),))  # save cosine distance between pairs264 265    total_pairs = np.array(range(len(p1)))266    batchsize = 100000  # small batchsize instead of all pairs in one batch due to the memory limiation267    sublists = [268        total_pairs[i:i + batchsize] for i in range(0, len(p1), batchsize)269    ]270    total_sublists = len(sublists)271    for c, s in enumerate(sublists):272        feat1 = template_norm_feats[template2id[p1[s]]]273        feat2 = template_norm_feats[template2id[p2[s]]]274        similarity_score = np.sum(feat1 * feat2, -1)275        score[s] = similarity_score.flatten()276        if c % 10 == 0:277            print('Finish {}/{} pairs.'.format(c, total_sublists))278    return score279 280 281# In[ ]:282def verification2(template_norm_feats=None,283                  unique_templates=None,284                  p1=None,285                  p2=None):286    template2id = np.zeros((max(unique_templates) + 1, 1), dtype=int)287    for count_template, uqt in enumerate(unique_templates):288        template2id[uqt] = count_template289    score = np.zeros((len(p1),))  # save cosine distance between pairs290    total_pairs = np.array(range(len(p1)))291    batchsize = 100000  # small batchsize instead of all pairs in one batch due to the memory limiation292    sublists = [293        total_pairs[i:i + batchsize] for i in range(0, len(p1), batchsize)294    ]295    total_sublists = len(sublists)296    for c, s in enumerate(sublists):297        feat1 = template_norm_feats[template2id[p1[s]]]298        feat2 = template_norm_feats[template2id[p2[s]]]299        similarity_score = np.sum(feat1 * feat2, -1)300        score[s] = similarity_score.flatten()301        if c % 10 == 0:302            print('Finish {}/{} pairs.'.format(c, total_sublists))303    return score304 305 306def read_score(path):307    with open(path, 'rb') as fid:308        img_feats = pickle.load(fid)309    return img_feats310 311 312# # Step1: Load Meta Data313 314# In[ ]:315 316assert target == 'IJBC' or target == 'IJBB'317 318# =============================================================319# load image and template relationships for template feature embedding320# tid --> template id,  mid --> media id321# format:322#           image_name tid mid323# =============================================================324start = timeit.default_timer()325templates, medias = read_template_media_list(326    os.path.join('%s/meta' % image_path,327                 '%s_face_tid_mid.txt' % target.lower()))328stop = timeit.default_timer()329print('Time: %.2f s. ' % (stop - start))330 331# In[ ]:332 333# =============================================================334# load template pairs for template-to-template verification335# tid : template id,  label : 1/0336# format:337#           tid_1 tid_2 label338# =============================================================339start = timeit.default_timer()340p1, p2, label = read_template_pair_list(341    os.path.join('%s/meta' % image_path,342                 '%s_template_pair_label.txt' % target.lower()))343stop = timeit.default_timer()344print('Time: %.2f s. ' % (stop - start))345 346# # Step 2: Get Image Features347 348# In[ ]:349 350# =============================================================351# load image features352# format:353#           img_feats: [image_num x feats_dim] (227630, 512)354# =============================================================355start = timeit.default_timer()356img_path = '%s/loose_crop' % image_path357img_list_path = '%s/meta/%s_name_5pts_score.txt' % (image_path, target.lower())358img_list = open(img_list_path)359files = img_list.readlines()360# files_list = divideIntoNstrand(files, rank_size)361files_list = files362 363# img_feats364# for i in range(rank_size):365img_feats, faceness_scores = get_image_feature(img_path, files_list,366                                               model_path, 0, gpu_id)367stop = timeit.default_timer()368print('Time: %.2f s. ' % (stop - start))369print('Feature Shape: ({} , {}) .'.format(img_feats.shape[0],370                                          img_feats.shape[1]))371 372# # Step3: Get Template Features373 374# In[ ]:375 376# =============================================================377# compute template features from image features.378# =============================================================379start = timeit.default_timer()380# ==========================================================381# Norm feature before aggregation into template feature?382# Feature norm from embedding network and faceness score are able to decrease weights for noise samples (not face).383# ==========================================================384# 1. FaceScore (Feature Norm)385# 2. FaceScore (Detector)386 387if use_flip_test:388    # concat --- F1389    # img_input_feats = img_feats390    # add --- F2391    img_input_feats = img_feats[:, 0:img_feats.shape[1] //392                                     2] + img_feats[:, img_feats.shape[1] // 2:]393else:394    img_input_feats = img_feats[:, 0:img_feats.shape[1] // 2]395 396if use_norm_score:397    img_input_feats = img_input_feats398else:399    # normalise features to remove norm information400    img_input_feats = img_input_feats / np.sqrt(401        np.sum(img_input_feats ** 2, -1, keepdims=True))402 403if use_detector_score:404    print(img_input_feats.shape, faceness_scores.shape)405    img_input_feats = img_input_feats * faceness_scores[:, np.newaxis]406else:407    img_input_feats = img_input_feats408 409template_norm_feats, unique_templates = image2template_feature(410    img_input_feats, templates, medias)411stop = timeit.default_timer()412print('Time: %.2f s. ' % (stop - start))413 414# # Step 4: Get Template Similarity Scores415 416# In[ ]:417 418# =============================================================419# compute verification scores between template pairs.420# =============================================================421start = timeit.default_timer()422score = verification(template_norm_feats, unique_templates, p1, p2)423stop = timeit.default_timer()424print('Time: %.2f s. ' % (stop - start))425 426# In[ ]:427save_path = os.path.join(result_dir, args.job)428# save_path = result_dir + '/%s_result' % target429 430if not os.path.exists(save_path):431    os.makedirs(save_path)432 433score_save_file = os.path.join(save_path, "%s.npy" % target.lower())434np.save(score_save_file, score)435 436# # Step 5: Get ROC Curves and TPR@FPR Table437 438# In[ ]:439 440files = [score_save_file]441methods = []442scores = []443for file in files:444    methods.append(Path(file).stem)445    scores.append(np.load(file))446 447methods = np.array(methods)448scores = dict(zip(methods, scores))449colours = dict(450    zip(methods, sample_colours_from_colourmap(methods.shape[0], 'Set2')))451x_labels = [10 ** -6, 10 ** -5, 10 ** -4, 10 ** -3, 10 ** -2, 10 ** -1]452tpr_fpr_table = PrettyTable(['Methods'] + [str(x) for x in x_labels])453fig = plt.figure()454for method in methods:455    fpr, tpr, _ = roc_curve(label, scores[method])456    roc_auc = auc(fpr, tpr)457    fpr = np.flipud(fpr)458    tpr = np.flipud(tpr)  # select largest tpr at same fpr459    plt.plot(fpr,460             tpr,461             color=colours[method],462             lw=1,463             label=('[%s (AUC = %0.4f %%)]' %464                    (method.split('-')[-1], roc_auc * 100)))465    tpr_fpr_row = []466    tpr_fpr_row.append("%s-%s" % (method, target))467    for fpr_iter in np.arange(len(x_labels)):468        _, min_index = min(469            list(zip(abs(fpr - x_labels[fpr_iter]), range(len(fpr)))))470        tpr_fpr_row.append('%.2f' % (tpr[min_index] * 100))471    tpr_fpr_table.add_row(tpr_fpr_row)472plt.xlim([10 ** -6, 0.1])473plt.ylim([0.3, 1.0])474plt.grid(linestyle='--', linewidth=1)475plt.xticks(x_labels)476plt.yticks(np.linspace(0.3, 1.0, 8, endpoint=True))477plt.xscale('log')478plt.xlabel('False Positive Rate')479plt.ylabel('True Positive Rate')480plt.title('ROC on IJB')481plt.legend(loc="lower right")482fig.savefig(os.path.join(save_path, '%s.pdf' % target.lower()))483print(tpr_fpr_table)484