{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30698,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:54:29.817424Z","iopub.execute_input":"2024-05-10T04:54:29.817786Z","iopub.status.idle":"2024-05-10T04:54:30.822312Z","shell.execute_reply.started":"2024-05-10T04:54:29.817756Z","shell.execute_reply":"2024-05-10T04:54:30.821145Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%capture\n!pip install fastai","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:54:30.824671Z","iopub.execute_input":"2024-05-10T04:54:30.825059Z","iopub.status.idle":"2024-05-10T04:54:44.495352Z","shell.execute_reply.started":"2024-05-10T04:54:30.825024Z","shell.execute_reply":"2024-05-10T04:54:44.494249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Imports","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport glob\nimport random\nimport zipfile\nimport numpy as np\nimport pandas as pd\nfrom pathlib import Path\n\nimport torch\nfrom fastai.vision.all import * \nfrom torchvision import transforms \nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.transforms import v2\nfrom sklearn.model_selection import train_test_split\n\nimport matplotlib.pyplot as plt\n%matplotlib inline","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:54:44.496760Z","iopub.execute_input":"2024-05-10T04:54:44.497058Z","iopub.status.idle":"2024-05-10T04:54:51.556873Z","shell.execute_reply.started":"2024-05-10T04:54:44.497032Z","shell.execute_reply":"2024-05-10T04:54:51.556044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Processing","metadata":{}},{"cell_type":"code","source":"data_dir = Path(\"/kaggle/input/dogs-vs-cats-redux-kernels-edition/\")\nzipfiles = [Path(file) for file in glob.glob(f\"{data_dir}/*.zip\")]\nzipfiles","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:54:51.560932Z","iopub.execute_input":"2024-05-10T04:54:51.561859Z","iopub.status.idle":"2024-05-10T04:54:51.570292Z","shell.execute_reply.started":"2024-05-10T04:54:51.561829Z","shell.execute_reply":"2024-05-10T04:54:51.569343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def extract_file(file):\n    with zipfile.ZipFile(file, 'r') as f:\n        f.extractall('data')\n        \nfor file in zipfiles:\n    extract_file(file)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:54:51.571356Z","iopub.execute_input":"2024-05-10T04:54:51.571675Z","iopub.status.idle":"2024-05-10T04:55:07.372747Z","shell.execute_reply.started":"2024-05-10T04:54:51.571644Z","shell.execute_reply":"2024-05-10T04:55:07.371896Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TRAIN_DIR = \"/kaggle/working/data/train/\"\nTEST_DIR = \"/kaggle/working/data/test/\"\n\nlen(os.listdir(TRAIN_DIR)), len(os.listdir(TEST_DIR))","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:55:07.373855Z","iopub.execute_input":"2024-05-10T04:55:07.374171Z","iopub.status.idle":"2024-05-10T04:55:07.401937Z","shell.execute_reply.started":"2024-05-10T04:55:07.374145Z","shell.execute_reply":"2024-05-10T04:55:07.401147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_labels(file_path):\n    labels = []\n    for file in os.listdir(file_path):\n        label = file.split('.')[0]\n        if label == 'dog':\n            labels.append(1)\n        elif label == \"cat\":\n            labels.append(0)\n    return labels","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:55:07.403027Z","iopub.execute_input":"2024-05-10T04:55:07.403372Z","iopub.status.idle":"2024-05-10T04:55:07.714660Z","shell.execute_reply.started":"2024-05-10T04:55:07.403338Z","shell.execute_reply":"2024-05-10T04:55:07.713657Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x_train = [cv2.imread(TRAIN_DIR + i) for i in os.listdir(TRAIN_DIR)]\ny_train = get_labels(TRAIN_DIR)\nx_test = [cv2.imread(TEST_DIR + i) for i in os.listdir(TEST_DIR)]\nlen(x_train), len(y_train), len(x_test)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:55:07.715924Z","iopub.execute_input":"2024-05-10T04:55:07.716720Z","iopub.status.idle":"2024-05-10T04:56:25.188617Z","shell.execute_reply.started":"2024-05-10T04:55:07.716685Z","shell.execute_reply":"2024-05-10T04:56:25.187472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"samples = [torch.tensor(img) for img in x_train[13: 19]]\n\ndef plot_imgs(samples, title, permute=False):\n    plt.suptitle(title)\n    for idx, sample in enumerate(samples):\n        plt.subplot(2, 3, idx+1)\n        plt.axis(False)\n        if permute:\n            sample = sample.permute(1, 2 ,0)\n        plt.imshow(sample)\n        \nplot_imgs(samples, \"Original Set\")","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:25.190116Z","iopub.execute_input":"2024-05-10T04:56:25.190478Z","iopub.status.idle":"2024-05-10T04:56:25.839773Z","shell.execute_reply.started":"2024-05-10T04:56:25.190445Z","shell.execute_reply":"2024-05-10T04:56:25.838829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Augmentations   \n- AutoAugment\n- RandAugment\n- CutMix\n- MixUp","metadata":{}},{"cell_type":"markdown","source":"### 1) AutoAugment","metadata":{}},{"cell_type":"code","source":"def apply_transform(samples, transforms):\n    imgs = []\n    for sample in samples:\n        aug_img = transforms(sample.permute(2, 0, 1))\n        imgs.append(aug_img)\n    return imgs","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:25.842794Z","iopub.execute_input":"2024-05-10T04:56:25.843079Z","iopub.status.idle":"2024-05-10T04:56:25.848193Z","shell.execute_reply.started":"2024-05-10T04:56:25.843055Z","shell.execute_reply":"2024-05-10T04:56:25.847207Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"auto_samples = samples.copy()\nauto_augs = v2.AutoAugment(policy=transforms.autoaugment.AutoAugmentPolicy.IMAGENET)\nauto_aug_imgs = apply_transform(auto_samples, auto_augs)\nplot_imgs(auto_aug_imgs, \"AutoAugment\", permute=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:25.849393Z","iopub.execute_input":"2024-05-10T04:56:25.849704Z","iopub.status.idle":"2024-05-10T04:56:26.496984Z","shell.execute_reply.started":"2024-05-10T04:56:25.849681Z","shell.execute_reply":"2024-05-10T04:56:26.495978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 2) RandAugment","metadata":{}},{"cell_type":"code","source":"rand_samples = samples.copy()\nrand_augs = v2.RandAugment(num_ops=3)\nrand_aug_imgs = apply_transform(rand_samples, rand_augs)\nplot_imgs(rand_aug_imgs, \"RandAugment\", permute=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:26.498214Z","iopub.execute_input":"2024-05-10T04:56:26.498531Z","iopub.status.idle":"2024-05-10T04:56:27.055608Z","shell.execute_reply.started":"2024-05-10T04:56:26.498504Z","shell.execute_reply":"2024-05-10T04:56:27.054654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 3) CutMix","metadata":{}},{"cell_type":"code","source":"df = pd.DataFrame({'img': x_train, 'label': y_train})\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:27.056802Z","iopub.execute_input":"2024-05-10T04:56:27.057114Z","iopub.status.idle":"2024-05-10T04:56:43.812955Z","shell.execute_reply.started":"2024-05-10T04:56:27.057070Z","shell.execute_reply":"2024-05-10T04:56:43.811888Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CatsDogsDataset(Dataset):\n    def __init__(self, df):\n        self.imgs = df['img'].values\n        self.labels = df['label'].values\n        self.augs = transforms.Compose([\n            transforms.Resize((224,224), antialias=True)\n        ])\n        \n    def __len__(self):\n        return len(df)\n    \n    def __getitem__(self, idx):\n        img = torch.tensor(self.imgs[idx], dtype=torch.float).permute(2, 0, 1)\n        aug_img = self.augs(img)\n        label = self.labels[idx]\n        return aug_img, label","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:43.814552Z","iopub.execute_input":"2024-05-10T04:56:43.814910Z","iopub.status.idle":"2024-05-10T04:56:43.822244Z","shell.execute_reply.started":"2024-05-10T04:56:43.814878Z","shell.execute_reply":"2024-05-10T04:56:43.821174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dset = CatsDogsDataset(df)\ndataloader = DataLoader(dset, batch_size=16, shuffle=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:43.823735Z","iopub.execute_input":"2024-05-10T04:56:43.824069Z","iopub.status.idle":"2024-05-10T04:56:43.836379Z","shell.execute_reply.started":"2024-05-10T04:56:43.824038Z","shell.execute_reply":"2024-05-10T04:56:43.835433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cutmix = v2.CutMix(num_classes=2)\nfor image, label in dataloader:\n    print(f\"Before CutMix: {image.shape = }, {label.shape = }\")\n    img, labels = cutmix(image, label)\n    print(f\"After CutMix: {img.shape = }, {labels.shape = }\")\n    break","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:43.837432Z","iopub.execute_input":"2024-05-10T04:56:43.837688Z","iopub.status.idle":"2024-05-10T04:56:43.912707Z","shell.execute_reply.started":"2024-05-10T04:56:43.837667Z","shell.execute_reply":"2024-05-10T04:56:43.911989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### 4) MixUp","metadata":{}},{"cell_type":"code","source":"mixup = v2.MixUp(num_classes=2)\nfor image, label in dataloader:\n    print(f\"Before MixUp: {image.shape = }, {label.shape = }\")\n    img, labels = mixup(image, label)\n    print(f\"After MixUp: {img.shape = }, {labels.shape = }\")\n    break","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:43.913673Z","iopub.execute_input":"2024-05-10T04:56:43.914326Z","iopub.status.idle":"2024-05-10T04:56:43.961959Z","shell.execute_reply.started":"2024-05-10T04:56:43.914298Z","shell.execute_reply":"2024-05-10T04:56:43.960940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Sample Model Training","metadata":{}},{"cell_type":"code","source":"cd_data = DataBlock(blocks = (ImageBlock, CategoryBlock),\n                   get_items=get_image_files,\n                    splitter=RandomSplitter(seed=42),\n                    get_y=using_attr(RegexLabeller(r'(cat|dog)'), 'name'),\n                    item_tfms=Resize(224),\n                    batch_tfms=aug_transforms(size=224, min_scale=0.75))\ndls = cd_data.dataloaders('/kaggle/working/data/train')","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:46.712235Z","iopub.execute_input":"2024-05-10T04:56:46.712502Z","iopub.status.idle":"2024-05-10T04:56:49.270992Z","shell.execute_reply.started":"2024-05-10T04:56:46.712477Z","shell.execute_reply":"2024-05-10T04:56:49.269920Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dls.show_batch()","metadata":{"execution":{"iopub.status.busy":"2024-05-10T04:56:49.272282Z","iopub.execute_input":"2024-05-10T04:56:49.272633Z","iopub.status.idle":"2024-05-10T04:56:50.828026Z","shell.execute_reply.started":"2024-05-10T04:56:49.272601Z","shell.execute_reply":"2024-05-10T04:56:50.826976Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"es_cb = EarlyStoppingCallback(patience=2)\nsm_cb = SaveModelCallback()\ncallbacks = [es_cb, sm_cb]","metadata":{"execution":{"iopub.status.busy":"2024-05-10T05:30:40.566507Z","iopub.execute_input":"2024-05-10T05:30:40.567404Z","iopub.status.idle":"2024-05-10T05:30:40.575010Z","shell.execute_reply.started":"2024-05-10T05:30:40.567357Z","shell.execute_reply":"2024-05-10T05:30:40.574120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Baseline Model","metadata":{}},{"cell_type":"code","source":"learn = vision_learner(dls, resnet18, metrics=accuracy, cbs=callbacks)\nlearn.fine_tune(3, 3e-3)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T05:30:42.767624Z","iopub.execute_input":"2024-05-10T05:30:42.767996Z","iopub.status.idle":"2024-05-10T05:35:31.434993Z","shell.execute_reply.started":"2024-05-10T05:30:42.767967Z","shell.execute_reply":"2024-05-10T05:35:31.433801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds, targs = learn.tta()\naccuracy(preds, targs).item()","metadata":{"execution":{"iopub.status.busy":"2024-05-10T05:35:31.437320Z","iopub.execute_input":"2024-05-10T05:35:31.437700Z","iopub.status.idle":"2024-05-10T05:36:43.999402Z","shell.execute_reply.started":"2024-05-10T05:35:31.437662Z","shell.execute_reply":"2024-05-10T05:36:43.998229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Since the baseline model achieves sufficiently high accuracy, improving it further by techniques such as MixUp or CutMix are not required. However, lets try it out for curiosity's sake.","metadata":{}},{"cell_type":"markdown","source":"### Baseline + MixUp Augmentation","metadata":{}},{"cell_type":"code","source":"mixup = MixUp()\ncallbacks.append(mixup)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T05:36:44.001424Z","iopub.execute_input":"2024-05-10T05:36:44.001785Z","iopub.status.idle":"2024-05-10T05:36:44.007078Z","shell.execute_reply.started":"2024-05-10T05:36:44.001750Z","shell.execute_reply":"2024-05-10T05:36:44.006247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"learn = vision_learner(dls, resnet18, metrics=accuracy, cbs=callbacks)\nlearn.fine_tune(3, 3e-3)","metadata":{"execution":{"iopub.status.busy":"2024-05-10T05:36:44.009327Z","iopub.execute_input":"2024-05-10T05:36:44.009848Z","iopub.status.idle":"2024-05-10T05:41:34.926356Z","shell.execute_reply.started":"2024-05-10T05:36:44.009817Z","shell.execute_reply":"2024-05-10T05:41:34.925267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds, targs = learn.tta()\naccuracy(preds, targs).item()","metadata":{"execution":{"iopub.status.busy":"2024-05-10T05:41:34.927683Z","iopub.execute_input":"2024-05-10T05:41:34.928401Z","iopub.status.idle":"2024-05-10T05:42:47.520371Z","shell.execute_reply.started":"2024-05-10T05:41:34.928368Z","shell.execute_reply":"2024-05-10T05:42:47.519019Z"},"trusted":true},"execution_count":null,"outputs":[]}]}