metrics.py 5.2 KB
Newer Older
W
weishengyu 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
# copyright (c) 2021 PaddlePaddle Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import numpy as np
import paddle
import paddle.nn as nn

W
weishengyu 已提交
19
class TopkAcc(nn.Layer):
W
weishengyu 已提交
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
    def __init__(self, topk=(1, 5)):
        super().__init__()
        assert isinstance(topk, (int, list, tuple))
        if isinstance(topk, int):
            topk = [topk]
        self.topk = topk

    def forward(self, x, label):
        if isinstance(x, dict):
            x = x["logits"]

        metric_dict = dict()
        for k in self.topk:
            metric_dict["top{}".format(k)] = paddle.metric.accuracy(
                x, label, k=k)
        return metric_dict

class mAP(nn.Layer):
D
dongshuilong 已提交
38
    def __init__(self):
W
weishengyu 已提交
39 40
        super().__init__()

B
Bin Lu 已提交
41
    def forward(self, similarities_matrix, query_img_id, gallery_img_id):
W
weishengyu 已提交
42
        metric_dict = dict()
B
Bin Lu 已提交
43 44
        
        choosen_indices = paddle.argsort(similarities_matrix, axis=1, descending=True) 
B
Bin Lu 已提交
45
        gallery_labels_transpose = paddle.transpose(gallery_img_id, [1,0])
B
Bin Lu 已提交
46 47
        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)        
B
Bin Lu 已提交
48
        equal_flag = paddle.equal(choosen_label, query_img_id)
B
Bin Lu 已提交
49 50 51 52 53 54 55 56 57 58
        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)

        #calc map
        precision_mask = paddle.multiply(equal_flag, precision)
        ap = paddle.sum(precision_mask, axis=1) / paddle.sum(equal_flag, axis=1)
        metric_dict["mAP"] = paddle.mean(ap).numpy()[0]
W
weishengyu 已提交
59 60 61
        return metric_dict

class mINP(nn.Layer):
D
dongshuilong 已提交
62
    def __init__(self):
W
weishengyu 已提交
63 64
        super().__init__()

B
Bin Lu 已提交
65
    def forward(self, similarities_matrix, query_img_id, gallery_img_id):
W
weishengyu 已提交
66
        metric_dict = dict()
B
Bin Lu 已提交
67 68
        
        choosen_indices = paddle.argsort(similarities_matrix, axis=1, descending=True) 
B
Bin Lu 已提交
69
        gallery_labels_transpose = paddle.transpose(gallery_img_id, [1,0])
B
Bin Lu 已提交
70 71
        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)        
B
Bin Lu 已提交
72
        tmp = paddle.equal(choosen_label, query_img_id)
B
Bin Lu 已提交
73 74 75 76 77 78 79 80 81 82
        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)
        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]
W
weishengyu 已提交
83 84 85
        return metric_dict

class Recallk(nn.Layer):
D
dongshuilong 已提交
86
    def __init__(self, topk=(1, 5)):
W
weishengyu 已提交
87
        super().__init__()
B
Bin Lu 已提交
88
        assert isinstance(topk, (int, list, tuple))
W
weishengyu 已提交
89 90 91 92
        if isinstance(topk, int):
            topk = [topk]
        self.topk = topk

B
Bin Lu 已提交
93
    def forward(self, similarities_matrix, query_img_id, gallery_img_id):
W
weishengyu 已提交
94
        metric_dict = dict()
B
Bin Lu 已提交
95 96 97

        #get cmc
        choosen_indices = paddle.argsort(similarities_matrix, axis=1, descending=True) 
B
Bin Lu 已提交
98
        gallery_labels_transpose = paddle.transpose(gallery_img_id, [1,0])
B
Bin Lu 已提交
99 100
        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)        
B
Bin Lu 已提交
101
        equal_flag = paddle.equal(choosen_label, query_img_id)
B
Bin Lu 已提交
102 103 104 105 106
        equal_flag = paddle.cast(equal_flag, '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() 
W
weishengyu 已提交
107 108 109 110 111

        for k in self.topk:
            metric_dict["recall{}".format(k)] = all_cmc[k - 1]
        return metric_dict

112 113 114 115 116 117 118 119 120 121 122
class DistillationTopkAcc(TopkAcc):
    def __init__(self, model_key, feature_key=None, topk=(1, 5)):
        super().__init__(topk=topk)
        self.model_key = model_key
        self.feature_key = feature_key

    def forward(self, x, label):
        x = x[self.model_key]
        if self.feature_key is not None:
            x = x[self.feature_key]
        return super().forward(x, label)
C
cuicheng01 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135


class GoogLeNetTopkAcc(TopkAcc):
    def __init__(self, topk=(1, 5)):
        super().__init__()
        assert isinstance(topk, (int, list, tuple))
        if isinstance(topk, int):
            topk = [topk]
        self.topk = topk

    def forward(self, x, label):
        return super().forward(x[0], label)