{"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":"markdown","source":"# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Image Classification with PyTorch-Lightning & Comet ML </div></b>\n![](https://img.freepik.com/free-vector/process-cancer-cell-development_1308-98254.jpg?w=1380&t=st=1683703025~exp=1683703625~hmac=c97f17908421e06077a85bc5122ccacd44d85eff4c237734edabc89a750a5cd0)\n\nHi guys 😀 In this notebook, we'll walk you through how to implement image classification with [PyTorch-Ligthning](https://lightning.ai/docs/pytorch/latest/) and track the parameters, metrics and source code with [Comet ML](https://www.comet.com/site/).\n\nTable of contents:\n<ul>\n<li><a href=\"#importing\">Importing required libraries </a></li>  \n<li><a href=\"#data-importing\">Importing the dataset </a></li>  \n<li><a href=\"#understanding\">Understanding the dataset</a></li>         \n<li><a href=\"#data-preprocessing\">Data preprocessing</a></li>   \n<li><a href=\"#data-loading\">Loading the dataset</a></li>\n<li><a href=\"#model-building\">Building the model</a></li>\n<li><a href=\"#creating-callbacks\">Creating Callbacks</a></li>   \n<li><a href=\"#model-traning\">Trainging the model</a></li>\n<li><a href=\"#model-evaluation\">Model prediction</a></li>      \n<li><a href=\"#conclusion\">Conclusion</a></li>   \n</ul>\n\nI'm excited, let's get started right away 🚀","metadata":{}},{"cell_type":"markdown","source":"<a id='importing'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Importing Required Libraries </div></b>","metadata":{}},{"cell_type":"code","source":"!pip install comet_ml -q","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:22.515867Z","iopub.execute_input":"2023-05-11T09:10:22.516870Z","iopub.status.idle":"2023-05-11T09:10:36.535103Z","shell.execute_reply.started":"2023-05-11T09:10:22.516832Z","shell.execute_reply":"2023-05-11T09:10:36.533930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport comet_ml\nimport shutil\nimport pandas as pd\nimport numpy as np\nfrom PIL import Image\nimport matplotlib.pyplot as plt\n\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import DataLoader, Dataset, random_split\nimport torchvision.transforms as T\nfrom torchvision.models import resnet50, ResNet50_Weights\nfrom torchmetrics import Accuracy, F1Score\n\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import EarlyStopping, Callback\nfrom pytorch_lightning.loggers import CometLogger","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:36.538703Z","iopub.execute_input":"2023-05-11T09:10:36.539032Z","iopub.status.idle":"2023-05-11T09:10:49.902141Z","shell.execute_reply.started":"2023-05-11T09:10:36.538999Z","shell.execute_reply":"2023-05-11T09:10:49.901266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Torch version:\",torch.__version__)\nprint(\"Ligthening version:\",pl.__version__)\nprint(\"Comet ML version\", comet_ml.__version__)","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:49.903677Z","iopub.execute_input":"2023-05-11T09:10:49.904034Z","iopub.status.idle":"2023-05-11T09:10:49.910790Z","shell.execute_reply.started":"2023-05-11T09:10:49.904000Z","shell.execute_reply":"2023-05-11T09:10:49.908689Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from kaggle_secrets import UserSecretsClient\nuser_secrets = UserSecretsClient()\nmy_api_key = user_secrets.get_secret(\"COMET_API_KEY\")","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:49.913627Z","iopub.execute_input":"2023-05-11T09:10:49.913984Z","iopub.status.idle":"2023-05-11T09:10:50.132989Z","shell.execute_reply.started":"2023-05-11T09:10:49.913939Z","shell.execute_reply":"2023-05-11T09:10:50.132184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='data-importing'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Importing the Dataset </div></b>","metadata":{}},{"cell_type":"code","source":"cancer_labels = pd.read_csv(\"/kaggle/input/histopathologic-cancer-detection/train_labels.csv\")\ncancer_labels.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:50.134625Z","iopub.execute_input":"2023-05-11T09:10:50.134886Z","iopub.status.idle":"2023-05-11T09:10:50.491091Z","shell.execute_reply.started":"2023-05-11T09:10:50.134863Z","shell.execute_reply":"2023-05-11T09:10:50.489977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='understanding'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Understanding the Dataset </div></b>","metadata":{}},{"cell_type":"code","source":"base_dir = '../input/histopathologic-cancer-detection/'\nprint(\"Train Size: {}\".format(len(os.listdir(f'{base_dir}train'))))\nprint(\"Test Size: {}\".format(len(os.listdir(f'{base_dir}test'))))","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:50.492489Z","iopub.execute_input":"2023-05-11T09:10:50.492895Z","iopub.status.idle":"2023-05-11T09:10:53.969432Z","shell.execute_reply.started":"2023-05-11T09:10:50.492856Z","shell.execute_reply":"2023-05-11T09:10:53.968220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_count = cancer_labels.label.value_counts()\n\nplt.pie(labels_count, labels=['No Cancer', 'Cancer'], startangle=180, autopct='%1.1f')\nplt.figure(figsize=(16,16))\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:53.970744Z","iopub.execute_input":"2023-05-11T09:10:53.971338Z","iopub.status.idle":"2023-05-11T09:10:54.165318Z","shell.execute_reply.started":"2023-05-11T09:10:53.971300Z","shell.execute_reply":"2023-05-11T09:10:54.164070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = plt.figure(figsize=(25, 6))\n\ntrain_imgs = os.listdir(base_dir+\"train\")\nfor idx, img in enumerate(np.random.choice(train_imgs, 20)):\n    ax = fig.add_subplot(2, 20//2, idx+1, xticks=[], yticks=[])\n    im = Image.open(base_dir+\"train/\" + img)\n    plt.imshow(im)\n    lab = cancer_labels.loc[cancer_labels['id'] == img.split('.')[0], 'label'].values[0]\n    ax.set_title('Label: %s'%lab)","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:54.166564Z","iopub.execute_input":"2023-05-11T09:10:54.167309Z","iopub.status.idle":"2023-05-11T09:10:56.576296Z","shell.execute_reply.started":"2023-05-11T09:10:54.167275Z","shell.execute_reply":"2023-05-11T09:10:56.575024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='data-preprocessing'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Data Preprocessing</div></b>","metadata":{}},{"cell_type":"code","source":"np.random.seed(0)\ntrain_imgs_orig = os.listdir(\"/kaggle/input/histopathologic-cancer-detection/train\")\nselected_image_list = []\nfor img in np.random.choice(train_imgs_orig, 10000):\n    selected_image_list.append(img)\nlen(selected_image_list)","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:56.577463Z","iopub.execute_input":"2023-05-11T09:10:56.577774Z","iopub.status.idle":"2023-05-11T09:10:56.852365Z","shell.execute_reply.started":"2023-05-11T09:10:56.577748Z","shell.execute_reply":"2023-05-11T09:10:56.851319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.random.seed(0)\nnp.random.shuffle(selected_image_list)\ncancer_train_idx = selected_image_list[:8000]\ncancer_test_idx = selected_image_list[8000:10000]\nprint(\"Number of images in the downsampled training dataset: \", len(cancer_train_idx))\nprint(\"Number of images in the downsampled testing dataset: \", len(cancer_test_idx))","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:56.857131Z","iopub.execute_input":"2023-05-11T09:10:56.857425Z","iopub.status.idle":"2023-05-11T09:10:56.863882Z","shell.execute_reply.started":"2023-05-11T09:10:56.857400Z","shell.execute_reply":"2023-05-11T09:10:56.862886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('/kaggle/working/cancer_train_dataset/')\nfor fname in cancer_train_idx:\n    src = os.path.join('/kaggle/input/histopathologic-cancer-detection/train', fname)\n    dst = os.path.join('/kaggle/working/cancer_train_dataset', fname)\n    shutil.copyfile(src, dst)\nprint('Number of images in downsampled training dataset: ', len(os.listdir(\"/kaggle/working/cancer_train_dataset\")))","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:10:56.865156Z","iopub.execute_input":"2023-05-11T09:10:56.866148Z","iopub.status.idle":"2023-05-11T09:11:42.493594Z","shell.execute_reply.started":"2023-05-11T09:10:56.866108Z","shell.execute_reply":"2023-05-11T09:11:42.492630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.mkdir('/kaggle/working/cancer_test_dataset/')\nfor fname in cancer_test_idx:\n    src = os.path.join('/kaggle/input/histopathologic-cancer-detection/train', fname)\n    dst = os.path.join('/kaggle/working/cancer_test_dataset/', fname)\n    shutil.copyfile(src, dst)\nprint('Number of images in downsampled testing dataset: ', len(os.listdir(\"/kaggle/working/cancer_test_dataset/\")))","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:11:42.494913Z","iopub.execute_input":"2023-05-11T09:11:42.495451Z","iopub.status.idle":"2023-05-11T09:11:53.231865Z","shell.execute_reply.started":"2023-05-11T09:11:42.495415Z","shell.execute_reply":"2023-05-11T09:11:53.230916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"selected_image_labels = pd.DataFrame()\nid_list = []\nlabel_list = []\n\nfor img in selected_image_list:\n    label_tuple = cancer_labels.loc[cancer_labels['id'] == img.split('.')[0]]\n    id_list.append(label_tuple['id'].values[0])\n    label_list.append(label_tuple['label'].values[0])","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:11:53.233439Z","iopub.execute_input":"2023-05-11T09:11:53.233801Z","iopub.status.idle":"2023-05-11T09:17:08.355949Z","shell.execute_reply.started":"2023-05-11T09:11:53.233768Z","shell.execute_reply":"2023-05-11T09:17:08.354990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"selected_image_labels['id'] = id_list\nselected_image_labels['label'] = label_list\nselected_image_labels.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.357423Z","iopub.execute_input":"2023-05-11T09:17:08.357761Z","iopub.status.idle":"2023-05-11T09:17:08.414397Z","shell.execute_reply.started":"2023-05-11T09:17:08.357729Z","shell.execute_reply":"2023-05-11T09:17:08.413433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_class_dict = {k:v for k, v in zip(selected_image_labels.id, selected_image_labels.label)}","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.415671Z","iopub.execute_input":"2023-05-11T09:17:08.416605Z","iopub.status.idle":"2023-05-11T09:17:08.433801Z","shell.execute_reply.started":"2023-05-11T09:17:08.416573Z","shell.execute_reply":"2023-05-11T09:17:08.432927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='data-loading'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Loading the Dataset</div></b>","metadata":{}},{"cell_type":"code","source":"class LoadCancerDataset(Dataset):\n    def __init__(self, datafolder, transform, labels_dict={}):\n        self.datafolder = datafolder\n        self.image_files_list = [s for s in os.listdir(datafolder)]\n        self.transform = transform\n        self.labels_dict = labels_dict\n        self.labels = [labels_dict[i.split('.')[0]] for i in self.image_files_list]\n\n    def __len__(self):\n        return len(self.image_files_list)\n\n    def __getitem__(self, idx):\n        img_name = os.path.join(self.datafolder, self.image_files_list[idx])\n        image = Image.open(img_name)\n        image = self.transform(image)\n        img_name_short = self.image_files_list[idx].split('.')[0]\n        label = self.labels_dict[img_name_short]\n        return image, label","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.434935Z","iopub.execute_input":"2023-05-11T09:17:08.435253Z","iopub.status.idle":"2023-05-11T09:17:08.445688Z","shell.execute_reply.started":"2023-05-11T09:17:08.435223Z","shell.execute_reply":"2023-05-11T09:17:08.444793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CancerDataModule(pl.LightningDataModule):\n    def __init__(self, batch_size, num_workers, data_dir):\n        super().__init__()\n        self.data_dir = data_dir\n        self.batch_size = batch_size\n        self.num_workers = num_workers\n\n    def prepare_data(self):\n        \"\"\"\n        The prepare_data method was intentionally left empty as we have the dataset in our directory.\n        \"\"\"\n        pass\n\n    def setup(self, stage=None):\n        # Assign train/val datasets for use in dataloaders\n        if stage == \"fit\" or stage is None:            \n            train_set_full = LoadCancerDataset(\n                datafolder=f'{self.data_dir}/cancer_train_dataset',  \n                transform=T.Compose([\n                    T.Resize(224),\n                    T.RandomHorizontalFlip(),\n                    T.RandomVerticalFlip(),\n                    T.ToTensor()\n                ]),\n                labels_dict=img_class_dict\n            )\n            train_set_size = int(len(train_set_full) * 0.9)\n            valid_set_size = len(train_set_full) - train_set_size\n            self.train_ds, self.val_ds = random_split(train_set_full, [train_set_size, valid_set_size])  \n\n        # Assign test dataset for use in dataloader(s)     \n        if stage == \"test\" or stage is None:            \n            self.test_ds = LoadCancerDataset(\n                datafolder=f'{self.data_dir}/cancer_test_dataset',\n                transform=T.Compose([\n                    T.Resize(224),\n                    T.ToTensor()]),\n                labels_dict=img_class_dict\n            )\n\n    def train_dataloader(self):\n        return DataLoader(self.train_ds, batch_size=self.batch_size, num_workers=self.num_workers, shuffle=True)\n\n    def val_dataloader(self):\n        return DataLoader( self.val_ds, batch_size=self.batch_size, num_workers=self.num_workers, shuffle=False)\n\n    def test_dataloader(self):\n        return DataLoader( self.test_ds, batch_size=self.batch_size, num_workers=self.num_workers, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.447453Z","iopub.execute_input":"2023-05-11T09:17:08.448133Z","iopub.status.idle":"2023-05-11T09:17:08.461425Z","shell.execute_reply.started":"2023-05-11T09:17:08.448102Z","shell.execute_reply":"2023-05-11T09:17:08.460505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='model-building'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Buiding the Model</div></b>","metadata":{}},{"cell_type":"code","source":"class CancerImageClassifier(pl.LightningModule):\n\n    def __init__(self, learning_rate = 0.001, num_classes = 2):   \n        super().__init__()\n        self.learning_rate = learning_rate\n        self.loss_fn = nn.CrossEntropyLoss()   \n        self.num_classes = num_classes\n        self.accuracy = Accuracy(task=\"binary\", num_classes=num_classes)  \n        self.f1_score = F1Score(task=\"binary\", num_classes=num_classes)\n        self.history = {'train_loss' : [], 'train_acc' : [], 'val_loss' : [], 'val_acc' : []}\n        \n        self.pretrain_model = resnet50(weights=ResNet50_Weights.DEFAULT)\n        self.pretrain_model.eval()\n        for param in self.pretrain_model.parameters():\n            param.requires_grad = False\n        \n        self.pretrain_model.fc = nn.Sequential(\n            nn.Linear(self.pretrain_model.fc.in_features, 1024),\n            nn.ReLU(),\n            nn.Dropout(),\n            nn.Linear(1024,self.num_classes)\n        )\n\n    def forward(self, input):\n        output=self.pretrain_model(input)\n        return output\n\n    def training_step(self, batch, batch_idx):       \n        outputs, targets, loss, preds = self._common_step(batch, batch_idx)     \n        train_accuracy = self.accuracy(preds, targets)           \n        self.history['train_loss'].append(loss.item())\n        self.history['train_acc'].append(train_accuracy.item())      \n        self.log_dict(\n            {\"train_loss\": loss,\"train_acc\": train_accuracy,},\n            on_step=False, on_epoch=True, prog_bar=True)  \n        return {\"loss\":loss, 'train_acc': train_accuracy}\n            \n    def validation_step(self, batch, batch_idx):      \n        outputs, targets, loss, preds = self._common_step(batch, batch_idx)  \n        val_accuracy = self.accuracy(preds, targets)     \n        self.history['val_loss'].append(loss.item())\n        self.history['val_acc'].append(val_accuracy.item())     \n        self.log_dict(\n            {\"val_loss\": loss,\"val_acc\": val_accuracy},\n            on_step=False, on_epoch=True, prog_bar=True,\n        )\n        return {\"loss\":loss, 'val_acc': val_accuracy}\n    \n    def test_step(self, batch, batch_idx):\n        outputs, targets, loss, preds = self._common_step(batch, batch_idx)\n        test_accuracy = self.accuracy(preds, targets)           \n        f1_score = self.f1_score(preds, targets)         \n        self.log_dict(\n            {\"test_loss\": loss,\"test_acc\": test_accuracy, \"test_f1_score\": f1_score},\n            on_step=False, on_epoch=True, prog_bar=True,\n        )\n        return {\"test_loss\":loss, \"test_accuracy\":test_accuracy, \"test_f1_score\": f1_score}\n    \n    def _common_step(self, batch, batch_idx):\n        inputs, targets = batch\n        outputs = self.forward(inputs)\n        loss = self.loss_fn(outputs, targets)\n        preds = torch.argmax(outputs, dim=1)\n        return outputs, targets, loss, preds\n\n    def configure_optimizers(self):\n        params = self.parameters()\n        optimizer = optim.Adam(params=params, lr = self.learning_rate)\n        return optimizer","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.462748Z","iopub.execute_input":"2023-05-11T09:17:08.463092Z","iopub.status.idle":"2023-05-11T09:17:08.481836Z","shell.execute_reply.started":"2023-05-11T09:17:08.463058Z","shell.execute_reply":"2023-05-11T09:17:08.480871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='creating-callbacks'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Creating Callbacks</div></b>","metadata":{}},{"cell_type":"code","source":"# Callback to monitor metrics\nclass PrintCallback(pl.Callback):\n    def on_train_epoch_end(self, trainer, pl_module):\n        print(\"Epoch {}, train loss: {:.3f}, train acc: {:.3f} \".format(trainer.current_epoch, \n                                         trainer.callback_metrics['train_loss'].item(),\n                                         trainer.callback_metrics['train_acc'].item()))\n        print(\"-\" * 10)\n\n    def on_validation_epoch_end(self, trainer, pl_module):\n        print(\"Epoch {}, val loss: {:.3f}, val acc: {:.3f} \".format(trainer.current_epoch, \n                                      trainer.callback_metrics['val_loss'].item(), \n                                      trainer.callback_metrics['val_acc'].item()))","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.483204Z","iopub.execute_input":"2023-05-11T09:17:08.483526Z","iopub.status.idle":"2023-05-11T09:17:08.496304Z","shell.execute_reply.started":"2023-05-11T09:17:08.483495Z","shell.execute_reply":"2023-05-11T09:17:08.495459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='model-traing'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Training the Model</div></b>","metadata":{}},{"cell_type":"code","source":"#Setting the hyperparameters\nhyper_params = {\n    # Training hyperparameters\n    \"NUM_CLASSES\": 2, \n    \"LEARNING_RATE\": 0.001, \n    \"BATCH_SIZE\": 128,\n    \"NUM_EPOCHS\": 15,\n    # Dataset\n    \"DATA_DIR\": \"/kaggle/working\",\n    \"NUM_WORKERS\": os.cpu_count(),\n    # Compute related\n    \"ACCELERATOR\": \"auto\",\n    \"DEVICES\": \"auto\",\n    }","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.497845Z","iopub.execute_input":"2023-05-11T09:17:08.498185Z","iopub.status.idle":"2023-05-11T09:17:08.505740Z","shell.execute_reply.started":"2023-05-11T09:17:08.498155Z","shell.execute_reply":"2023-05-11T09:17:08.504774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create an experiment with your API key\ncomet_logger = CometLogger(\n    api_key= my_api_key,\n    workspace=\"tirendaz\",\n    project_name=\"cancer-tracking\"\n)\n\n# Logging hyperparamters\ncomet_logger.experiment.log_parameters(hyper_params)","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:08.507243Z","iopub.execute_input":"2023-05-11T09:17:08.507621Z","iopub.status.idle":"2023-05-11T09:17:12.587209Z","shell.execute_reply.started":"2023-05-11T09:17:08.507590Z","shell.execute_reply":"2023-05-11T09:17:12.586200Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"my_dataloader = CancerDataModule(\n        batch_size=hyper_params[\"BATCH_SIZE\"],\n        num_workers=hyper_params[\"NUM_WORKERS\"],\n        data_dir=hyper_params[\"DATA_DIR\"])\n\nmy_model = CancerImageClassifier(\n        num_classes=hyper_params[\"NUM_CLASSES\"],\n        learning_rate=hyper_params[\"LEARNING_RATE\"])\n\nmy_trainer = pl.Trainer(\n        logger=comet_logger,\n        accelerator=hyper_params[\"ACCELERATOR\"],\n        devices=hyper_params[\"DEVICES\"],\n        callbacks=[PrintCallback()],  \n        max_epochs=hyper_params[\"NUM_EPOCHS\"])\n\nmy_trainer.fit(my_model, my_dataloader)","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:17:12.591885Z","iopub.execute_input":"2023-05-11T09:17:12.594431Z","iopub.status.idle":"2023-05-11T09:19:35.437298Z","shell.execute_reply.started":"2023-05-11T09:17:12.594384Z","shell.execute_reply":"2023-05-11T09:19:35.436308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize = (15, 5))\nplt.subplot(1,2,1)\nplt.title('Training Loss')\nplt.xlabel('Steps')\nplt.plot(my_model.history['train_loss'])\n\nplt.subplot(1,2,2)\nplt.title('Training Accuracy')\nplt.xlabel('Steps')\nplt.plot(my_model.history['train_acc'])","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:19:35.439219Z","iopub.execute_input":"2023-05-11T09:19:35.439571Z","iopub.status.idle":"2023-05-11T09:19:35.852651Z","shell.execute_reply.started":"2023-05-11T09:19:35.439537Z","shell.execute_reply":"2023-05-11T09:19:35.851821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='model-evaluation'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Model Evaluation</div></b>","metadata":{}},{"cell_type":"code","source":"my_dataloader.setup()\nmy_trainer.test(model=my_model, dataloaders=my_dataloader.test_dataloader())","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:19:35.854087Z","iopub.execute_input":"2023-05-11T09:19:35.854606Z","iopub.status.idle":"2023-05-11T09:19:43.704892Z","shell.execute_reply.started":"2023-05-11T09:19:35.854572Z","shell.execute_reply":"2023-05-11T09:19:43.703962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Saving Model in Comet-ML\nfrom comet_ml.integration.pytorch import log_model\nlog_model(comet_logger.experiment, my_model, model_name=\"my_pl_model\")","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:19:43.706384Z","iopub.execute_input":"2023-05-11T09:19:43.706731Z","iopub.status.idle":"2023-05-11T09:19:45.309583Z","shell.execute_reply.started":"2023-05-11T09:19:43.706694Z","shell.execute_reply":"2023-05-11T09:19:45.308469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Ending our experiment\ncomet_logger.experiment.end()","metadata":{"execution":{"iopub.status.busy":"2023-05-11T09:19:45.315483Z","iopub.execute_input":"2023-05-11T09:19:45.316153Z","iopub.status.idle":"2023-05-11T09:19:49.578290Z","shell.execute_reply.started":"2023-05-11T09:19:45.316126Z","shell.execute_reply":"2023-05-11T09:19:49.577395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<a id='conclusion'></a>\n# <b><div style='padding:15px;background-color:#850E35;color:white;border-radius:2px;font-size:110%;text-align: center'>Conclusion</div></b>\n\nIn this notebook, we learned how to perform image classification with PyTorch-Lightning. Thanks for taking the time! If you enjoyed it, please consider upvoting.\n\n\n🔗 Let's connect [YouTube](http://youtube.com/tirendazacademy) | [Medium](http://tirendazacademy.medium.com) | [Twitter](http://twitter.com/tirendazacademy) | [Instagram](https://www.instagram.com/tirendazacademy) | [GitHub](http://github.com/tirendazacademy) | [Linkedin](https://www.linkedin.com/in/tirendaz-academy) | [Kaggle](https://www.kaggle.com/tirendazacademy) 😎","metadata":{}},{"cell_type":"markdown","source":"## Resource\n- [Deep Learning with PyTorch Lightning](https://www.amazon.com/dp/180056161X)","metadata":{}}]}