{"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":"### notes\n#1. dataset not balanced\n#2. transforms not done sochke\n#3. ensembling not tried\n#4. FOLDS not tried out\n#5. Cosine anneling/reduce on LR\n#6. Mixed precision training  -- DONE\n#check https://www.kaggle.com/c/cassava-leaf-disease-classification/discussion/203111#1111578","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:22:28.398748Z","iopub.execute_input":"2022-11-25T06:22:28.399000Z","iopub.status.idle":"2022-11-25T06:22:28.404041Z","shell.execute_reply.started":"2022-11-25T06:22:28.398972Z","shell.execute_reply":"2022-11-25T06:22:28.403177Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# IMPORTS","metadata":{}},{"cell_type":"code","source":"# !pip install efficientnet-pytorch\n!pip install --no-deps imagededup==0.2.2 > /dev/null\n\nimport sys\nsys.path = [\n    '../input/efficientnet-pytorch/EfficientNet-PyTorch/EfficientNet-PyTorch-master',\n] + sys.path\nsys.path = [\n    '../input/ttach-kaggle/ttach/',\n] + sys.path\n\nimport numpy as np \nimport pandas as pd \nfrom collections import Counter\nfrom sklearn.model_selection import train_test_split\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.utils import make_grid\nfrom PIL import Image\nfrom tqdm.notebook import tqdm\nimport matplotlib.pyplot as plt\nimport torchvision.models as models\nimport torchvision.transforms as T\nimport torch.nn.functional as F\nimport torch.nn as nn\nimport json\nimport torch\nimport torchvision\nimport cv2\nimport PIL\nimport os\nimport random\nfrom efficientnet_pytorch import EfficientNet\nfrom imagededup.methods import PHash\n\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\ndef seed_torch(seed=42):\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\nseed_torch()","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:22:28.409563Z","iopub.execute_input":"2022-11-25T06:22:28.410225Z","iopub.status.idle":"2022-11-25T06:22:39.941168Z","shell.execute_reply.started":"2022-11-25T06:22:28.410183Z","shell.execute_reply":"2022-11-25T06:22:39.940414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# READ FILES","metadata":{}},{"cell_type":"code","source":"train_csv_path = \"../input/cassavapreprocessed/merged_data.csv\"\ntrain_images_path = \"../input/cassavapreprocessed/train_images/train_images\"\n\n# get image labels\ndata_csv = pd.read_csv(train_csv_path)\nprint(data_csv.head())\nprint(\"\\ntotal label types = \", Counter(data_csv['label']))\n\n# get disease names corresponding to labels\nf = open('../input/cassava-leaf-disease-classification/label_num_to_disease_map.json')\nreal_labels = json.load(f)\nreal_labels = {int(k):v for k,v in real_labels.items()} #fixing datatype\nreal_labels","metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","execution":{"iopub.status.busy":"2022-11-25T06:22:39.943013Z","iopub.execute_input":"2022-11-25T06:22:39.943365Z","iopub.status.idle":"2022-11-25T06:22:40.024614Z","shell.execute_reply.started":"2022-11-25T06:22:39.943337Z","shell.execute_reply":"2022-11-25T06:22:40.023751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# just put in the names, same as label column\ndata_csv['class_name'] = data_csv.label.map(real_labels)\ndata_csv.head()","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:22:40.026079Z","iopub.execute_input":"2022-11-25T06:22:40.026443Z","iopub.status.idle":"2022-11-25T06:22:40.044316Z","shell.execute_reply.started":"2022-11-25T06:22:40.026405Z","shell.execute_reply":"2022-11-25T06:22:40.043308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# read image given path\ndef get_image(path):\n    img = Image.open(path)\n    return img\n\n# sample image\nimg = get_image(\"../input/cassavapreprocessed/train_images/train_images/1000015157.jpg\")\nimg","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:22:40.046179Z","iopub.execute_input":"2022-11-25T06:22:40.046544Z","iopub.status.idle":"2022-11-25T06:22:40.243623Z","shell.execute_reply.started":"2022-11-25T06:22:40.046509Z","shell.execute_reply":"2022-11-25T06:22:40.241594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DBSCAN to remove duplicate images ","metadata":{}},{"cell_type":"code","source":"# takes around 10 mins, skipable in realtime\nphasher = PHash()\n\nencodings = phasher.encode_images(image_dir=train_images_path)\nduplicates = phasher.find_duplicates(encoding_map=encodings, max_distance_threshold=0)","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:22:40.246423Z","iopub.execute_input":"2022-11-25T06:22:40.246706Z","iopub.status.idle":"2022-11-25T06:27:56.047277Z","shell.execute_reply.started":"2022-11-25T06:22:40.246678Z","shell.execute_reply":"2022-11-25T06:27:56.046416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_CLUSTERS=[]\nTRAIN_CLUSTERING_CACHE= set()\nBAD_CASES_DBSCAN_CACHE = set()\n\nfor image_id, values in tqdm(duplicates.items(), total=len(duplicates)):\n    image_id = image_id.split('.')[0]\n    if len(values) < 1:\n        continue\n#     if image_id not in TRAIN_IMAGE_IDS:\n#         continue\n    sorted_cluster = [image_id]\n    for value in values:\n        value = value.split('.')[0]\n#         if value in TRAIN_IMAGE_IDS:\n        sorted_cluster.append(value)\n\n    sorted_cluster = sorted(sorted_cluster)\n    if len(sorted_cluster) > 1:\n        cluster_name = '.'.join(sorted_cluster)\n#         if cluster_name in BAD_CASES_CACHE:\n#             continue\n        if cluster_name not in TRAIN_CLUSTERING_CACHE:\n            TRAIN_CLUSTERING_CACHE.add(cluster_name)\n            TRAIN_CLUSTERS.append(sorted_cluster)\n            \n\nTRAIN_CLUSTERS = sorted(TRAIN_CLUSTERS, key=lambda x: -len(x))\n\nmargin = 0\ncount = 20\n\ndraw_clusters = TRAIN_CLUSTERS[margin:margin+count]\n\nsize = min([5, len(draw_clusters[0])])\n\nfig, ax = plt.subplots(count, size, figsize=(size*3, 4*count))\n\nfor j, image_ids in enumerate(draw_clusters):\n    for i, image_id in enumerate(image_ids[:size]):\n        image_id = image_id.split('.')[0]\n        image = cv2.imread(f'../input/cassavapreprocessed/train_images/train_images/{image_id}.jpg', cv2.IMREAD_COLOR)\n        image = cv2.resize(image, (256, 256), cv2.INTER_AREA)\n        ax[j][i].imshow(image);\n#         patient_id = df_folds.loc[image_id]['patient_id']\n        ax[j][i].set_title(f'{image_id}')","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:27:56.050326Z","iopub.execute_input":"2022-11-25T06:27:56.050926Z","iopub.status.idle":"2022-11-25T06:28:01.469520Z","shell.execute_reply.started":"2022-11-25T06:27:56.050887Z","shell.execute_reply":"2022-11-25T06:28:01.467281Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#removing duplicates \n\nprint(\"total duplicate images = \", len(TRAIN_CLUSTERS))\nfor group in TRAIN_CLUSTERS:\n    data_csv = data_csv[data_csv.image_id != f'{group[0]}.jpg']\nprint(data_csv.shape)","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:01.471544Z","iopub.execute_input":"2022-11-25T06:28:01.472174Z","iopub.status.idle":"2022-11-25T06:28:03.618763Z","shell.execute_reply.started":"2022-11-25T06:28:01.472131Z","shell.execute_reply":"2022-11-25T06:28:03.617105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading data","metadata":{}},{"cell_type":"code","source":"#read dataset train/val/test\nclass GetDataset(Dataset):\n    def __init__(self, df, data_root, transforms = None, output_label = True):\n        super().__init__()\n        self.df = df.reset_index(drop=True).copy()\n        self.data_root = data_root\n        self.transforms = transforms\n        self.output_label = output_label\n        \n    def __len__(self):\n        return self.df.shape[0]\n    \n    def __getitem__(self, index: int):    #enforces index to be int\n            \n        path = \"{}/{}\".format(self.data_root, self.df.iloc[index]['image_id'])\n        img = get_image(path)         \n            \n        #if transforms exist then apply transforms\n        if self.transforms:\n            img = self.transforms(img)\n            \n        #if label exists then get label and return\n        if self.output_label:\n            label = self.df.iloc[index]['label']\n            return img, label\n        else:\n            return img\n        \n        \nIMG_SIZE = 512\nBATCH_SIZE = 16\nIMG_SHAPE = (IMG_SIZE,IMG_SIZE)\nepochs = 6\nmax_lr = 10e-4\ngrad_clip = 0.1\nweight_decay = 10e-4\nopt_func=torch.optim.Adam","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:03.620001Z","iopub.execute_input":"2022-11-25T06:28:03.620355Z","iopub.status.idle":"2022-11-25T06:28:03.630917Z","shell.execute_reply.started":"2022-11-25T06:28:03.620325Z","shell.execute_reply":"2022-11-25T06:28:03.628740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# splitting into train and validation\ntrain_csv, val_csv = train_test_split(data_csv, test_size = 0.1, random_state = 23, stratify = data_csv['class_name'])\n#stratify maintains the label ratios even after splitting\n\n\ntrain_transforms = T.Compose([\n#     T.RandomCrop(IMG_SHAPE),\n    T.Resize(IMG_SHAPE),\n    T.RandomHorizontalFlip(p = 0.5),\n    T.RandomVerticalFlip(p = 0.5),\n    T.ColorJitter(hue=.05, saturation=.05),\n    T.RandomRotation(20, resample=PIL.Image.BILINEAR),\n    T.ToTensor(),\n    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])\n\nvalidation_transforms = T.Compose([\n#     T.CenterCrop(IMG_SHAPE),\n    T.Resize(IMG_SHAPE),\n    T.ToTensor(),\n    T.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n])\n\ntrain_ds = GetDataset(train_csv, train_images_path, transforms = train_transforms, output_label = True)\nval_ds = GetDataset(val_csv, train_images_path, transforms = validation_transforms, output_label = True)\n\n# weights = [1.62, 8.31, 8.96, 9.77, 19.68]\n# sampler = torch.utils.data.WeightedRandomSampler(weights, len(weights))\n\ntrain = torch.utils.data.DataLoader(\n    train_ds,\n    batch_size = BATCH_SIZE,\n    num_workers = 2,\n#     sampler = sampler,\n    shuffle = False,\n    pin_memory = False\n)\nval = torch.utils.data.DataLoader(\n    val_ds,\n    batch_size = BATCH_SIZE,\n    num_workers = 2,\n    shuffle = False,\n    pin_memory = False\n)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:03.632592Z","iopub.execute_input":"2022-11-25T06:28:03.633080Z","iopub.status.idle":"2022-11-25T06:28:03.673118Z","shell.execute_reply.started":"2022-11-25T06:28:03.633043Z","shell.execute_reply":"2022-11-25T06:28:03.672455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(train_dl):\n    for images, labels in train_dl:\n        fig, ax = plt.subplots(figsize=(20, 20))\n        ax.set_xticks([]); ax.set_yticks([])\n        ax.imshow(make_grid(images[:32], nrow=8).permute(1,2,0))\n        break\n        \nshow_images(train)\n\n#to get 1 batch i.e. batchsize\n# dataiter = iter(train)\n# images, labels = dataiter.next()\n\n# plt.imshow(torchvision.utils.make_grid(images[2]))\n# print(labels)","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:03.674397Z","iopub.execute_input":"2022-11-25T06:28:03.674913Z","iopub.status.idle":"2022-11-25T06:28:07.339617Z","shell.execute_reply.started":"2022-11-25T06:28:03.674876Z","shell.execute_reply":"2022-11-25T06:28:07.338796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DATA TO DEVICE","metadata":{}},{"cell_type":"code","source":"def get_device():\n    if torch.cuda.is_available():\n        return torch.device(\"cuda\")\n    else:\n        return torch.device(\"cpu\")\n    \ndef to_device(data, device):\n    if isinstance(data, (list,tuple)):\n        return [to_device(x, device) for x in data]\n    return data.to(device, non_blocking=True)\n\nclass DeviceDataLoader():\n    def __init__(self, dl, device):\n        self.dl = dl\n        self.device = device\n    \n    def __iter__(self):\n        for x in self.dl:\n            yield to_device(x, self.device)\n            \n    def __len__(self):\n        return len(self.dl)\n\ndevice = get_device()\ntrain = DeviceDataLoader(train, device)\nval = DeviceDataLoader(val, device)\nprint(\"Model running on\", device)","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:07.341108Z","iopub.execute_input":"2022-11-25T06:28:07.341696Z","iopub.status.idle":"2022-11-25T06:28:07.421506Z","shell.execute_reply.started":"2022-11-25T06:28:07.341638Z","shell.execute_reply":"2022-11-25T06:28:07.420694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def accuracy(out, labels):\n    _, preds = torch.max(out, dim=1)\n    return torch.tensor(torch.sum(preds == labels).item() / len(preds))\n\nclass ImageClassificationBase(nn.Module):\n    def training_step(self, batch):\n        images, labels = batch\n        out = self(images)\n        loss = F.cross_entropy(out, labels)#,  weight= torch.tensor([1.62, 8.31, 8.96, 9.77, 19.68]).to(device))\n        return loss\n    \n    def validation_step(self, batch):\n        images, labels = batch\n        out = self(images)\n        loss = F.cross_entropy(out, labels)\n        acc = accuracy(out, labels)\n        return {\"val_loss\": loss.detach(), \"val_acc\": acc}\n    \n    def validation_epoch_end(self, outputs):\n        batch_loss = [x[\"val_loss\"] for x in outputs]\n        epoch_loss = torch.stack(batch_loss).mean()\n        batch_acc = [x[\"val_acc\"] for x in outputs]\n        epoch_acc = torch.stack(batch_acc).mean()\n        return {\"val_loss\": epoch_loss.item(), \"val_acc\": epoch_acc.item()}\n    \n    def epoch_end(self, epoch, epochs, result):\n        print(\"Epoch: [{}/{}], last_lr: {:.6f}, train_loss: {:.4f}, val_loss: {:.4f}, val_acc: {:.4f}\".format(\n        epoch, epochs, result[\"lrs\"][-1], result[\"train_loss\"], result[\"val_loss\"], result[\"val_acc\"]))","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:07.422956Z","iopub.execute_input":"2022-11-25T06:28:07.423536Z","iopub.status.idle":"2022-11-25T06:28:07.437009Z","shell.execute_reply.started":"2022-11-25T06:28:07.423492Z","shell.execute_reply":"2022-11-25T06:28:07.436093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DEFINE MODEL","metadata":{}},{"cell_type":"code","source":"class Classifier(ImageClassificationBase):\n    def __init__(self):\n        super().__init__()\n        self.network = EfficientNet.from_name('efficientnet-b4')\n        number_of_features =  self.network._fc.in_features\n        self.network._fc = nn.Linear(number_of_features, 5)\n        \n    def forward(self, xb):\n        return self.network(xb)\n        \n    def freeze(self):\n        for param in self.network.parameters():\n            param.requires_grad=False\n        for param in self.network._fc.parameters():\n            param.requires_grad=True\n        \n    def unfreeze(self):\n        for param in self.network.parameters():\n            param.requires_grad=True","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:07.438395Z","iopub.execute_input":"2022-11-25T06:28:07.438886Z","iopub.status.idle":"2022-11-25T06:28:07.448667Z","shell.execute_reply.started":"2022-11-25T06:28:07.438850Z","shell.execute_reply":"2022-11-25T06:28:07.447748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = to_device(Classifier(), device)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:07.450434Z","iopub.execute_input":"2022-11-25T06:28:07.450807Z","iopub.status.idle":"2022-11-25T06:28:13.435602Z","shell.execute_reply.started":"2022-11-25T06:28:07.450771Z","shell.execute_reply":"2022-11-25T06:28:13.434676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"@torch.no_grad()\ndef evaluate(model, val_dl):\n    model.eval()\n    outputs = [model.validation_step(batch) for batch in val_dl]\n    return model.validation_epoch_end(outputs)\n\ndef get_lr(optimizer):\n    for param_group in optimizer.param_groups:\n        return param_group[\"lr\"]\n    \ndef fit_one_cycle(epochs, max_lr, model, train_dl, val_dl, weight_decay=0, grad_clip=None,\n                 opt_func=torch.optim.Adam):\n    \n    torch.cuda.empty_cache()\n    \n    history = []\n    opt = opt_func(model.parameters(), max_lr, weight_decay=weight_decay)\n    sched = torch.optim.lr_scheduler.OneCycleLR(opt, max_lr, epochs=epochs,\n                                                   steps_per_epoch=len(train_dl))\n    scaler = torch.cuda.amp.GradScaler()\n\n    for epoch in range(epochs):\n        model.train()\n        train_loss = []\n        lrs = []\n        for batch in tqdm(train_dl):\n            opt.zero_grad()\n            \n            with torch.cuda.amp.autocast():\n                loss = model.training_step(batch)\n            \n            scaler.scale(loss).backward()\n            scaler.step(opt)\n            scaler.update()\n\n#             loss = model.training_step(batch)\n            train_loss.append(loss)\n#             loss.backward()\n            \n            if grad_clip:\n                nn.utils.clip_grad_value_(model.parameters(), grad_clip)\n                \n#             opt.step()            \n            lrs.append(get_lr(opt))\n            sched.step()\n            \n        result = evaluate(model, val_dl)\n        result[\"train_loss\"] = torch.stack(train_loss).mean().item()\n        result[\"lrs\"] = lrs\n        model.epoch_end(epoch, epochs, result)\n        history.append(result)\n    return history","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:13.437075Z","iopub.execute_input":"2022-11-25T06:28:13.437439Z","iopub.status.idle":"2022-11-25T06:28:13.450983Z","shell.execute_reply.started":"2022-11-25T06:28:13.437400Z","shell.execute_reply":"2022-11-25T06:28:13.449883Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = [evaluate(model, val)]\nhistory","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:28:13.452439Z","iopub.execute_input":"2022-11-25T06:28:13.453060Z","iopub.status.idle":"2022-11-25T06:29:09.835353Z","shell.execute_reply.started":"2022-11-25T06:28:13.453024Z","shell.execute_reply":"2022-11-25T06:29:09.834372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TRAIN","metadata":{}},{"cell_type":"code","source":"# model.freeze()","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:29:09.837005Z","iopub.execute_input":"2022-11-25T06:29:09.837389Z","iopub.status.idle":"2022-11-25T06:29:09.841662Z","shell.execute_reply.started":"2022-11-25T06:29:09.837347Z","shell.execute_reply":"2022-11-25T06:29:09.840854Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.unfreeze()","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:29:09.842859Z","iopub.execute_input":"2022-11-25T06:29:09.843367Z","iopub.status.idle":"2022-11-25T06:29:09.857420Z","shell.execute_reply.started":"2022-11-25T06:29:09.843329Z","shell.execute_reply":"2022-11-25T06:29:09.856709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:29:09.858536Z","iopub.execute_input":"2022-11-25T06:29:09.858873Z","iopub.status.idle":"2022-11-25T06:29:10.958432Z","shell.execute_reply.started":"2022-11-25T06:29:09.858835Z","shell.execute_reply":"2022-11-25T06:29:10.957534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nhistory=[]\nhistory += fit_one_cycle(epochs, max_lr, model, train, val, weight_decay=weight_decay,\n                        grad_clip=grad_clip, opt_func=opt_func)","metadata":{"execution":{"iopub.status.busy":"2022-11-25T06:29:10.960144Z","iopub.execute_input":"2022-11-25T06:29:10.960562Z","iopub.status.idle":"2022-11-25T08:56:28.605309Z","shell.execute_reply.started":"2022-11-25T06:29:10.960520Z","shell.execute_reply":"2022-11-25T08:56:28.604368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2022-11-25T08:56:28.947735Z","iopub.execute_input":"2022-11-25T08:56:28.948122Z","iopub.status.idle":"2022-11-25T08:56:29.999051Z","shell.execute_reply.started":"2022-11-25T08:56:28.948069Z","shell.execute_reply":"2022-11-25T08:56:29.998168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nmax_lr = 10e-5\nhistory += fit_one_cycle(epochs, max_lr, model, train, val, weight_decay=weight_decay,\n                        grad_clip=grad_clip, opt_func=opt_func)","metadata":{"execution":{"iopub.status.busy":"2022-11-25T08:56:30.000824Z","iopub.execute_input":"2022-11-25T08:56:30.001130Z","iopub.status.idle":"2022-11-25T11:23:39.331719Z","shell.execute_reply.started":"2022-11-25T08:56:30.001095Z","shell.execute_reply":"2022-11-25T11:23:39.330724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2022-11-25T11:23:39.748504Z","iopub.execute_input":"2022-11-25T11:23:39.748871Z","iopub.status.idle":"2022-11-25T11:23:40.808594Z","shell.execute_reply.started":"2022-11-25T11:23:39.748833Z","shell.execute_reply":"2022-11-25T11:23:40.807595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# PLOT","metadata":{}},{"cell_type":"code","source":"accuracy = [x[\"val_acc\"] for x in history]\nplt.plot(accuracy, \"-rx\")\nplt.title(\"Accuracy vs number of epochs\")\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Accuracy\")","metadata":{"execution":{"iopub.status.busy":"2022-11-25T11:23:40.810323Z","iopub.execute_input":"2022-11-25T11:23:40.810591Z","iopub.status.idle":"2022-11-25T11:23:40.944761Z","shell.execute_reply.started":"2022-11-25T11:23:40.810562Z","shell.execute_reply":"2022-11-25T11:23:40.943952Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_loss = [x[\"val_loss\"] for x in history]\ntrain_loss = [x.get(\"train_loss\") for x in history]\nplt.plot(val_loss, \"-bx\")\nplt.plot(train_loss, \"-gx\")\nplt.title(\"Losses vs number of epochs\")\nplt.legend([\"Validation loss\", \"Train loss\"])\nplt.xlabel(\"Epochs\")","metadata":{"execution":{"iopub.status.busy":"2022-11-25T11:23:40.946517Z","iopub.execute_input":"2022-11-25T11:23:40.946865Z","iopub.status.idle":"2022-11-25T11:23:41.086121Z","shell.execute_reply.started":"2022-11-25T11:23:40.946831Z","shell.execute_reply":"2022-11-25T11:23:41.085325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# SAVING MODEL","metadata":{}},{"cell_type":"code","source":"torch.save(model, \"/kaggle/working/mod.pth\")\nmodel = torch.load('mod.pth', map_location=torch.device('cuda') )\n\nfor parameter in model.parameters():\n    parameter.requires_grad = False\n\nmodel.eval()","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2022-11-25T11:23:41.087795Z","iopub.execute_input":"2022-11-25T11:23:41.088162Z","iopub.status.idle":"2022-11-25T11:23:41.454008Z","shell.execute_reply.started":"2022-11-25T11:23:41.088103Z","shell.execute_reply":"2022-11-25T11:23:41.453147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TESTING\n","metadata":{}},{"cell_type":"code","source":"test_transforms = T.Compose([\n    T.Resize(IMG_SIZE),\n    T.ToTensor()\n])\n\ndef predict_image(image):\n    image_tensor = test_transforms(image).float()\n    image_tensor = image_tensor.unsqueeze_(0)\n    input = image_tensor.to(device)\n    output = model(input)\n    index = output.data.cpu().numpy().argmax()\n    return index\n\nTEST_DIR = '../input/cassava-leaf-disease-classification/test_images/'\ntest_images = os.listdir(TEST_DIR)\npredictions = []\n\nfor image in test_images:\n    img = Image.open(TEST_DIR + image)\n    output = predict_image(img)\n    predictions.append(output)\n\nsub = pd.DataFrame({'image_id': test_images, 'label': predictions})\ndisplay(sub)\nsub.to_csv('submission.csv', index = False)\n","metadata":{"execution":{"iopub.status.busy":"2022-11-25T11:23:41.455346Z","iopub.execute_input":"2022-11-25T11:23:41.455854Z","iopub.status.idle":"2022-11-25T11:23:41.843650Z","shell.execute_reply.started":"2022-11-25T11:23:41.455812Z","shell.execute_reply":"2022-11-25T11:23:41.842723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}