{"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":"code","source":"import numpy as np\nimport pandas as pd\nimport torch\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport ast\nimport sys\neffdet_path = \"../input/effdet\"\nsys.path.append(effdet_path)\ntimm_path = \"../input/timm-pytorch-image-models/pytorch-image-models-master\"\nsys.path.append(timm_path)\nimport timm\nfrom timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport sklearn\nimport os\nfrom tqdm.notebook import tqdm\nimport matplotlib.pyplot as plt\nomega_path = \"../input/omegaconf\"\nsys.path.append(omega_path)\nfrom omegaconf import OmegaConf\nimport glob\nimport sklearn\nimport math\nimport random\n\nimport cv2\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset,DataLoader\nfrom torch import optim\nfrom torchvision import transforms\n\nfrom transformers import get_cosine_schedule_with_warmup\n\nimport warnings\nwarnings.filterwarnings('ignore')\nfrom sklearn import metrics, model_selection, preprocessing\nfrom sklearn.model_selection import GroupKFold\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice\n","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:24.217913Z","iopub.execute_input":"2022-01-17T19:30:24.218259Z","iopub.status.idle":"2022-01-17T19:30:33.751400Z","shell.execute_reply.started":"2022-01-17T19:30:24.218161Z","shell.execute_reply":"2022-01-17T19:30:33.750621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install --no-deps '../input/pycocotools202/pycocotools-2.0.2-cp37-cp37m-linux_x86_64.whl' > /dev/null","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:33.753321Z","iopub.execute_input":"2022-01-17T19:30:33.753558Z","iopub.status.idle":"2022-01-17T19:30:36.121034Z","shell.execute_reply.started":"2022-01-17T19:30:33.753521Z","shell.execute_reply":"2022-01-17T19:30:36.120209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preparation","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"../input/tensorflow-great-barrier-reef/train.csv\")","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.122735Z","iopub.execute_input":"2022-01-17T19:30:36.123026Z","iopub.status.idle":"2022-01-17T19:30:36.170314Z","shell.execute_reply.started":"2022-01-17T19:30:36.122982Z","shell.execute_reply":"2022-01-17T19:30:36.169622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = df[df.annotations != '[]']\ndf = df.reset_index(drop = True)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.171728Z","iopub.execute_input":"2022-01-17T19:30:36.172165Z","iopub.status.idle":"2022-01-17T19:30:36.187457Z","shell.execute_reply.started":"2022-01-17T19:30:36.172127Z","shell.execute_reply":"2022-01-17T19:30:36.186627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['fold'] = -1\nkf = GroupKFold(n_splits = 5)\nfor fold, (train_idx, val_idx) in enumerate(kf.split(df, y = df.video_id.tolist(), groups=df.sequence)):\n    df.loc[val_idx, 'fold'] = fold\n","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.190525Z","iopub.execute_input":"2022-01-17T19:30:36.190874Z","iopub.status.idle":"2022-01-17T19:30:36.203407Z","shell.execute_reply.started":"2022-01-17T19:30:36.190843Z","shell.execute_reply":"2022-01-17T19:30:36.202761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.204713Z","iopub.execute_input":"2022-01-17T19:30:36.204958Z","iopub.status.idle":"2022-01-17T19:30:36.219490Z","shell.execute_reply.started":"2022-01-17T19:30:36.204925Z","shell.execute_reply":"2022-01-17T19:30:36.218841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.fold.value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.220520Z","iopub.execute_input":"2022-01-17T19:30:36.220906Z","iopub.status.idle":"2022-01-17T19:30:36.229463Z","shell.execute_reply.started":"2022-01-17T19:30:36.220870Z","shell.execute_reply":"2022-01-17T19:30:36.228796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['path'] = [f\"../input/tensorflow-great-barrier-reef/train_images/video_{a}/{b}.jpg\" for a,b in zip(df[\"video_id\"],df[\"video_frame\"])]\ndf['annotations'] = df['annotations'].apply(eval)\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.230505Z","iopub.execute_input":"2022-01-17T19:30:36.231243Z","iopub.status.idle":"2022-01-17T19:30:36.401215Z","shell.execute_reply.started":"2022-01-17T19:30:36.231203Z","shell.execute_reply":"2022-01-17T19:30:36.400448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IMAGE_SIZE = 320","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.402455Z","iopub.execute_input":"2022-01-17T19:30:36.402730Z","iopub.status.idle":"2022-01-17T19:30:36.406651Z","shell.execute_reply.started":"2022-01-17T19:30:36.402693Z","shell.execute_reply":"2022-01-17T19:30:36.405906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom matplotlib import patches\n\ndef get_rectangle_edges_from_pascal_bbox(bbox):\n    xmin_top_left, ymin_top_left, xmax_bottom_right, ymax_bottom_right = bbox\n\n    bottom_left = (xmin_top_left, ymax_bottom_right)\n    width = xmax_bottom_right - xmin_top_left\n    height = ymin_top_left - ymax_bottom_right\n\n    return bottom_left, width, height\n\ndef draw_pascal_voc_bboxes(\n    plot_ax,\n    bboxes,\n    get_rectangle_corners_fn=get_rectangle_edges_from_pascal_bbox,\n):\n    for bbox in bboxes:\n        bottom_left, width, height = get_rectangle_corners_fn(bbox)\n\n        rect_1 = patches.Rectangle(\n            bottom_left,\n            width,\n            height,\n            linewidth=2,\n            edgecolor=\"black\",\n            fill=False,\n        )\n        rect_2 = patches.Rectangle(\n            bottom_left,\n            width,\n            height,\n            linewidth=2,\n            edgecolor=\"red\",\n            fill=False,\n        )\n\n        # Add the patch to the Axes\n        plot_ax.add_patch(rect_1)\n        plot_ax.add_patch(rect_2)\n\ndef draw_image(\n    image, bboxes=None, draw_bboxes_fn=draw_pascal_voc_bboxes, figsize=(10, 10)\n):\n    fig, ax = plt.subplots(1, figsize=figsize)\n    ax.imshow(image)\n\n    if bboxes is not None:\n        draw_bboxes_fn(ax, bboxes)\n\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.407905Z","iopub.execute_input":"2022-01-17T19:30:36.408459Z","iopub.status.idle":"2022-01-17T19:30:36.419599Z","shell.execute_reply.started":"2022-01-17T19:30:36.408421Z","shell.execute_reply":"2022-01-17T19:30:36.418796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DataAdaptor:\n    def __init__(self,df):\n        self.df = df\n    def __len__(self):\n        return len(self.df)\n    \n    def get_boxes(self, row):\n        \"\"\"Returns the bboxes for a given row as a 3D matrix with format [x_min, y_min, x_max, y_max]\"\"\"\n        \n        boxes = pd.DataFrame(row['annotations'], columns=['x', 'y', 'width', 'height']).astype(float).values\n        \n        # Change from [x_min, y_min, w, h] to [x_min, y_min, x_max, y_max]\n        boxes[:, 2] = np.clip(boxes[:, 0] + boxes[:, 2],0,1280)\n        boxes[:, 3] = np.clip(boxes[:, 1] + boxes[:, 3],0,720) \n        \n        return boxes\n    \n    def get_image_bb(self , idx):\n        img_src = self.df.loc[idx,'path']\n        image   = cv2.imread(img_src)\n        image   = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        row     = self.df.iloc[idx]\n        bboxes  = self.get_boxes(row) \n        class_labels = np.ones(len(bboxes))\n        return image, bboxes, class_labels, idx\n    \n        \n    def show_image(self, index):\n        image, bboxes, class_labels, image_id = self.get_image_bb(index)\n        print(f\"image_id: {image_id}\")\n        draw_image(image, bboxes.tolist())\n        print(class_labels)     \n        \n        ","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.420787Z","iopub.execute_input":"2022-01-17T19:30:36.421189Z","iopub.status.idle":"2022-01-17T19:30:36.432466Z","shell.execute_reply.started":"2022-01-17T19:30:36.421147Z","shell.execute_reply":"2022-01-17T19:30:36.431744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds =DataAdaptor(df)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.433566Z","iopub.execute_input":"2022-01-17T19:30:36.433983Z","iopub.status.idle":"2022-01-17T19:30:36.449293Z","shell.execute_reply.started":"2022-01-17T19:30:36.433947Z","shell.execute_reply":"2022-01-17T19:30:36.445959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"im,bb,_,_ = train_ds.get_image_bb(4005)\nbb","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.453584Z","iopub.execute_input":"2022-01-17T19:30:36.454165Z","iopub.status.idle":"2022-01-17T19:30:36.563917Z","shell.execute_reply.started":"2022-01-17T19:30:36.454125Z","shell.execute_reply":"2022-01-17T19:30:36.562092Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_ds.show_image(4005)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:36.567959Z","iopub.execute_input":"2022-01-17T19:30:36.568502Z","iopub.status.idle":"2022-01-17T19:30:37.150227Z","shell.execute_reply.started":"2022-01-17T19:30:36.568455Z","shell.execute_reply":"2022-01-17T19:30:37.149446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Effdet Model","metadata":{}},{"cell_type":"code","source":"from effdet import create_model","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:37.151129Z","iopub.execute_input":"2022-01-17T19:30:37.151364Z","iopub.status.idle":"2022-01-17T19:30:37.649480Z","shell.execute_reply.started":"2022-01-17T19:30:37.151333Z","shell.execute_reply":"2022-01-17T19:30:37.648750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# to know more what more pretrained models you can use, see here https://github.com/rwightman/efficientdet-pytorch/blob/9cb43186711d28bd41f82f132818c65663b33c1f/effdet/config/model_config.py\n# 'tf_efficientdet_lite0' is one of the lightest model, you can use others","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:37.650684Z","iopub.execute_input":"2022-01-17T19:30:37.650938Z","iopub.status.idle":"2022-01-17T19:30:37.655371Z","shell.execute_reply.started":"2022-01-17T19:30:37.650904Z","shell.execute_reply":"2022-01-17T19:30:37.654382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model('tf_efficientdet_lite0' , bench_task='train' , num_classes= 1 , image_size=(IMAGE_SIZE,IMAGE_SIZE),bench_labeler=True,pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:37.656655Z","iopub.execute_input":"2022-01-17T19:30:37.657141Z","iopub.status.idle":"2022-01-17T19:30:39.237211Z","shell.execute_reply.started":"2022-01-17T19:30:37.657029Z","shell.execute_reply":"2022-01-17T19:30:39.236473Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset & DataLoader","metadata":{}},{"cell_type":"code","source":"\ndef train_aug():\n    return A.Compose(\n        [\n           \n            A.Resize(IMAGE_SIZE,IMAGE_SIZE ,p = 1.0),\n            A.Flip(0.5),  \n            \n       A.Normalize(mean=IMAGENET_DEFAULT_MEAN, std=IMAGENET_DEFAULT_STD),\n            ToTensorV2()\n        ],\n        p=1.0,\n        bbox_params=A.BboxParams(\n            format=\"pascal_voc\", min_area=0, min_visibility=0, label_fields=[\"labels\"]\n        ),\n    \n    )\n\n\ndef val_aug():\n    return  A.Compose(\n        [ \n            A.Resize(IMAGE_SIZE,IMAGE_SIZE ,p = 1.0),\n            A.Normalize(mean=IMAGENET_DEFAULT_MEAN, std=IMAGENET_DEFAULT_STD),\n            ToTensorV2()\n        ],\n        p=1.0,\n        bbox_params=A.BboxParams(\n            format=\"pascal_voc\", min_area=0, min_visibility=0, label_fields=[\"labels\"]\n        ),\n    )","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:39.238410Z","iopub.execute_input":"2022-01-17T19:30:39.238673Z","iopub.status.idle":"2022-01-17T19:30:39.248731Z","shell.execute_reply.started":"2022-01-17T19:30:39.238640Z","shell.execute_reply":"2022-01-17T19:30:39.248001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CotsData(Dataset):\n    def __init__(self , data_adaptor , transforms = None):\n        self.ds = data_adaptor\n        self.transforms = transforms\n    \n    def can_augment(self, boxes,image_size = 320): \n        box_outside_image = ((boxes[:, 0] < 0).any() or (boxes[:, 1] < 0).any() \n                             or (boxes[:, 2] > image_size).any() or (boxes[:, 3] > image_size).any())\n        return not box_outside_image\n    \n    def __len__(self):\n        return len(self.ds)\n    \n    def __getitem__(self, idx):\n        image, bboxes, class_labels, image_id = self.ds.get_image_bb(idx)\n        image = np.array(image, dtype=np.float32)\n        sample = {\n        \"image\": image,\n        \"bboxes\": bboxes,\n        \"labels\": class_labels,\n                }\n        sample = self.transforms(**sample)\n        sample[\"bboxes\"] = np.array(sample[\"bboxes\"])\n        image = sample[\"image\"]\n        bboxes = sample[\"bboxes\"]\n        labels = sample[\"labels\"]\n        _, new_h, new_w = image.shape\n        sample[\"bboxes\"][:, [0, 1, 2, 3]] = sample[\"bboxes\"][:, [1, 0, 3, 2]]  # convert to yxyx\n\n        target = {\n            \"bboxes\": torch.as_tensor(sample[\"bboxes\"], dtype=torch.float32),\n            \"labels\": torch.as_tensor(labels),\n            \"image_id\": torch.tensor([image_id]),\n            \"img_size\": (new_h, new_w),\n            \"img_scale\": torch.tensor([1.0]),}\n        \n        \n        \n        return image, target, image_id\n     ","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:39.250146Z","iopub.execute_input":"2022-01-17T19:30:39.250409Z","iopub.status.idle":"2022-01-17T19:30:39.264527Z","shell.execute_reply.started":"2022-01-17T19:30:39.250374Z","shell.execute_reply":"2022-01-17T19:30:39.263814Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def collate_fn(batch):\n        images, targets, image_ids = tuple(zip(*batch))\n        images = torch.stack(images)\n        images = images.float()\n\n        boxes = [target[\"bboxes\"].float() for target in targets]\n        labels = [target[\"labels\"].float() for target in targets]\n        img_size = torch.tensor([target[\"img_size\"] for target in targets]).float()\n        img_scale = torch.tensor([target[\"img_scale\"] for target in targets]).float()\n\n        annotations = {\n            \"bbox\": boxes,\n            \"cls\": labels,\n            \"img_size\": img_size,\n            \"img_scale\": img_scale,\n        }\n\n        return images, annotations, targets, image_ids","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:39.265832Z","iopub.execute_input":"2022-01-17T19:30:39.266185Z","iopub.status.idle":"2022-01-17T19:30:39.275718Z","shell.execute_reply.started":"2022-01-17T19:30:39.266149Z","shell.execute_reply":"2022-01-17T19:30:39.274881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"class AverageMeter(object):\n    \"\"\"Computes and stores the average and current value\"\"\"\n    def __init__(self):\n        self.reset()\n\n    def reset(self):\n        self.val = 0\n        self.avg = 0\n        self.sum = 0\n        self.count = 0\n\n    def update(self, val, n=1):\n        self.val = val\n        self.sum += val * n\n        self.count += n\n        self.avg = self.sum / self.count","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:30:39.276904Z","iopub.execute_input":"2022-01-17T19:30:39.277226Z","iopub.status.idle":"2022-01-17T19:30:39.287004Z","shell.execute_reply.started":"2022-01-17T19:30:39.277190Z","shell.execute_reply":"2022-01-17T19:30:39.286245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train_one_epoch(train_loader,model,optimizer,e,epochs,scheduler):\n    losses = AverageMeter()\n    c_losses = AverageMeter()\n    b_losses = AverageMeter()\n    model.train()\n    global_step = 0\n    loop = tqdm(enumerate(train_loader),total = len(train_loader))\n    \n    for step,batch in loop:\n        images, ann, _, image_ids = batch \n        batch_size = len(image_ids)\n        images = images.to(device)\n        target = {}\n        target[\"bbox\"] = [a.to(device) for a in ann['bbox']]\n        target[\"cls\"] = [a.to(device) for a in ann[\"cls\"]]\n        target[\"img_scale\"] = (\n            torch.tensor([1] * batch_size).float().to(device)\n        )\n        target[\"img_size\"] = (\n            torch.tensor( ann[\"img_size\"]).to(device).float()\n        )\n        \n        output = model(images , target)\n        loss = output['loss']\n        c_loss = output['class_loss']\n        b_loss = output['box_loss']\n     \n        losses.update(loss.item(), batch_size)\n        c_losses.update(c_loss.item(), batch_size)\n        b_losses.update(b_loss.item(), batch_size)\n        \n        loss.backward()\n        optimizer.step()\n        optimizer.zero_grad()\n\n\n        scheduler.step()\n        global_step += 1\n        \n        loop.set_description(f\"Epoch {e+1}/{epochs}\")\n        loop.set_postfix(loss = loss.item(), stage = 'train')\n        \n        \n    return losses.avg, c_losses.avg , b_losses.avg","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:35:17.078865Z","iopub.execute_input":"2022-01-17T19:35:17.079150Z","iopub.status.idle":"2022-01-17T19:35:17.090433Z","shell.execute_reply.started":"2022-01-17T19:35:17.079115Z","shell.execute_reply":"2022-01-17T19:35:17.089566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def val_one_epoch(train_loader,model,e,epochs):\n    losses = AverageMeter()\n    c_losses = AverageMeter()\n    b_losses = AverageMeter()\n    model.eval()\n    global_step = 0\n    loop = tqdm(enumerate(train_loader),total = len(train_loader))\n    \n    for step,batch in loop:\n        images, ann, _, image_ids = batch \n        batch_size = len(image_ids)\n        images = images.to(device)\n        target = {}\n        target[\"bbox\"] = [a.to(device) for a in ann['bbox']]\n        target[\"cls\"] = [a.to(device) for a in ann[\"cls\"]]\n        target[\"img_scale\"] = (\n            torch.tensor([1] * batch_size).float().to(device)\n        )\n        target[\"img_size\"] = (\n            torch.tensor( ann[\"img_size\"]).to(device).float()\n        )\n         \n        with torch.no_grad():\n            output = model(images , target)\n        loss = output['loss']\n        c_loss = output['class_loss']\n        b_loss = output['box_loss']\n     \n        losses.update(loss.item(), batch_size)\n        c_losses.update(c_loss.item(), batch_size)\n        b_losses.update(b_loss.item(), batch_size)\n  \n\n        global_step += 1\n        \n        loop.set_description(f\"Epoch {e+1}/{epochs}\")\n        loop.set_postfix(loss = loss.item(), stage = 'val')\n        \n        \n    return losses.avg, c_losses.avg , b_losses.avg","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:35:17.592689Z","iopub.execute_input":"2022-01-17T19:35:17.593370Z","iopub.status.idle":"2022-01-17T19:35:17.604150Z","shell.execute_reply.started":"2022-01-17T19:35:17.593330Z","shell.execute_reply":"2022-01-17T19:35:17.602999Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def fit(m,fold_n ,train_bs=12, val_bs = 24):\n    \n    \n    train_data= df[df.fold != fold_n]\n    val_data  = df[df.fold == fold_n]\n    \n    train_ds =DataAdaptor(train_data.reset_index(drop=True))\n    val_ds = DataAdaptor(val_data.reset_index(drop=True))\n    \n    train_data= CotsData(train_ds ,train_aug() )\n    val_data  = CotsData(val_ds ,val_aug() )\n    \n    \n    train_loader =DataLoader(\n            train_data,\n            batch_size=train_bs,\n            shuffle=True,\n            pin_memory=True,\n            drop_last=True,\n            num_workers=4,\n            collate_fn=collate_fn,)\n    \n    valid_loader =DataLoader(\n            val_data,\n            batch_size=val_bs ,\n            shuffle=False,\n            drop_last=False,\n            num_workers=4,\n            collate_fn=collate_fn,)\n   \n    optimizer = optim.AdamW(m.parameters(), lr= 2e-4, weight_decay = 1e-6)\n    epochs= 5\n    warmup_epochs = 2\n    num_train_steps = math.ceil(len(train_loader))\n    num_warmup_steps= num_train_steps * warmup_epochs\n    num_training_steps=int(num_train_steps * epochs)\n    sch = get_cosine_schedule_with_warmup(optimizer,num_warmup_steps = num_warmup_steps,num_training_steps =num_training_steps) \n    \n    loop = range(epochs)\n    for e in loop:\n        \n        total_loss,class_loss,box_loss = train_one_epoch(train_loader,m,optimizer,e,epochs,sch)\n    \n        print(f'For epoch {e+1}/{epochs}')\n        print(f'average total_loss {total_loss}')\n        print(f'average class_loss {class_loss}')\n        print(f'average box_loss {box_loss}' )\n        \n        v_total_loss,v_class_loss,v_box_loss = val_one_epoch(valid_loader,m,e,epochs)\n    \n        print(f'For epoch {e+1}/{epochs}')\n        print(f'average val total_loss {v_total_loss}')\n        print(f'average val class_loss {v_class_loss}')\n        print(f'average val box_loss {v_box_loss}' )\n        \n        torch.save(m.state_dict(),OUTPUT_DIR+ f'Fold {fold_n} model with val loss {v_total_loss}.pth') ","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:35:19.415476Z","iopub.execute_input":"2022-01-17T19:35:19.416035Z","iopub.status.idle":"2022-01-17T19:35:19.428505Z","shell.execute_reply.started":"2022-01-17T19:35:19.415985Z","shell.execute_reply":"2022-01-17T19:35:19.427646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OUTPUT_DIR = './'\nif not os.path.exists(OUTPUT_DIR):\n    os.makedirs(OUTPUT_DIR)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:35:19.742352Z","iopub.execute_input":"2022-01-17T19:35:19.742951Z","iopub.status.idle":"2022-01-17T19:35:19.746609Z","shell.execute_reply.started":"2022-01-17T19:35:19.742910Z","shell.execute_reply":"2022-01-17T19:35:19.745890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model= model.to(device)\nfit(model,0)","metadata":{"execution":{"iopub.status.busy":"2022-01-17T19:35:20.142649Z","iopub.execute_input":"2022-01-17T19:35:20.143120Z","iopub.status.idle":"2022-01-17T19:35:56.541377Z","shell.execute_reply.started":"2022-01-17T19:35:20.143084Z","shell.execute_reply":"2022-01-17T19:35:56.539063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# References\n1. https://medium.com/data-science-at-microsoft/training-efficientdet-on-custom-data-with-pytorch-lightning-using-an-efficientnetv2-backbone-1cdf3bd7921f\n2. https://www.kaggle.com/shonenkov/training-efficientdet/notebook\n3. https://www.kaggle.com/julian3833/reef-starter-torch-fasterrcnn-train-lb-0-416/notebook\n4. https://github.com/benihime91/SIIM-COVID19-DETECTION-KAGGLE/blob/main/net-det/train.py\n5. Most importantly thanks to this https://github.com/rwightman/efficientdet-pytorch","metadata":{}},{"cell_type":"markdown","source":"Infer coming soon(I guess)","metadata":{}}]}