{"cells":[{"metadata":{},"cell_type":"markdown","source":"This notebook shows numpy version of calculating map in this competition\n\nI have taken one example from https://www.kaggle.com/pestipeti/competition-metric-details-script and it seems that my code have same result with this code.\n\nCouple things you need to do before run the function : \n\n(1) The boxes should be sorted by their score \n\n(2) Convert the format of boxes to (xmin,ymin,xmax,ymax)\n\n(3) Make sure your gt boxes were not transformed by your Dataset,I spent a while debugging the code and realizing my gt boxes were transformed(Resize and ToTensor)....\n\nI put some explanation to help you understand my algorithm.I did not test otehr cases except the one I mentioned above.\n\n","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np ","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"def calc_ap(preds,gt_boxes,iou_thresholds = np.linspace(0.5,0.75,6)):\n    ap = 0.\n    n = len(iou_thresholds)\n    \n    for iou_threshold in  iou_thresholds:\n        \n        #calculate iou\n        inter_xmax = np.minimum(preds[:,None,2],gt_boxes[:,2])\n        inter_ymax = np.minimum(preds[:,None,3],gt_boxes[:,3])\n        inter_xmin = np.maximum(preds[:,None,0],gt_boxes[:,0])\n        inter_ymin = np.maximum(preds[:,None,1],gt_boxes[:,1])\n\n        w = (inter_xmax-inter_xmin+1).clip(0.)\n        h = (inter_ymax-inter_ymin+1).clip(0.)\n\n        inter_area = w*h\n\n        gt_area = (gt_boxes[:,2]-gt_boxes[:,0]+1) * (gt_boxes[:,3]-gt_boxes[:,1]+1)\n\n        preds_area = (preds[:,2]-preds[:,0]+1) * (preds[:,3]-preds[:,1]+1)\n        \n        #iou shape (28,20)\n        #In matrix iou ,each row(prediction) has iou value with every gt\n        iou = inter_area/(gt_area+preds_area[:,None]-inter_area)\n        \n        gt_to_match = np.zeros(gt_boxes.shape[0])\n        \n        #pick the one with highest iou with gt\n        arg_max = np.argmax(iou,axis = -1)\n        \n        \n        #if the highest iou is less than threshold, constider it as false positive \n        fp_idx = np.where(iou[np.arange(arg_max.shape[0]),arg_max]<iou_threshold)\n\n        fp = len(fp_idx[0])\n        \n        #discard these false positive predictions \n        iou = np.delete(iou,fp_idx,axis = 0)\n        \n        #since we have deleted the boxes that are invalid,the rest woud just be counted as tp\n        arg_max = np.argmax(iou,axis = -1)\n        \n        #However,for some cases ,there are more than one predictions match for one gt\n        #we need to count extra ones as fp \n        tp_arg_max_filter  = np.unique(arg_max)\n        \n        gt_to_match[tp_arg_max_filter] = 1\n\n        tp = len(tp_arg_max_filter)\n\n        fp+=(len(arg_max)-tp)\n        #check if there's box that no prediction match.\n        fn = len(np.where(gt_to_match==0.)[0])\n\n        ap+= tp / (tp + fp + fn)\n        \n    return ap/n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"gt_boxes = np.array([[954, 391,  70,  90],\n                    [660, 220,  95, 102],\n                    [ 64, 209,  76,  57],\n                    [896,  99, 102,  69],\n                    [747, 460,  72,  77],\n                    [885, 163, 103,  69],\n                    [514, 399,  90,  97],\n                    [702, 794,  97,  99],\n                    [721, 624,  98, 108],\n                    [826, 512,  82,  94],\n                    [883, 944,  79,  74],\n                    [247, 594, 123,  92],\n                    [673, 514,  95, 113],\n                    [829, 847, 102, 110],\n                    [ 94, 737,  92, 107],\n                    [588, 568,  75, 107],\n                    [158, 890, 103,  64],\n                    [744, 906,  75,  79],\n                    [826,  33,  72,  74],\n                    [601,  69,  67,  87]])\npreds = np.array([[956, 409, 68, 85],\n                [883, 945, 85, 77],\n                [745, 468, 81, 87],\n                [658, 239, 103, 105],\n                [518, 419, 91, 100],\n                [711, 805, 92, 106],\n                [62, 213, 72, 64],\n                [884, 175, 109, 68],\n                [721, 626, 96, 104],\n                [878, 619, 121, 81],\n                [887, 107, 111, 71],\n                [827, 525, 88, 83],\n                [816, 868, 102, 86],\n                [166, 882, 78, 75],\n                [603, 563, 78, 97],\n                [744, 916, 68, 52],\n                [582, 86, 86, 72],\n                [79, 715, 91, 101],\n                [246, 586, 95, 80],\n                [181, 512, 93, 89],\n                [655, 527, 99, 90],\n                [568, 363, 61, 76],\n                [9, 717, 152, 110],\n                [576, 698, 75, 78],\n                [805, 974, 75, 50],\n                [10, 15, 78, 64],\n                [826, 40, 69, 74],\n                [32, 983, 106, 40]]\n                )\nscores = np.array([0.9932319, 0.99206185, 0.99145633, 0.9898089, 0.98906296, 0.9817738,\n                0.9799762, 0.97967803, 0.9771589, 0.97688967, 0.9562935, 0.9423076,\n                0.93556845, 0.9236257, 0.9102379, 0.88644403, 0.8808225, 0.85238415,\n                0.8472188, 0.8417798, 0.79908705, 0.7963756, 0.7437897, 0.6044758,\n                0.59249884, 0.5557045, 0.53130984, 0.5020239])\n\n\nscores_idx = np.argsort(scores)[::-1]\npreds = preds[scores_idx]\npreds[:,2] = preds[:,2] + preds[:,0]\npreds[:,3] = preds[:,3] + preds[:,1]\ngt_boxes[:,2] = gt_boxes[:,2] + gt_boxes[:,0]\ngt_boxes[:,3] = gt_boxes[:,3] + gt_boxes[:,1]\n\ncalc_ap(preds,gt_boxes)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"This is my first share notebook,If you enjoy reading and find this notebook helpful,that would make my day!\n\nI write the code on my own,maybe there's something wrong in my code,\nPlease correct me if you find any mistake!Thanks!","execution_count":null}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}