{"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_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"\n\n\n\n","metadata":{}},{"cell_type":"code","source":"import numpy as np, pandas as pd\nfrom glob import glob\nimport shutil, os\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import GroupKFold\nfrom tqdm.notebook import tqdm\nimport seaborn as sns\nimport torch\nimport os\nimport numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nfrom glob import glob","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:30.020515Z","iopub.execute_input":"2022-01-18T07:23:30.020800Z","iopub.status.idle":"2022-01-18T07:23:32.338281Z","shell.execute_reply.started":"2022-01-18T07:23:30.020702Z","shell.execute_reply":"2022-01-18T07:23:32.337560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!mkdir -p /root/.config/Ultralytics\n!cp /kaggle/input/yolov5/starfish_yolov5/Arial.ttf /root/.config/Ultralytics/","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:32.340823Z","iopub.execute_input":"2022-01-18T07:23:32.341306Z","iopub.status.idle":"2022-01-18T07:23:33.708940Z","shell.execute_reply.started":"2022-01-18T07:23:32.341268Z","shell.execute_reply":"2022-01-18T07:23:33.707334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"shutil.copytree('/kaggle/input/yolov5/starfish_yolov5', '/kaggle/working/yolov5/starfish_yolov5')\nos.chdir('/kaggle/working/yolov5/starfish_yolov5') # install dependencies","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:33.711363Z","iopub.execute_input":"2022-01-18T07:23:33.711951Z","iopub.status.idle":"2022-01-18T07:23:34.406615Z","shell.execute_reply.started":"2022-01-18T07:23:33.711910Z","shell.execute_reply":"2022-01-18T07:23:34.405834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"file = open(\"/kaggle/input/starfish-fold/video/video/val_video1.txt\")\nlines = file.readlines()\n# ../input/starfish-fold/video/video/val_video1.txt","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:34.410505Z","iopub.execute_input":"2022-01-18T07:23:34.410761Z","iopub.status.idle":"2022-01-18T07:23:34.429201Z","shell.execute_reply.started":"2022-01-18T07:23:34.410719Z","shell.execute_reply":"2022-01-18T07:23:34.428535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile fold0.yaml\n\nnames: [starfish]\nnc: 1\ntrain: '/kaggle/input/starfish-fold/video/video/val_video1.txt'\nval: '/kaggle/input/starfish-fold/video/video/val_video1.txt'","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:34.431404Z","iopub.execute_input":"2022-01-18T07:23:34.432002Z","iopub.status.idle":"2022-01-18T07:23:34.438566Z","shell.execute_reply.started":"2022-01-18T07:23:34.431965Z","shell.execute_reply":"2022-01-18T07:23:34.437705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ../input/reef-baseline-fold12/l6_3600_uflip_vm5_f12_up/f1/best.pt","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:34.439700Z","iopub.execute_input":"2022-01-18T07:23:34.440022Z","iopub.status.idle":"2022-01-18T07:23:34.446543Z","shell.execute_reply.started":"2022-01-18T07:23:34.439990Z","shell.execute_reply":"2022-01-18T07:23:34.445863Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**copy from  yolov5/val.py**","metadata":{}},{"cell_type":"code","source":"import argparse\nimport json\nimport os\nimport sys\nfrom pathlib import Path\nfrom threading import Thread\nimport numpy as np\nimport torch\nfrom tqdm import tqdm\n\nROOT= '/kaggle/working/yolov5/starfish_yolov5/'\nif str(ROOT) not in sys.path:\n    sys.path.append(str(ROOT)) \n\nfrom models.experimental import attempt_load\nfrom utils.datasets import create_dataloader\nfrom utils.general import coco80_to_coco91_class, check_dataset, check_img_size, check_requirements, \\\n    check_suffix, check_yaml, box_iou, non_max_suppression, scale_coords, xyxy2xywh, xywh2xyxy, set_logging, \\\n    increment_path, colorstr, print_args\nfrom utils.metrics import ap_per_class, ConfusionMatrix\nfrom utils.plots import output_to_target, plot_images, plot_val_study\nfrom utils.torch_utils import select_device, time_sync\nfrom utils.callbacks import Callbacks\n\ndef save_one_txt(predn, save_conf, shape, file):\n    # Save one txt result\n    gn = torch.tensor(shape)[[1, 0, 1, 0]]  # normalization gain whwh\n    for *xyxy, conf, cls in predn.tolist():\n        xywh = (xyxy2xywh(torch.tensor(xyxy).view(1, 4)) / gn).view(-1).tolist()  # normalized xywh\n        line = (cls, *xywh, conf) if save_conf else (cls, *xywh)  # label format\n        with open(file, 'a') as f:\n            f.write(('%g ' * len(line)).rstrip() % line + '\\n')\n\n\ndef save_one_json(predn, jdict, path, class_map):\n    # Save one JSON result {\"image_id\": 42, \"category_id\": 18, \"bbox\": [258.15, 41.29, 348.26, 243.78], \"score\": 0.236}\n    image_id = int(path.stem) if path.stem.isnumeric() else path.stem\n    box = xyxy2xywh(predn[:, :4])  # xywh\n    box[:, :2] -= box[:, 2:] / 2  # xy center to top-left corner\n    for p, b in zip(predn.tolist(), box.tolist()):\n        jdict.append({'image_id': image_id,\n                      'category_id': class_map[int(p[5])],\n                      'bbox': [round(x, 3) for x in b],\n                      'score': round(p[4], 5)})\n\n\ndef process_batch(detections, labels, iouv):\n    \"\"\"\n    Return correct predictions matrix. Both sets of boxes are in (x1, y1, x2, y2) format.\n    Arguments:\n        detections (Array[N, 6]), x1, y1, x2, y2, conf, class\n        labels (Array[M, 5]), class, x1, y1, x2, y2\n    Returns:\n        correct (Array[N, 10]), for 10 IoU levels\n    \"\"\"\n    correct = torch.zeros(detections.shape[0], iouv.shape[0], dtype=torch.bool, device=iouv.device)\n    iou = box_iou(labels[:, 1:], detections[:, :4])\n    x = torch.where((iou >= iouv[0]) & (labels[:, 0:1] == detections[:, 5]))  # IoU above threshold and classes match\n    if x[0].shape[0]:\n        matches = torch.cat((torch.stack(x, 1), iou[x[0], x[1]][:, None]), 1).cpu().numpy()  # [label, detection, iou]\n        if x[0].shape[0] > 1:\n            matches = matches[matches[:, 2].argsort()[::-1]]\n            matches = matches[np.unique(matches[:, 1], return_index=True)[1]]\n            # matches = matches[matches[:, 2].argsort()[::-1]]\n            matches = matches[np.unique(matches[:, 0], return_index=True)[1]]\n        matches = torch.Tensor(matches).to(iouv.device)\n        correct[matches[:, 1].long()] = matches[:, 2:3] >= iouv\n    return correct","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:34.448127Z","iopub.execute_input":"2022-01-18T07:23:34.448661Z","iopub.status.idle":"2022-01-18T07:23:35.002791Z","shell.execute_reply.started":"2022-01-18T07:23:34.448624Z","shell.execute_reply":"2022-01-18T07:23:35.002051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ../input/starfish-yolo/best_fold1_f2_64017.pt\n@torch.no_grad()\ndef run(data = '/kaggle/working/yolov5/starfish_yolov5/fold0.yaml',\n        weights='/kaggle/input/reef-baseline-fold12/l6_3600_uflip_vm5_f12_up/f1/best.pt',  # model.pt path(s)\n        batch_size=2,  # batch size\n        imgsz=9000,  # inference size (pixels)\n        conf_thres=0.001,  # confidence threshold\n        iou_thres=0.45,  # NMS IoU threshold\n        task='val',  # train, val, test, speed or study\n        device='0',  # cuda device, i.e. 0 or 0,1,2,3 or cpu\n        single_cls=False,  # treat as single-class dataset\n        augment=True,  # augmented inference\n        verbose=False,  # verbose output\n        save_txt=False,  # save results to *.txt\n        save_hybrid=False,  # save label+prediction hybrid results to *.txt\n        save_conf=False,  # save confidences in --save-txt labels\n        save_json=False,  # save a COCO-JSON results file\n        project=ROOT + 'runs/val',  # save to project/name\n        name='exp',  # save to project/name\n        exist_ok=False,  # existing project/name ok, do not increment\n        half=True,  # use FP16 half-precision inference\n        model=None,\n        dataloader=None,\n        save_dir=Path(''),\n        plots=True,\n        callbacks=Callbacks(),\n        compute_loss=None,\n        ):\n    # Initialize/load model and set device\n    training = model is not None\n    if training:  # called by train.py\n        device = next(model.parameters()).device  # get model device\n\n    else:  # called directly\n        device = select_device(device, batch_size=batch_size)\n\n        # Directories\n        save_dir = increment_path(Path(project) / name, exist_ok=exist_ok)  # increment run\n        (save_dir / 'labels' if save_txt else save_dir).mkdir(parents=True, exist_ok=True)  # make dir\n\n        # Load model\n        check_suffix(weights, '.pt')\n        model = attempt_load(weights, map_location=device)  # load FP32 model\n        gs = max(int(model.stride.max()), 32)  # grid size (max stride)\n        imgsz = check_img_size(imgsz, s=gs)  # check image size\n\n        # Multi-GPU disabled, incompatible with .half() https://github.com/ultralytics/yolov5/issues/99\n        # if device.type != 'cpu' and torch.cuda.device_count() > 1:\n        #     model = nn.DataParallel(model)\n\n        # Data\n        data = check_dataset(data)  # check\n\n    # Half\n    half &= device.type != 'cpu'  # half precision only supported on CUDA\n    model.half() if half else model.float()\n\n    # Configure\n    model.eval()\n    is_coco = isinstance(data.get('val'), str) and data['val'].endswith('coco/val2017.txt')  # COCO dataset\n    nc = 1 if single_cls else int(data['nc'])  # number of classes\n    iouv = torch.linspace(0.3, 0.8, 11).to(device)  # iou vector for mAP@0.5:0.95\n    niou = iouv.numel()\n\n    # Dataloader\n    if not training:\n        if device.type != 'cpu':\n            model(torch.zeros(1, 3, imgsz, imgsz).to(device).type_as(next(model.parameters())))  # run once\n        pad = 0.0 if task == 'speed' else 0.5\n        task = task if task in ('train', 'val', 'test') else 'val'  # path to train/val/test images\n        dataloader = create_dataloader(data[task], imgsz, batch_size, gs, single_cls, pad=pad, rect=True,\n                                       prefix=colorstr(f'{task}: '))[0]\n\n    seen = 0\n    confusion_matrix = ConfusionMatrix(nc=nc)\n    names = {k: v for k, v in enumerate(model.names if hasattr(model, 'names') else model.module.names)}\n    class_map = coco80_to_coco91_class() if is_coco else list(range(1000))\n    s = ('%20s' + '%11s' * 6) % ('Class', 'Images', 'Labels', 'P', 'R', 'mAP@.5', 'mAP@.5:.95')\n    dt, p, r, f1, mp, mr, map50, map = [0.0, 0.0, 0.0], 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0\n    loss = torch.zeros(3, device=device)\n    jdict, stats, ap, ap_class = [], [], [], []\n    for batch_i, (img, targets, paths, shapes) in enumerate(tqdm(dataloader, desc=s)):\n        t1 = time_sync()\n        img = img.to(device, non_blocking=True)\n        img = img.half() if half else img.float()  # uint8 to fp16/32\n        img /= 255.0  # 0 - 255 to 0.0 - 1.0\n        targets = targets.to(device)\n        nb, _, height, width = img.shape  # batch size, channels, height, width\n        t2 = time_sync()\n        dt[0] += t2 - t1\n\n        # Run model\n        out, train_out = model(img, augment=augment)  # inference and training outputs\n        dt[1] += time_sync() - t2\n\n        # Compute loss\n        if compute_loss:\n            loss += compute_loss([x.float() for x in train_out], targets)[1]  # box, obj, cls\n\n        # Run NMS\n        targets[:, 2:] *= torch.Tensor([width, height, width, height]).to(device)  # to pixels\n        lb = [targets[targets[:, 0] == i, 1:] for i in range(nb)] if save_hybrid else []  # for autolabelling\n        t3 = time_sync()\n        out = non_max_suppression(out, conf_thres, iou_thres, labels=lb, multi_label=True, agnostic=single_cls)\n        dt[2] += time_sync() - t3\n\n        # Statistics per image\n        for si, pred in enumerate(out):\n            labels = targets[targets[:, 0] == si, 1:]\n            nl = len(labels)\n            tcls = labels[:, 0].tolist() if nl else []  # target class\n            path, shape = Path(paths[si]), shapes[si][0]\n            seen += 1\n\n            if len(pred) == 0:\n                if nl:\n                    stats.append((torch.zeros(0, niou, dtype=torch.bool), torch.Tensor(), torch.Tensor(), tcls))\n                continue\n\n            # Predictions\n            if single_cls:\n                pred[:, 5] = 0\n            predn = pred.clone()\n            scale_coords(img[si].shape[1:], predn[:, :4], shape, shapes[si][1])  # native-space pred\n\n            # Evaluate\n            if nl:\n                tbox = xywh2xyxy(labels[:, 1:5])  # target boxes\n                scale_coords(img[si].shape[1:], tbox, shape, shapes[si][1])  # native-space labels\n                labelsn = torch.cat((labels[:, 0:1], tbox), 1)  # native-space labels\n                correct = process_batch(predn, labelsn, iouv)\n                if plots:\n                    confusion_matrix.process_batch(predn, labelsn)\n            else:\n                correct = torch.zeros(pred.shape[0], niou, dtype=torch.bool)\n            stats.append((correct.cpu(), pred[:, 4].cpu(), pred[:, 5].cpu(), tcls))  # (correct, conf, pcls, tcls)\n\n            # Save/log\n            if save_txt:\n                save_one_txt(predn, save_conf, shape, file=save_dir / 'labels' / (path.stem + '.txt'))\n            if save_json:\n                save_one_json(predn, jdict, path, class_map)  # append to COCO-JSON dictionary\n            callbacks.run('on_val_image_end', pred, predn, path, names, img[si])\n\n        # Plot images\n        if plots and batch_i < 3:\n            f = save_dir / f'val_batch{batch_i}_labels.jpg'  # labels\n            Thread(target=plot_images, args=(img, targets, paths, f, names), daemon=True).start()\n            f = save_dir / f'val_batch{batch_i}_pred.jpg'  # predictions\n            Thread(target=plot_images, args=(img, output_to_target(out), paths, f, names), daemon=True).start()\n\n    # Compute statistics\n    stats = [np.concatenate(x, 0) for x in zip(*stats)]  # to numpy\n    if len(stats) and stats[0].any():\n        p, r, ap, f2, ap_class,conf_i = ap_per_class(*stats, plot=plots, save_dir=save_dir, names=names)\n        ap50, ap = ap[:, 4], ap.mean(1)  # AP@0.5, AP@0.5:0.95\n        mp, mr, map50, map = p.mean(), r.mean(), ap50.mean(), ap.mean()\n        nt = np.bincount(stats[3].astype(np.int64), minlength=nc)  # number of targets per class\n    else:\n        nt = torch.zeros(1)\n\n    # Print results\n    pf = '%20s' + '%11i' * 2 + '%11.3g' * 4  # print format\n    print(pf % ('all', seen, nt.sum(), mp, mr, map50, map))\n    print('conf:' + str(conf_i*0.001))\n    f2 = f2[0]\n    print('f2-score:'+str(f2))\n\n    # Print results per class\n    if (verbose or (nc < 50 and not training)) and nc > 1 and len(stats):\n        for i, c in enumerate(ap_class):\n            print(pf % (names[c], seen, nt[c], p[i], r[i], ap50[i], ap[i]))\n\n    # Print speeds\n    t = tuple(x / seen * 1E3 for x in dt)  # speeds per image\n    if not training:\n        shape = (batch_size, 3, imgsz, imgsz)\n        print(f'Speed: %.1fms pre-process, %.1fms inference, %.1fms NMS per image at shape {shape}' % t)\n\n    # Plots\n    if plots:\n        confusion_matrix.plot(save_dir=save_dir, names=list(names.values()))\n        callbacks.run('on_val_end')\n\n    # Save JSON\n    if save_json and len(jdict):\n        w = Path(weights[0] if isinstance(weights, list) else weights).stem if weights is not None else ''  # weights\n        anno_json = str(Path(data.get('path', '../coco')) / 'annotations/instances_val2017.json')  # annotations json\n        pred_json = str(save_dir / f\"{w}_predictions.json\")  # predictions json\n        print(f'\\nEvaluating pycocotools mAP... saving {pred_json}...')\n        with open(pred_json, 'w') as f:\n            json.dump(jdict, f)\n\n        try:  # https://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocoEvalDemo.ipynb\n            check_requirements(['pycocotools'])\n            from pycocotools.coco import COCO\n            from pycocotools.cocoeval import COCOeval\n\n            anno = COCO(anno_json)  # init annotations api\n            pred = anno.loadRes(pred_json)  # init predictions api\n            eval = COCOeval(anno, pred, 'bbox')\n            if is_coco:\n                eval.params.imgIds = [int(Path(x).stem) for x in dataloader.dataset.img_files]  # image IDs to evaluate\n            eval.evaluate()\n            eval.accumulate()\n            eval.summarize()\n            map, map50 = eval.stats[:2]  # update results (mAP@0.5:0.95, mAP@0.5)\n        except Exception as e:\n            print(f'pycocotools unable to run: {e}')\n\n    # Return results\n    model.float()  # for training\n    if not training:\n        s = f\"\\n{len(list(save_dir.glob('labels/*.txt')))} labels saved to {save_dir / 'labels'}\" if save_txt else ''\n        print(f\"Results saved to {colorstr('bold', save_dir)}{s}\")\n    maps = np.zeros(nc) + map\n    for i, c in enumerate(ap_class):\n        maps[c] = ap[i]\n    return (mp, mr, map50, map, *(loss.cpu() / len(dataloader)).tolist()), maps, t,f2,conf_i","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:35.005225Z","iopub.execute_input":"2022-01-18T07:23:35.005668Z","iopub.status.idle":"2022-01-18T07:23:35.054576Z","shell.execute_reply.started":"2022-01-18T07:23:35.005634Z","shell.execute_reply":"2022-01-18T07:23:35.053636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results, maps, _,f2,conf_i = run()","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:23:35.056046Z","iopub.execute_input":"2022-01-18T07:23:35.056382Z","iopub.status.idle":"2022-01-18T07:24:44.316779Z","shell.execute_reply.started":"2022-01-18T07:23:35.056344Z","shell.execute_reply":"2022-01-18T07:24:44.315178Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''mp, mr, map50, map0.3:0.8'''\nresults ","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:24:44.318285Z","iopub.status.idle":"2022-01-18T07:24:44.318958Z","shell.execute_reply.started":"2022-01-18T07:24:44.318705Z","shell.execute_reply":"2022-01-18T07:24:44.318746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"best_conf = conf_i*0.001\nbest_conf ","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:24:44.320239Z","iopub.status.idle":"2022-01-18T07:24:44.320896Z","shell.execute_reply.started":"2022-01-18T07:24:44.320642Z","shell.execute_reply":"2022-01-18T07:24:44.320666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f2","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:24:44.322122Z","iopub.status.idle":"2022-01-18T07:24:44.322774Z","shell.execute_reply.started":"2022-01-18T07:24:44.322510Z","shell.execute_reply":"2022-01-18T07:24:44.322533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''1.Change yolov5/utils/metrics.py  ,ap_per_class()'''","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:24:44.323979Z","iopub.status.idle":"2022-01-18T07:24:44.324650Z","shell.execute_reply.started":"2022-01-18T07:24:44.324388Z","shell.execute_reply":"2022-01-18T07:24:44.324412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# '''\n# def ap_per_class(tp, conf, pred_cls, target_cls, plot=False, save_dir='.', names=()):\n#     \"\"\" Compute the average precision, given the recall and precision curves.\n#     Source: https://github.com/rafaelpadilla/Object-Detection-Metrics.\n#     # Arguments\n#         tp:  True positives (nparray, nx1 or nx10).\n#         conf:  Objectness value from 0-1 (nparray).\n#         pred_cls:  Predicted object classes (nparray).\n#         target_cls:  True object classes (nparray).\n#         plot:  Plot precision-recall curve at mAP@0.5\n#         save_dir:  Plot save directory\n#     # Returns\n#         The average precision as computed in py-faster-rcnn.\n#     \"\"\"\n\n#     # Sort by objectness\n#     i = np.argsort(-conf)\n#     tp, conf, pred_cls = tp[i], conf[i], pred_cls[i]\n\n#     # Find unique classes\n#     unique_classes = np.unique(target_cls)\n#     nc = unique_classes.shape[0]  # number of classes, number of detections\n\n#     # Create Precision-Recall curve and compute AP for each class\n#     px, py = np.linspace(0, 1, 1000), []  # for plotting\n#     ap, p, r = np.zeros((nc, tp.shape[1])), np.zeros((nc, 1000)), np.zeros((nc, 1000))\n#     m_f2 = []\n#     for ci, c in enumerate(unique_classes):\n#         i = pred_cls == c\n#         n_l = (target_cls == c).sum()  # number of labels\n#         n_p = i.sum()  # number of predictions\n\n#         if n_p == 0 or n_l == 0:\n#             continue\n#         else:\n#             # Accumulate FPs and TPs\n#             fpc = (1 - tp[i]).cumsum(0)\n#             tpc = tp[i].cumsum(0)\n\n#             # Recall\n#             recall = tpc / (n_l + 1e-16)  # recall curve\n#             r[ci] = np.interp(-px, -conf[i], recall[:, 4], left=0)  # negative x, xp because xp decreases\n\n#             # Precision\n#             precision = tpc / (tpc + fpc)  # precision curve\n#             p[ci] = np.interp(-px, -conf[i], precision[:, 4], left=1)  # p at pr_score\n\n#             '''计算mean-f2'''\n#             for j in range(tp.shape[1]):\n#                 '''遍历iou 0.3~0.8，计算对应的f2'''\n#                 # Recall\n#                 recall = tpc / (n_l + 1e-16)  # recall curve\n#                 current_p = np.interp(-px, -conf[i], precision[:, j], left=0)# negative x, xp because xp decreases\n\n#                 # Precision\n#                 precision = tpc / (tpc + fpc)  # precision curve\n#                 current_r = np.interp(-px, -conf[i], recall[:, j], left=1)\n\n#                 '''对应当前iou下的f2'''\n#                 current_f2 = 5 * (current_p * current_r) / (4 * current_p + current_r + 1e-16)\n#                 m_f2.append(current_f2)\n\n#             '''此时m_f2尺寸为[11,1000]'''\n#             m_f2 = np.array(m_f2)\n\n#             '''在11的这个维度上取平均，得到F2-socre[0.3,0.8]'''\n#             m_f2=np.mean(m_f2, axis=0)\n#             '''变换形状，方便计算最大值'''\n#             m_f2=m_f2.reshape(1, 1000)\n\n#             # AP from recall-precision curve\n#             for j in range(tp.shape[1]):\n#                 ap[ci, j], mpre, mrec = compute_ap(recall[:, j], precision[:, j])\n\n#                 if plot and j == 0:\n#                     py.append(np.interp(px, mrec, mpre))  # precision at mAP@0.5\n\n#     # Compute F1 (harmonic mean of precision and recall)\n#     f1 = 2 * p * r / (p + r + 1e-16)\n\n#     if plot:\n#         plot_pr_curve(px, py, ap, Path(save_dir) / 'PR_curve.png', names)\n#         plot_mc_curve(px, f1, Path(save_dir) / 'F1_curve.png', names, ylabel='F1')\n#         plot_mc_curve(px, m_f2, Path(save_dir) / 'meanF2_curve.png', names, ylabel='mF2')\n#         plot_mc_curve(px, p, Path(save_dir) / 'P_curve.png', names, ylabel='Precision')\n#         plot_mc_curve(px, r, Path(save_dir) / 'R_curve.png', names, ylabel='Recall')\n\n#     # i = f1.mean(0).argmax()  # max F1 index\n#     i = m_f2.mean(0).argmax()\n#     return p[:, i], r[:, i], ap, m_f2[:, i], unique_classes.astype('int32'),i\n# '''","metadata":{"execution":{"iopub.status.busy":"2022-01-18T07:24:44.325995Z","iopub.status.idle":"2022-01-18T07:24:44.326625Z","shell.execute_reply.started":"2022-01-18T07:24:44.326377Z","shell.execute_reply":"2022-01-18T07:24:44.326401Z"},"trusted":true},"execution_count":null,"outputs":[]}]}