From 914e69676ea129d21d081d5719b3172e2bede5a4 Mon Sep 17 00:00:00 2001 From: dongshuilong Date: Tue, 22 Jun 2021 17:08:02 +0800 Subject: [PATCH] fix reid recall metric bugs --- ppcls/engine/trainer.py | 4 +- ppcls/metric/metrics.py | 86 +++++++++++++++++++++++++++++------------ 2 files changed, 64 insertions(+), 26 deletions(-) diff --git a/ppcls/engine/trainer.py b/ppcls/engine/trainer.py index 7848ae6f..80957757 100644 --- a/ppcls/engine/trainer.py +++ b/ppcls/engine/trainer.py @@ -442,10 +442,12 @@ class Trainer(object): keep_mask = paddle.logical_or(query_id_mask, image_id_mask) similarity_matrix = similarity_matrix * keep_mask.astype( "float32") + else: + keep_mask = None metric_tmp = self.eval_metric_func(similarity_matrix, image_id_blocks[block_idx], - gallery_img_id) + gallery_img_id, keep_mask) for key in metric_tmp: if key not in metric_dict: diff --git a/ppcls/metric/metrics.py b/ppcls/metric/metrics.py index df4cf0ad..b4f1b442 100644 --- a/ppcls/metric/metrics.py +++ b/ppcls/metric/metrics.py @@ -16,6 +16,7 @@ import numpy as np import paddle import paddle.nn as nn + class TopkAcc(nn.Layer): def __init__(self, topk=(1, 5)): super().__init__() @@ -34,54 +35,72 @@ class TopkAcc(nn.Layer): x, label, k=k) return metric_dict + class mAP(nn.Layer): def __init__(self): super().__init__() - def forward(self, similarities_matrix, query_img_id, gallery_img_id): + def forward(self, similarities_matrix, query_img_id, gallery_img_id, + *args): metric_dict = dict() - - choosen_indices = paddle.argsort(similarities_matrix, axis=1, descending=True) - gallery_labels_transpose = paddle.transpose(gallery_img_id, [1,0]) - gallery_labels_transpose = paddle.broadcast_to(gallery_labels_transpose, shape=[choosen_indices.shape[0], gallery_labels_transpose.shape[1]]) - choosen_label = paddle.index_sample(gallery_labels_transpose, choosen_indices) + + choosen_indices = paddle.argsort( + similarities_matrix, axis=1, descending=True) + gallery_labels_transpose = paddle.transpose(gallery_img_id, [1, 0]) + gallery_labels_transpose = paddle.broadcast_to( + gallery_labels_transpose, + shape=[ + choosen_indices.shape[0], gallery_labels_transpose.shape[1] + ]) + choosen_label = paddle.index_sample(gallery_labels_transpose, + choosen_indices) equal_flag = paddle.equal(choosen_label, query_img_id) equal_flag = paddle.cast(equal_flag, 'float32') acc_sum = paddle.cumsum(equal_flag, axis=1) div = paddle.arange(acc_sum.shape[1]).astype("float32") + 1 - precision = paddle.divide(acc_sum, div) + precision = paddle.divide(acc_sum, div) #calc map precision_mask = paddle.multiply(equal_flag, precision) - ap = paddle.sum(precision_mask, axis=1) / paddle.sum(equal_flag, axis=1) + ap = paddle.sum(precision_mask, axis=1) / paddle.sum(equal_flag, + axis=1) metric_dict["mAP"] = paddle.mean(ap).numpy()[0] return metric_dict + class mINP(nn.Layer): def __init__(self): super().__init__() - def forward(self, similarities_matrix, query_img_id, gallery_img_id): + def forward(self, similarities_matrix, query_img_id, gallery_img_id, + *args): metric_dict = dict() - - choosen_indices = paddle.argsort(similarities_matrix, axis=1, descending=True) - gallery_labels_transpose = paddle.transpose(gallery_img_id, [1,0]) - gallery_labels_transpose = paddle.broadcast_to(gallery_labels_transpose, shape=[choosen_indices.shape[0], gallery_labels_transpose.shape[1]]) - choosen_label = paddle.index_sample(gallery_labels_transpose, choosen_indices) + + choosen_indices = paddle.argsort( + similarities_matrix, axis=1, descending=True) + gallery_labels_transpose = paddle.transpose(gallery_img_id, [1, 0]) + gallery_labels_transpose = paddle.broadcast_to( + gallery_labels_transpose, + shape=[ + choosen_indices.shape[0], gallery_labels_transpose.shape[1] + ]) + choosen_label = paddle.index_sample(gallery_labels_transpose, + choosen_indices) tmp = paddle.equal(choosen_label, query_img_id) tmp = paddle.cast(tmp, 'float64') #do accumulative sum div = paddle.arange(tmp.shape[1]).astype("float64") + 2 - minus = paddle.divide(tmp, div) - auxilary = paddle.subtract(tmp, minus) + minus = paddle.divide(tmp, div) + auxilary = paddle.subtract(tmp, minus) hard_index = paddle.argmax(auxilary, axis=1).astype("float64") all_INP = paddle.divide(paddle.sum(tmp, axis=1), hard_index) mINP = paddle.mean(all_INP) metric_dict["mINP"] = mINP.numpy()[0] return metric_dict + class Recallk(nn.Layer): def __init__(self, topk=(1, 5)): super().__init__() @@ -90,25 +109,43 @@ class Recallk(nn.Layer): topk = [topk] self.topk = topk - def forward(self, similarities_matrix, query_img_id, gallery_img_id): + def forward(self, similarities_matrix, query_img_id, gallery_img_id, + keep_mask): metric_dict = dict() #get cmc - choosen_indices = paddle.argsort(similarities_matrix, axis=1, descending=True) - gallery_labels_transpose = paddle.transpose(gallery_img_id, [1,0]) - gallery_labels_transpose = paddle.broadcast_to(gallery_labels_transpose, shape=[choosen_indices.shape[0], gallery_labels_transpose.shape[1]]) - choosen_label = paddle.index_sample(gallery_labels_transpose, choosen_indices) + choosen_indices = paddle.argsort( + similarities_matrix, axis=1, descending=True) + gallery_labels_transpose = paddle.transpose(gallery_img_id, [1, 0]) + gallery_labels_transpose = paddle.broadcast_to( + gallery_labels_transpose, + shape=[ + choosen_indices.shape[0], gallery_labels_transpose.shape[1] + ]) + choosen_label = paddle.index_sample(gallery_labels_transpose, + choosen_indices) equal_flag = paddle.equal(choosen_label, query_img_id) + if keep_mask is not None: + keep_mask = paddle.index_sample( + keep_mask.astype('float32'), choosen_indices) + equal_flag = paddle.logical_and(equal_flag, + keep_mask.astype('bool')) equal_flag = paddle.cast(equal_flag, 'float32') - + real_query_num = paddle.sum(equal_flag, axis=1) + real_query_num = paddle.sum( + paddle.greater_than(real_query_num, paddle.to_tensor(0.)).astype( + "float32")) + acc_sum = paddle.cumsum(equal_flag, axis=1) - mask = paddle.greater_than(acc_sum, paddle.to_tensor(0.)).astype("float32") - all_cmc = paddle.mean(mask, axis=0).numpy() + mask = paddle.greater_than(acc_sum, + paddle.to_tensor(0.)).astype("float32") + all_cmc = (paddle.sum(mask, axis=0) / real_query_num).numpy() for k in self.topk: metric_dict["recall{}".format(k)] = all_cmc[k - 1] return metric_dict + class DistillationTopkAcc(TopkAcc): def __init__(self, model_key, feature_key=None, topk=(1, 5)): super().__init__(topk=topk) @@ -132,4 +169,3 @@ class GoogLeNetTopkAcc(TopkAcc): def forward(self, x, label): return super().forward(x[0], label) - -- GitLab