{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":5441,"databundleVersionId":38425,"sourceType":"competition"}],"dockerImageVersionId":30733,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install --upgrade lightning\n!pip install wandb","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:02:56.259584Z","iopub.execute_input":"2024-06-11T16:02:56.259831Z","iopub.status.idle":"2024-06-11T16:03:25.627063Z","shell.execute_reply.started":"2024-06-11T16:02:56.259809Z","shell.execute_reply":"2024-06-11T16:03:25.625998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport torch\nimport lightning as pl\nfrom torchmetrics.classification import Accuracy, F1Score\nfrom torch.utils.data import DataLoader, Dataset\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom lightning.pytorch.callbacks import ModelCheckpoint, EarlyStopping, TQDMProgressBar\nfrom lightning.pytorch.loggers import WandbLogger\nimport wandb","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:03:25.628848Z","iopub.execute_input":"2024-06-11T16:03:25.629155Z","iopub.status.idle":"2024-06-11T16:03:33.210725Z","shell.execute_reply.started":"2024-06-11T16:03:25.629129Z","shell.execute_reply":"2024-06-11T16:03:33.209925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!unzip /kaggle/input/dogs-vs-cats-redux-kernels-edition/train.zip -d /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:04:19.605527Z","iopub.execute_input":"2024-06-11T16:04:19.605899Z","iopub.status.idle":"2024-06-11T16:04:30.769148Z","shell.execute_reply.started":"2024-06-11T16:04:19.605871Z","shell.execute_reply":"2024-06-11T16:04:30.768227Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:04:32.399574Z","iopub.execute_input":"2024-06-11T16:04:32.399936Z","iopub.status.idle":"2024-06-11T16:04:33.348097Z","shell.execute_reply.started":"2024-06-11T16:04:32.399909Z","shell.execute_reply":"2024-06-11T16:04:33.347014Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomImageDataset(Dataset):\n    def __init__(self, image_dir, transform=None):\n        self.image_dir = image_dir\n        self.transform = transform\n        self.classes = os.listdir(image_dir)\n        self.image_paths = []\n        self.labels = []\n        \n        for img_name in os.listdir(image_dir):\n            self.image_paths.append(os.path.join(image_dir, img_name))\n            if img_name.startswith(\"cat\"):\n                self.labels.append(0)\n            else:\n                self.labels.append(1)\n        \n    def __len__(self):\n        return len(self.image_paths)\n    \n    def __getitem__(self, idx):\n        img_path = self.image_paths[idx]\n        image = cv2.imread(img_path)\n        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n        label = self.labels[idx]\n        \n        if self.transform:\n            augmented = self.transform(image=image)\n            image = augmented['image']\n        \n        return image, label","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:45:08.995857Z","iopub.execute_input":"2024-06-11T16:45:08.996730Z","iopub.status.idle":"2024-06-11T16:45:09.006666Z","shell.execute_reply.started":"2024-06-11T16:45:08.996698Z","shell.execute_reply":"2024-06-11T16:45:09.005551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SimpleCNN(pl.LightningModule):\n    def __init__(self, lr):\n        super(SimpleCNN, self).__init__()\n        self.model = torch.nn.Sequential(\n            torch.nn.Conv2d(3, 32, kernel_size=3, padding=\"same\"),\n            torch.nn.ReLU(),\n            torch.torch.nn.MaxPool2d(kernel_size=2),\n            torch.nn.Conv2d(32, 64, kernel_size=3, padding=\"same\"),\n            torch.nn.ReLU(),\n            torch.nn.MaxPool2d(kernel_size=2),\n            torch.nn.Flatten(),\n            torch.nn.Linear(64 * 64 * 64, 512),\n            torch.nn.ReLU(),\n            torch.nn.Linear(512, 64),\n            torch.nn.ReLU(),\n            torch.nn.Linear(64, 1),\n            torch.nn.Sigmoid(),\n        )\n        self.loss_fn = torch.nn.BCELoss()\n        self.lr = lr\n        \n        self.train_acc = Accuracy(task=\"binary\")\n        self.val_acc = Accuracy(task=\"binary\")\n        self.train_f1 = F1Score(task=\"binary\", average='macro')\n        self.val_f1 = F1Score(task=\"binary\", average='macro')\n    \n    def forward(self, x):\n        return self.model(x)\n    \n    def training_step(self, batch, batch_idx):\n        x, y = batch\n        y_hat = self(x).squeeze()\n        y = y.type(torch.float)\n        loss = self.loss_fn(y_hat, y)\n        y_hat = ((y_hat > 0.5) == y).type(torch.float)\n        \n        self.log('train_loss', loss)\n        self.train_acc.update(y_hat, y)\n        self.train_f1.update(y_hat, y)\n        self.log('train_acc', self.train_acc)\n        self.log('train_f1', self.train_f1)\n        \n        return loss\n    \n    def validation_step(self, batch, batch_idx):\n        x, y = batch\n        y_hat = self(x).squeeze()\n        y = y.type(torch.float)\n        val_loss = self.loss_fn(y_hat, y)\n        y_hat = ((y_hat > 0.5) == y).type(torch.float)\n        \n        self.val_acc.update(y_hat, y)\n        self.val_f1.update(y_hat, y)\n        self.log('val_loss', val_loss, prog_bar=True)\n        self.log('val_acc', self.val_acc)\n        self.log('val_f1', self.val_f1)\n        \n        return val_loss\n    \n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=self.lr, weight_decay=0.0001)\n        return optimizer\n    \n    def on_train_epoch_end(self):\n        self.log(\"train_acc_epoch\", self.train_acc.compute(), on_epoch=True)\n        self.log(\"train_f1_epoch\", self.train_f1.compute(), on_epoch=True)\n        self.train_acc.reset()\n        self.train_f1.reset()\n    \n    def on_validation_epoch_end(self):\n        self.log(\"val_acc_epoch\", self.val_acc.compute(), on_epoch=True)\n        self.log(\"val_f1_epoch\", self.val_f1.compute(), on_epoch=True)\n        self.val_acc.reset()\n        self.val_f1.reset()","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:45:09.674011Z","iopub.execute_input":"2024-06-11T16:45:09.674824Z","iopub.status.idle":"2024-06-11T16:45:09.694879Z","shell.execute_reply.started":"2024-06-11T16:45:09.674794Z","shell.execute_reply":"2024-06-11T16:45:09.693830Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_dir = '/kaggle/working/train'\ntransform = A.Compose([\n    A.Resize(256, 256),\n    A.RandomCrop(height=128, width=128, p=0.3),\n    A.Resize(256, 256),\n    A.Normalize(),\n    ToTensorV2(),\n])\n\ndataset = CustomImageDataset(image_dir, transform=transform)\ntrain_size = int(0.9 * len(dataset))\nval_size = len(dataset) - train_size\ntrain_dataset, val_dataset = torch.utils.data.random_split(dataset, [train_size, val_size], generator=torch.Generator().manual_seed(42))\ntrain_loader = DataLoader(train_dataset, batch_size=128, shuffle=True)\nval_loader = DataLoader(val_dataset, batch_size=128, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:45:10.605322Z","iopub.execute_input":"2024-06-11T16:45:10.605706Z","iopub.status.idle":"2024-06-11T16:45:10.703502Z","shell.execute_reply.started":"2024-06-11T16:45:10.605677Z","shell.execute_reply":"2024-06-11T16:45:10.702197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"checkpoint_callback = ModelCheckpoint(\n    monitor='val_loss',\n    dirpath='/kaggle/working/models/',\n    filename='best-checkpoint',\n    save_top_k=1,\n    mode='min'\n)\nearly_stopping_callback = EarlyStopping(\n    monitor='val_loss',\n    patience=7,\n    verbose=True,\n    mode='min'\n)\nprogress_bar = TQDMProgressBar(refresh_rate=10)\n\nwandb_logger = WandbLogger(project='cat_vs_dogs')\n\nmodel = SimpleCNN(lr=0.0001)\ntrainer = pl.Trainer(\n    max_epochs=10,\n    accelerator=\"auto\",\n    callbacks=[checkpoint_callback, early_stopping_callback, progress_bar],\n    logger = wandb_logger)","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:45:13.623283Z","iopub.execute_input":"2024-06-11T16:45:13.624092Z","iopub.status.idle":"2024-06-11T16:45:14.965941Z","shell.execute_reply.started":"2024-06-11T16:45:13.624061Z","shell.execute_reply":"2024-06-11T16:45:14.964840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(model, train_loader, val_loader)","metadata":{"execution":{"iopub.status.busy":"2024-06-11T16:45:18.862253Z","iopub.execute_input":"2024-06-11T16:45:18.862924Z","iopub.status.idle":"2024-06-11T17:00:55.414457Z","shell.execute_reply.started":"2024-06-11T16:45:18.862891Z","shell.execute_reply":"2024-06-11T17:00:55.413325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"wandb.finish()","metadata":{"execution":{"iopub.status.busy":"2024-06-11T17:03:29.541209Z","iopub.execute_input":"2024-06-11T17:03:29.541906Z","iopub.status.idle":"2024-06-11T17:03:33.601681Z","shell.execute_reply.started":"2024-06-11T17:03:29.541874Z","shell.execute_reply":"2024-06-11T17:03:33.600979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"execution":{"iopub.status.busy":"2024-06-11T17:04:01.160797Z","iopub.execute_input":"2024-06-11T17:04:01.161626Z","iopub.status.idle":"2024-06-11T17:04:04.285910Z","shell.execute_reply.started":"2024-06-11T17:04:01.161595Z","shell.execute_reply":"2024-06-11T17:04:04.284564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}