{"cells":[{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"!pip install efficientnet_pytorch\n!pip install cleanlab","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"In this Kernel, I used Confident Learning to remove some false positive in train.csv.About Confident Learning, you can check below.\n\n* 中文：https://zhuanlan.zhihu.com/p/146557232\n* English：https://arxiv.org/pdf/1911.00068.pdf\n* 日本語：https://aotamasaki.hatenablog.com/entry/confident_learning","execution_count":null},{"metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","trusted":true},"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport os\nimport re\nimport cv2\nimport matplotlib.pyplot as plt\nimport random\nfrom tqdm.notebook import tqdm\nfrom sklearn.model_selection import train_test_split\nfrom efficientnet_pytorch import EfficientNet\nfrom torch.utils.data import Dataset\nfrom torchvision import transforms\nfrom torch.optim import Adam, SGD, RMSprop\nfrom torchvision import transforms\nimport torch\nimport torch.nn as nn\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\nfrom sklearn.metrics import accuracy_score\nimport time","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 512\nnum_class = 2\nSEED = 42\ndef seed_everything(seed):\n    random.seed(seed)\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n\nseed_everything(SEED)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"def preprecess(df: pd.DataFrame) -> pd.DataFrame:\n    \"\"\"\n    https://www.kaggle.com/pestipeti/pytorch-starter-fasterrcnn-inference\n    :param df:\n    :return: df\n    \"\"\"\n    df['x'] = -1\n    df['y'] = -1\n    df['w'] = -1\n    df['h'] = -1\n\n    def expand_bbox(x):\n        r = np.array(re.findall(\"([0-9]+[.]?[0-9]*)\", x))\n        if len(r) == 0:\n            r = [-1, -1, -1, -1]\n        return r\n\n    df[['x', 'y', 'w', 'h']] = np.stack(df['bbox'].apply(lambda x: expand_bbox(x)))\n    df.drop(columns=['bbox'], inplace=True)\n    df['x'] = df['x'].astype(np.float)\n    df['y'] = df['y'].astype(np.float)\n    df['w'] = df['w'].astype(np.float)\n    df['h'] = df['h'].astype(np.float)\n\n    return df\n\ntrain = preprecess(pd.read_csv(\"../input/global-wheat-detection/train.csv\"))\ndata_dir = \"../input/global-wheat-detection/train/\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"too_small_box_df = train[(train['h'] < 10) | (train['w'] < 10)]\nprint('before remove too samll bboxes:', len(train))\ntrain = train.drop(index=too_small_box_df.index.values)\ntrain.reset_index(drop=True)\nprint('after remove too samll bboxes:', len(train))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"large_box_index = [3687,117344,173,113947,52868,2159,2169,121633,121634,147504,118211, 147552, 86917, 4412]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('before remove too large bboxes:', len(train))\ntrain = train.drop(index=large_box_index)\ntrain = train.reset_index(drop=True)\nprint('after remove too large bboxes:', len(train))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Cut Wheat","execution_count":null},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"def bbox_ioa(box1, box2):\n        # Returns the intersection over box2 area given box1, box2. box1 is 4, box2 is nx4. boxes are x1y1x2y2\n    box2 = box2.transpose()\n\n    # Get the coordinates of bounding boxes\n    b1_x1, b1_y1, b1_x2, b1_y2 = box1[0], box1[1], box1[2], box1[3]\n    b2_x1, b2_y1, b2_x2, b2_y2 = box2[0], box2[1], box2[2], box2[3]\n\n    # Intersection area\n    inter_area = (np.minimum(b1_x2, b2_x2) - np.maximum(b1_x1, b2_x1)).clip(0) * \\\n                 (np.minimum(b1_y2, b2_y2) - np.maximum(b1_y1, b2_y1)).clip(0)\n\n    # box2 area\n    box2_area = (b2_x2 - b2_x1) * (b2_y2 - b2_y1) + 1e-16\n\n    # Intersection over box2 area\n    return inter_area / box2_area","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"def create_data(df, data_dir, debug=True):\n    \n    wheat_imgs = []\n    wheat_labels = []\n    wheat_imgs_2 = []\n    wheat_labels_2 = []\n    \n    for img_id in tqdm(df[\"image_id\"].unique()):\n        \n        image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n        h, w = image.shape[:2]\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n        image /= 255.0\n        records = df[df['image_id'] == img_id]\n        boxes = records[['x', 'y', 'w', 'h']].values\n        boxes[:, 2] = boxes[:, 0] + boxes[:, 2]\n        boxes[:, 3] = boxes[:, 1] + boxes[:, 3]\n        \n        for box in boxes:\n            #create true image, wheat img and label == 1\n            img = image[int(box[1]):int(box[3]), int(box[0]):int(box[2]), :]\n            img = cv2.resize(img, (32, 32))\n            wheat_imgs.append(img)\n            wheat_labels.append(1)\n            if debug:\n                fig, ax = plt.subplots(1, 1, figsize=(2, 2))\n                plt.imshow(img)\n                plt.show()\n                debug = False\n                \n        scale = [0.25, 0.125, 0.0625] \n        \n        for i in range(len(boxes)):\n            \n            s = random.choice(scale)\n            y = random.randint(0, h)\n            x = random.randint(0, w)\n\n            y1 = np.clip(y - h*s // 2, 0, h)\n            y2 = np.clip(y1 + h*s, 0, h)\n            x1 = np.clip(x - w*s // 2, 0, w)\n            x2 = np.clip(x1 + w*s, 0, w)\n            cutout_box = np.array([x1, y1, x2, y2], dtype=np.float32)\n            \n            check = np.any(bbox_ioa(cutout_box, boxes) > 0.00) # intersection over area\n                \n            while check==True:\n                s = random.choice(scale)\n                y = random.randint(0, h)\n                x = random.randint(0, w)\n\n                y1 = np.clip(y - h*s // 2, 0, h)\n                y2 = np.clip(y1 + h*s, 0, h)\n                x1 = np.clip(x - w*s // 2, 0, w)\n                x2 = np.clip(x1 + w*s, 0, w)\n                cutout_box = np.array([x1, y1, x2, y2], dtype=np.float32)\n                check = np.any(bbox_ioa(cutout_box, boxes) > 0.1) \n                \n            img = image[int(y1):int(y2), int(x1):int(x2)]\n            img = cv2.resize(img, (32, 32))\n            wheat_imgs_2.append(img)\n            wheat_labels_2.append(0)\n            if debug:\n                fig, ax = plt.subplots(1, 1, figsize=(2, 2))\n                plt.imshow(img)\n                plt.show()\n                debug = False\n                 \n    return  np.concatenate((np.array(wheat_imgs), np.array(wheat_imgs_2)), 0), np.array(wheat_labels + wheat_labels_2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"wheat_imgs, wheat_labels = create_data(train, data_dir)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class WheatDataset(Dataset):\n    \n    def __init__(self, imgs, labels, transform=None):\n        self.imgs = imgs\n        self.labels = labels\n        self.transform = transform\n    \n    def __len__(self):\n        return len(self.imgs)\n    \n    def __getitem__(self, idx):\n        \n        label = self.labels[idx]\n        image = self.imgs[idx]\n        \n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n            \n        return image, label","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"val_transform = A.Compose([ToTensorV2(p=1.0)], p=1.0) \nvalset = WheatDataset(wheat_imgs, \n                      wheat_labels, \n                      val_transform)\nval_loader   = torch.utils.data.DataLoader(valset, \n                                           batch_size=batch_size, \n                                           shuffle=False, \n                                           num_workers=4)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"del wheat_imgs # save memory","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"max_images = 16\ngrid_width = 16\ngrid_height = int(max_images / grid_width)\nfig, axs = plt.subplots(grid_height, grid_width, figsize=(grid_width, grid_height))\n\nfor i, ax in zip(range(max_images), axs):\n    image, label = valset[i]\n    image = image.permute(1,2,0).cpu().numpy()\n    ax.imshow(image)\n    ax.set_title(label)\n    ax.axis('off')","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"trusted":true},"cell_type":"code","source":"def get_model(path):\n    model = EfficientNet.from_name('efficientnet-b0')\n    in_features = model._fc.in_features\n    model._fc   = nn.Linear(in_features, num_class)\n    model.load_state_dict(torch.load(path))\n    model.cuda()\n    \n    return model\n\nmodels = [get_model(\"../input/wheat-confident-learning/weight_acc_best_0.pt\"),\n          get_model(\"../input/wheat-confident-learning/weight_acc_best_1.pt\"),\n          get_model(\"../input/wheat-confident-learning/weight_acc_best_2.pt\"),\n          get_model(\"../input/wheat-confident-learning/weight_acc_best_3.pt\"),\n          get_model(\"../input/wheat-confident-learning/weight_acc_best_4.pt\"),\n         ]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def inference_model():\n    score = 0.\n    avg_val_loss = 0.\n    predicts = np.zeros((len(valset), 2))\n    \n   \n    with torch.no_grad():\n        for idx, (imgs, labels) in tqdm(enumerate(val_loader)):\n            start = idx * batch_size\n            end   = min(start + batch_size, len(valset))\n            imgs_vaild, labels_vaild = imgs.float().cuda(), labels.cuda()\n            \n            for model in models:\n                model.eval()\n                output_test = model(imgs_vaild)\n                output = torch.softmax(output_test, dim=1)\n                predicts[start:end, :] +=  output.detach().cpu().numpy()\n            \n    return predicts","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicts = inference_model()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicts /= 5","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicts","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Method: Prune by Class (PBC).","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Testing PBC and plotting results","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"import cleanlab\n#Prune by Class (PBC)\nbaseline_cl_pbc = cleanlab.pruning.get_noise_indices(wheat_labels, predicts, prune_method='prune_by_class')\nindex_pbc = np.where(baseline_cl_pbc[:len(train)] == True)[0].tolist()\nprint(len(index_pbc))\nprint(index_pbc)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pf_df = train.loc[index_pbc]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"pf_img_ids = pf_df['image_id'].unique()","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    \n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n    \n    \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids[12:]:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    \n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n        \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids[24:]:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    \n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n    \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids[36:]:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    \n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n    \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids[48:]:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n        \n    \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids[60:]:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    \n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n        \n    \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]},{"metadata":{"_kg_hide-input":true,"trusted":true},"cell_type":"code","source":"count = 0\nfor img_id in pf_img_ids[72:]:\n    if count == 12: break\n    \n    sub_test = pf_df[pf_df['image_id'] == img_id]\n    image = cv2.imread(f'{data_dir}/{img_id}.jpg', cv2.IMREAD_COLOR)\n    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB).astype(np.float32)\n    image /= 255.0\n    fig, ax = plt.subplots(1, 1, figsize=(16, 8))\n    \n    boxes = sub_test[['x','y', 'w', 'h']].values\n    original_boxes = train[train['image_id'] == img_id][['x','y', 'w', 'h']].values\n    \n    for box in original_boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (0, 1, 0), 2)\n    for box in boxes:\n        cv2.rectangle(image, (int(box[0]), int(box[1])), (int(box[0]+box[2]), int(box[1]+box[3])), (1, 0, 0), 2)\n    \n    ax.set_axis_off()\n    ax.set_title(img_id)\n    ax.imshow(image);\n    \n    count += 1","execution_count":null,"outputs":[]}],"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}