{"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":"# !pip install ../input/timm-wheel/timm-0.6.5-py3-none-any.whl\n\nimport torch\n# import timm\nimport pandas as pd\nimport os\nimport tifffile as tifi\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport random\nimport cv2\nimport h5py\nimport pandas as pd\nimport torchvision.models as models\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as T\nimport torch.nn as nn\nimport torch.nn.functional as F\n\ntorch.manual_seed(0)\nrandom.seed(0)\nnp.random.seed(0)\n\nif \"converted\" not in os.listdir():\n    os.mkdir(\"converted/\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-28T11:20:16.919623Z","iopub.execute_input":"2022-07-28T11:20:16.920102Z","iopub.status.idle":"2022-07-28T11:20:16.931268Z","shell.execute_reply.started":"2022-07-28T11:20:16.920069Z","shell.execute_reply":"2022-07-28T11:20:16.929918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections  import Counter\nCounter(pd.read_csv(\"../input/mayo-clinic-strip-ai/train.csv\").label.values.tolist())","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:20:19.349213Z","iopub.execute_input":"2022-07-28T11:20:19.349669Z","iopub.status.idle":"2022-07-28T11:20:19.363732Z","shell.execute_reply.started":"2022-07-28T11:20:19.349634Z","shell.execute_reply":"2022-07-28T11:20:19.362326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(\"../input/mayo-clinic-strip-ai/train.csv\")\ntrain_df              ","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:08:49.073178Z","iopub.execute_input":"2022-07-28T11:08:49.073752Z","iopub.status.idle":"2022-07-28T11:08:49.101686Z","shell.execute_reply.started":"2022-07-28T11:08:49.073717Z","shell.execute_reply":"2022-07-28T11:08:49.100849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from PIL import Image\ntrain_path = \"../input/mayo-clinic-strip-ai/train/\"\n\nimg = Image.open(\"../input/mayo-clinic-strip-ai/train/026c97_0.tif\")\n\nx1 = img.size[0]\nx2 = img.size[1]\nsc = x2/x1\n\n\n\nfactor = 1/10\nresized_img = img.resize((int(x1*factor), int(sc*x1*factor)))\n\nprint(resized_img.size)\nresized_img.rotate(90, expand=True)\n","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:08:49.103527Z","iopub.execute_input":"2022-07-28T11:08:49.104438Z","iopub.status.idle":"2022-07-28T11:08:52.93147Z","shell.execute_reply.started":"2022-07-28T11:08:49.104401Z","shell.execute_reply":"2022-07-28T11:08:52.930328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = {\"CE\":0, \"LAA\":1}\n\nconverted_train_path = \"./converted/\"\nsaved_converted_path = \"../input/mayo-clinic-strip-ainumpy-files/\"\ntrain_img_paths = []\ntrain_y = []\nfor n, (i,j) in enumerate(zip(train_df['image_id'].values, train_df['label'].values)):\n    print(f\"{n}/{len(train_df['label'].values)}\", end=\"\\r\")\n    if f\"{i}.npy\" not in os.listdir(saved_converted_path):\n        np.save(f\"./converted/{i}.npy\", cv2.resize(tifi.imread(train_path + i + '.tif'),(224, 224)))\n        train_img_paths.append(converted_train_path + i + '.npy')\n                \n    else:\n        train_img_paths.append(saved_converted_path + i + '.npy')\n                \n    train_y.append(labels[j])\n\nc = list(zip(train_img_paths, train_y))\n\nrandom.shuffle(c)\n\ntrain_img_paths, train_y = zip(*c)\ntrain_y = list(train_y)\ntrain_img_paths = list(train_img_paths)\n\nn_val = 40\n\nval_y = []\nval_img_paths = []\n\ni = 0 # start\nj = 0 # class 0 count\nk = 0 # class 1 count\n\n\nwhile len(val_y)!=n_val:\n    if train_y[i] == 0 and j<int(n_val/2):\n        j+=1\n        val_y.append(train_y.pop(i))\n        val_img_paths.append(train_img_paths.pop(0))\n        i=0\n        \n\n    elif train_y[i] == 1 and k<n_val-int(n_val/2):\n        k+=1\n        val_y.append(train_y.pop(i))\n        val_img_paths.append(train_img_paths.pop(0))\n        i=0\n        \n    else:\n        i+=1\n        \nCounter(val_y)","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:08:52.933116Z","iopub.execute_input":"2022-07-28T11:08:52.933772Z","iopub.status.idle":"2022-07-28T11:08:53.607375Z","shell.execute_reply.started":"2022-07-28T11:08:52.933732Z","shell.execute_reply":"2022-07-28T11:08:53.606217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ImgDataset(Dataset):\n    def __init__(self, x, y, dataset_type):\n        self.x = x\n        self.y = y\n        self.transform_train = T.Compose([T.RandomHorizontalFlip(),\n                                    T.RandomVerticalFlip(),\n                                    T.RandomRotation(30),\n                                    T.ToTensor(),\n                                    T.ConvertImageDtype(torch.float32),\n                                    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n   \n        self.transform_val = T.Compose([T.ToTensor(),\n                                    T.ConvertImageDtype(torch.float32),\n                                    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n    \n        self.dataset_type = dataset_type\n        \n#         if 'cache' not in os.listdir('./'):\n#             h5_file = h5py.File('cache', 'w')\n        \n#         else:\n#             h5_file = h5py.File('cache', 'a')\n        \n# #         if self.dataset_type not in h5_file:\n# #             index_dataset = h5_file.create_dataset(dataset_type, shape=(len(x), 3, 224, 224), dtype=np.float32, fillvalue=0)\n#         h5_file.close()\n        \n    def __len__(self):\n        return len(self.x)\n    \n    def __getitem__(self, idx):\n#         h5_file = h5py.File('cache', 'a')\n        \n#         if f'{idx}_{self.dataset_type}' not in h5_file: # true if empty/not cached\n#             img = Image.fromarray(cv2.resize(tifi.imread(self.x[idx]),(224, 224)))\n#             if self.dataset_type == 'train':\n#                 img = self.transform_train(img)\n#             elif self.dataset_type == 'val':\n#                 img = self.transform_val(img)\n                \n#             index_dataset = h5_file.create_dataset(f'{idx}_{self.dataset_type}', shape=(3, 224, 224), dtype=np.float32, data = img.numpy(), chunks=True)\n            \n#         else:\n#             img = torch.FloatTensor(data[f'{idx}_{self.dataset_type}'])\n\n        img = Image.fromarray(np.load(self.x[idx]))\n#         print(T.Compose([T.ToTensor()])(img))\n        \n        if self.dataset_type == 'train':\n            img = self.transform_train(img)\n        elif self.dataset_type == 'val':\n            img = self.transform_val(img)\n            \n        label = torch.LongTensor([self.y[idx]])\n#         h5_file.close()\n        \n\n        return img, label \n    \n    \ndef seed_worker(worker_id):\n    worker_seed = torch.initial_seed() % 2**32\n    np.random.seed(worker_seed)\n    random.seed(worker_seed)\n\ng = torch.Generator()\ng.manual_seed(0)\n    \ntrain_dataset = ImgDataset(train_img_paths, train_y, dataset_type = 'train')\nvalidation_dataset = ImgDataset(val_img_paths, val_y, dataset_type = 'val')\nvalidation_dataloader = DataLoader(validation_dataset, batch_size = 16, shuffle=False, worker_init_fn=seed_worker, generator=g)\ntrain_dataloader = DataLoader(train_dataset, batch_size = 16, shuffle=False, worker_init_fn=seed_worker, generator=g)","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:31:31.578689Z","iopub.execute_input":"2022-07-28T11:31:31.580974Z","iopub.status.idle":"2022-07-28T11:31:31.60047Z","shell.execute_reply.started":"2022-07-28T11:31:31.580907Z","shell.execute_reply":"2022-07-28T11:31:31.599453Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EfficientNet_b4(nn.Module):\n    def __init__(self, n_classes, pretrained=False):\n\n        super(EfficientNet_b4, self).__init__()\n\n        self.model = models.efficientnet_b4(pretrained = pretrained)\n\n        self.model.classifier[1] = nn.Linear(self.model.classifier[1].in_features, n_classes)\n\n    def forward(self, x):\n        x = self.model(x)\n        return x\n\nepoch = 20\nefficientnet = EfficientNet_b4(2)\nloss_history = [[], []] #train, val\naccuracy_history = [[], []] #train, val\nacc_epoch_history = [[],[]]\nloss_epoch_history = [[],[]]\n\noptimizer = torch.optim.Adam(efficientnet.parameters(), lr=2e-03)\ncriterion = nn.CrossEntropyLoss()","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:22:11.868703Z","iopub.execute_input":"2022-07-28T11:22:11.869711Z","iopub.status.idle":"2022-07-28T11:22:12.239583Z","shell.execute_reply.started":"2022-07-28T11:22:11.869672Z","shell.execute_reply":"2022-07-28T11:22:12.23839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Caching\n# for i, (data, target) in enumerate(train_dataloader):\n#     print(f\"MINIBATCH {i+1}/{train_dataloader.__len__()}\")\n    \n# for i, (data, target) in enumerate(val_dataloader):\n#     print(f\"MINIBATCH {i+1}/{val_dataloader.__len__()}\")","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:23:48.257866Z","iopub.status.idle":"2022-07-25T08:23:48.258455Z","shell.execute_reply.started":"2022-07-25T08:23:48.25826Z","shell.execute_reply":"2022-07-25T08:23:48.258281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for e in range(epoch):\n    efficientnet.train()\n    print(f\"====================== EPOCH {e+1} ======================\")\n    print(\"Training.....\")\n    for i, (data, target) in enumerate(train_dataloader):\n        optimizer.zero_grad()\n        output = efficientnet(data)\n        loss = criterion(output, target.view(-1,))\n        loss.backward()\n        \n        nn.utils.clip_grad_norm_(efficientnet.parameters(), 3)\n        accuracy = (output.argmax(dim=1) == target).float().mean()\n        \n        loss_history[0].append(loss.item())\n        accuracy_history[0].append(accuracy)\n        \n        optimizer.step()\n        \n        print(f\"MINIBATCH {i+1}/{train_dataloader.__len__()} TRAIN ACC : {accuracy_history[0][-1]}  TRAIN LOSS : {loss_history[0][-1]}\")\n            \n    \n    print(\"Validation.....\")\n    efficientnet.eval()\n    \n    with torch.no_grad():\n        for i, (data, target) in enumerate(validation_dataloader):\n            output = efficientnet(data)\n            loss = criterion(output, target.view(-1,))\n            accuracy = (output.argmax(dim=1) == target).float().mean()\n            loss_history[1].append(loss.item())\n            accuracy_history[1].append(accuracy)\n        \n    acc_epoch_history[0].append(sum(accuracy_history[0][-1:-train_dataloader.__len__():-1])/train_dataloader.__len__())\n    acc_epoch_history[1].append(sum(accuracy_history[1][-1:-validation_dataloader.__len__():-1])/validation_dataloader.__len__())\n    \n    loss_epoch_history[0].append(sum(loss_history[0][-1:-train_dataloader.__len__():-1])/train_dataloader.__len__())\n    loss_epoch_history[1].append(sum(loss_history[1][-1:-validation_dataloader.__len__():-1])/validation_dataloader.__len__())\n    \n    print(\"====================================================\")\n    print(f\"TRAIN ACC : {acc_epoch_history[0][-1]}  TRAIN LOSS : {loss_epoch_history[0][-1]}\")\n    print(f\"VALL ACC : {acc_epoch_history[1][-1]}  VAL LOSS : {loss_epoch_history[1][-1]}\")\n    print(\"====================================================\")\n    \n    torch.save({\n            'epoch': e,\n            'model_state_dict': efficientnet.state_dict(),\n            'optimizer_state_dict': optimizer.state_dict(),\n            'loss': loss_epoch_history[0][-1],\n            'acc' : acc_epoch_history[0][-1]\n            }, './model_checkpoint.pt')","metadata":{"execution":{"iopub.status.busy":"2022-07-28T11:31:33.900692Z","iopub.execute_input":"2022-07-28T11:31:33.901862Z","iopub.status.idle":"2022-07-28T11:31:55.265217Z","shell.execute_reply.started":"2022-07-28T11:31:33.901816Z","shell.execute_reply":"2022-07-28T11:31:55.263687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\nplt.plot(acc_epoch_history[0], label=\"train\")\nplt.plot(acc_epoch_history[1], label=\"val\")\nplt.legend()\nplt.title('ACCURACY VS EPOCH')\nplt.show()\n\nplt.plot(loss_epoch_history[0], label=\"train\")\nplt.plot(loss_epoch_history[1], label=\"val\")\nplt.legend()\nplt.title('LOSS VS EPOCH')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:43:03.711075Z","iopub.status.idle":"2022-07-25T08:43:03.711658Z","shell.execute_reply.started":"2022-07-25T08:43:03.711467Z","shell.execute_reply":"2022-07-25T08:43:03.711488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_path = '../input/mayo-clinic-strip-ai/test/'\npred = []\ntransform_val = T.Compose([T.PILToTensor(),\n                                    T.ConvertImageDtype(torch.float32),\n                                    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])\n\ntest_names = list(os.listdir(test_path))\nfor i in test_names:\n    img = Image.fromarray(cv2.resize(tifi.imread(test_path+i),(224, 224)))\n    pred.append(efficientnet(transform_val(img).unsqueeze(0)))","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:23:48.265463Z","iopub.status.idle":"2022-07-25T08:23:48.266127Z","shell.execute_reply.started":"2022-07-25T08:23:48.26591Z","shell.execute_reply":"2022-07-25T08:23:48.265932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = nn.functional.softmax(torch.FloatTensor([i.detach().numpy() for i in pred]).view(-1,2), dim=1).numpy()\nsubmission","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:43:03.714774Z","iopub.status.idle":"2022-07-25T08:43:03.715194Z","shell.execute_reply.started":"2022-07-25T08:43:03.715005Z","shell.execute_reply":"2022-07-25T08:43:03.715024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_csv = pd.read_csv('../input/mayo-clinic-strip-ai/sample_submission.csv')\nsubmission_csv","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:23:48.269117Z","iopub.status.idle":"2022-07-25T08:23:48.269724Z","shell.execute_reply.started":"2022-07-25T08:23:48.269529Z","shell.execute_reply":"2022-07-25T08:23:48.269549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_names","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:23:48.270873Z","iopub.status.idle":"2022-07-25T08:23:48.271482Z","shell.execute_reply.started":"2022-07-25T08:23:48.271287Z","shell.execute_reply":"2022-07-25T08:23:48.271307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = {'patient_id':[i[:-6] for i in test_names],\n        'CE':submission[:,0].tolist(),\n        'LAA':submission[:,1].tolist()}\n  \ndf = pd.DataFrame(data)\n\ndf","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:23:48.272533Z","iopub.status.idle":"2022-07-25T08:23:48.272938Z","shell.execute_reply.started":"2022-07-25T08:23:48.272724Z","shell.execute_reply":"2022-07-25T08:23:48.272741Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.to_csv('submission.csv')","metadata":{"execution":{"iopub.status.busy":"2022-07-25T08:23:48.274694Z","iopub.status.idle":"2022-07-25T08:23:48.275114Z","shell.execute_reply.started":"2022-07-25T08:23:48.274925Z","shell.execute_reply":"2022-07-25T08:23:48.274943Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = torch.jit.script(efficientnet)\n\n# Save to file\ntorch.jit.save(m, 'efficientnet.pt')\n","metadata":{},"execution_count":null,"outputs":[]}]}