{"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":"## RSNA Pneumonia Detection Challenge\n\n**Last updated: May 1, 2023 (completed)**\n\nCompetition Link: https://www.kaggle.com/competitions/rsna-pneumonia-detection-challenge/\n\nbuilding an algorithm that automatically detects potential pneumonia cases using Pytorch Lightning\n\n**About Challenge:** The competition challenges us to create an algorithm that can detect lung opacities on chest radiographs to aid in the accurate diagnosis of pneumonia, which is responsible for many deaths of children under 5 and emergency room visits in the US. Diagnosing pneumonia is difficult because other lung conditions and factors can cause increased opacity on the radiograph. CXRs are commonly used but their interpretation can be complicated and time-consuming, making an automated solution helpful in improving the efficiency and reach of diagnostic services. The Radiological Society of North America (RSNA®) has collaborated with Kaggle's machine learning community, the US National Institutes of Health, The Society of Thoracic Radiology, and MD.ai to create a dataset for this challenge.\n\n**About Dataset:** This is an update to a two-stage machine learning challenge to develop an algorithm that detects pneumonia in medical images by automatically locating lung opacities on chest radiographs. The dataset contains training and test images in DICOM format, along with training labels that include bounding boxes for pneumonia and a binary target column indicating whether evidence of pneumonia is present. Competitors are expected to predict bounding boxes for areas of the lung where pneumonia is present. The file format for predictions should include confidence, x-min, y-min, width, and height values, and there should be only one predicted row per image.\n\nThe dataset for this challenge consists of chest radiographs in DICOM format. The training set contains a total of 26,684 images, which includes both the images from the stage 1 train set and the new stage 2 train set. The stage 2 test set contains 3,640 new, unseen images.\n\n\n","metadata":{}},{"cell_type":"markdown","source":"## Importing Necessary Libraries and reading files","metadata":{}},{"cell_type":"code","source":"from pathlib import Path\nimport pydicom\nimport cv2\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom tqdm.notebook import tqdm\n\n# pytorch libraries for deep learning modelling\nimport torch\nimport torchvision\nfrom torchvision import transforms\nimport torchmetrics\nimport pytorch_lightning as pl\nfrom pytorch_lightning.callbacks import ModelCheckpoint\nfrom pytorch_lightning.loggers import TensorBoardLogger","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-01T10:20:32.375934Z","iopub.execute_input":"2023-05-01T10:20:32.376990Z","iopub.status.idle":"2023-05-01T10:20:40.018757Z","shell.execute_reply.started":"2023-05-01T10:20:32.376915Z","shell.execute_reply":"2023-05-01T10:20:40.017630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# reading labels data\nlabels = pd.read_csv(\"/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_train_labels.csv\")\nlabels.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:20:40.024418Z","iopub.execute_input":"2023-05-01T10:20:40.026790Z","iopub.status.idle":"2023-05-01T10:20:40.112056Z","shell.execute_reply.started":"2023-05-01T10:20:40.026745Z","shell.execute_reply":"2023-05-01T10:20:40.111146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# defining the root path to importing images and files and save path to save the models and images\nROOT_PATH = Path(\"/kaggle/input/rsna-pneumonia-detection-challenge/stage_2_train_images/\")\nSAVE_PATH = Path(\"/kaggle/working/\")","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:20:40.115070Z","iopub.execute_input":"2023-05-01T10:20:40.115372Z","iopub.status.idle":"2023-05-01T10:20:40.122381Z","shell.execute_reply.started":"2023-05-01T10:20:40.115344Z","shell.execute_reply":"2023-05-01T10:20:40.121428Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Now, we are going to generate a 3x3 grid of subplots, where each subplot displays a chest X-ray image from the training set along with its associated label. Where label 0 indicating no Pneumonia and 1 indicating there is some evidence of Pneuomia.","metadata":{}},{"cell_type":"code","source":"fig, axis = plt.subplots(3, 3, figsize=(9, 9))\nc = 0\nfor i in range(3):\n    for j in range(3):\n        patient_id = labels.patientId.iloc[c]\n        dcm_path = ROOT_PATH/patient_id\n        dcm_path = dcm_path.with_suffix(\".dcm\")\n        dcm = pydicom.read_file(dcm_path).pixel_array\n        \n        label = labels['Target'].iloc[c]\n        \n        axis[i][j].imshow(dcm, cmap=\"bone\")\n        axis[i][j].set_title(label)\n        c += 1","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:20:40.127368Z","iopub.execute_input":"2023-05-01T10:20:40.127639Z","iopub.status.idle":"2023-05-01T10:20:42.090655Z","shell.execute_reply.started":"2023-05-01T10:20:40.127613Z","shell.execute_reply":"2023-05-01T10:20:42.089634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Reading DICOM files and saved as .npy files\n\nFollowing code reads in DICOM files for each patient in a given dataset, resizes them to 224x224, saves the pixel arrays as .npy files to be used for training or validation, and calculates the mean and variance of pixel values for the training set.\n\n> The for loop iterates over the patient IDs in the \"labels\" DataFrame. For each patient, it reads in the DICOM file and converts the pixel array to a float between 0 and 1. It then resizes the pixel array to 224x224 using OpenCV's resize function, and saves the resized pixel array as a .npy file in a directory that corresponds to the patient's label (\"0\" or \"1\") and whether it's part of the training or validation set.\n\n> If the patient is part of the training set (determined by the value of the counter variable \"c\"), it also calculates the sum of pixel values and the sum of squared pixel values to be used later for normalization. The normalizer is set to the total number of pixels in the image (224 * 224).","metadata":{}},{"cell_type":"code","source":"sums, sums_squared = 0, 0\n\nfor c, patient_id in enumerate(tqdm(labels.patientId)):\n        patient_id = labels.patientId.iloc[c]\n        dcm_path = ROOT_PATH/patient_id\n        dcm_path = dcm_path.with_suffix(\".dcm\")\n        dcm = pydicom.read_file(dcm_path).pixel_array / 255\n        \n        dcm_array = cv2.resize(dcm, (224, 224)).astype(np.float16)\n        \n        label = labels.Target.iloc[c]\n        \n        train_or_val = 'train' if c < 24000 else 'val'\n        \n        current_save_path = SAVE_PATH/train_or_val/str(label)\n        current_save_path.mkdir(parents=True, exist_ok=True)\n        np.save(current_save_path/patient_id, dcm_array)\n        \n        normalizer = 224 * 224\n        if train_or_val == \"train\":\n            sums += np.sum(dcm_array) / normalizer\n            sums_squared += (dcm_array ** 2).sum() / normalizer\n\nmean = sums / 24000\nstd = np.sqrt((sums_squared / 24000) - mean ** 2)\nmean, std","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:20:42.091642Z","iopub.execute_input":"2023-05-01T10:20:42.091959Z","iopub.status.idle":"2023-05-01T10:29:39.093937Z","shell.execute_reply.started":"2023-05-01T10:20:42.091918Z","shell.execute_reply":"2023-05-01T10:29:39.092786Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# to load .npy file \ndef load_file(path):\n    return np.load(path).astype(np.float32)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:29:39.095365Z","iopub.execute_input":"2023-05-01T10:29:39.097383Z","iopub.status.idle":"2023-05-01T10:29:39.102564Z","shell.execute_reply.started":"2023-05-01T10:29:39.097342Z","shell.execute_reply":"2023-05-01T10:29:39.101488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Defining Train and Validation Transforms\n\nThe follwing code defines two different sets of transformations to be applied to the images in the training and validation sets of a deep learning model.\n\n> The purpose of these transformations is to increase the model's ability to generalize to new images and improve its overall performance.\n\n> The train_transforms include various data augmentation techniques such as random affine transformations and random cropping to increase the variability of the training data and prevent overfitting.\n\n> The val_transforms only includes normalization, which is necessary to ensure that the pixel values of the validation data are consistent with those of the training data. The same normalization parameters used for the training set are used for the validation set to ensure consistency.","metadata":{}},{"cell_type":"code","source":"train_transforms = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(0.49, 0.248),\n    transforms.RandomAffine(degrees=(-5, 5), translate=(0, 0.5), scale=(0.9, 1.1)),\n    transforms.RandomResizedCrop((224, 224), scale=(0.35, 1))\n])\n\nval_transforms = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(0.49, 0.248)\n])","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:29:39.105790Z","iopub.execute_input":"2023-05-01T10:29:39.106084Z","iopub.status.idle":"2023-05-01T10:29:39.113994Z","shell.execute_reply.started":"2023-05-01T10:29:39.106057Z","shell.execute_reply":"2023-05-01T10:29:39.112931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Defining training and validation dataset\n\nI write the following code to create PyTorch datasets for training and validation using the DatasetFolder class from the torchvision.datasets module. Specifically, I define the directories where the preprocessed numpy arrays are saved for the training and validation sets, along with the loader to read the numpy files (load_file function), the file extension (.npy), and the data transforms (train_transforms for training and val_transforms for validation). This allows me to load and transform the data on the fly during training and validation using PyTorch dataloaders.","metadata":{}},{"cell_type":"code","source":"train_dataset = torchvision.datasets.DatasetFolder(\"/kaggle/working/train/\", loader=load_file, extensions=\"npy\", transform=train_transforms)\nval_dataset = torchvision.datasets.DatasetFolder(\"/kaggle/working/val/\", loader=load_file, extensions=\"npy\", transform=val_transforms)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:29:39.115609Z","iopub.execute_input":"2023-05-01T10:29:39.115981Z","iopub.status.idle":"2023-05-01T10:29:39.218738Z","shell.execute_reply.started":"2023-05-01T10:29:39.115943Z","shell.execute_reply":"2023-05-01T10:29:39.217848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Let's visualize 4 images from train dataset that are transformed \n\nfig, axis = plt.subplots(2, 2, figsize=(9, 9))\n\nfor i in range(2):\n    for j in range(2):\n        random_index = np.random.randint(0, len(train_dataset))\n        x_ray, label = train_dataset[random_index]\n        axis[i][j].imshow(x_ray[0], cmap='bone')\n        axis[i][j].set_title(label)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:30:38.897172Z","iopub.execute_input":"2023-05-01T10:30:38.898190Z","iopub.status.idle":"2023-05-01T10:30:39.620660Z","shell.execute_reply.started":"2023-05-01T10:30:38.898150Z","shell.execute_reply":"2023-05-01T10:30:39.619781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Defining hyperparams and creating dataloader\n\nI created two data loaders (train_loader and val_loader) using PyTorch's DataLoader class to load the training and validation datasets respectively. The train_loader loads the data in batches of size 64 and shuffles the order of the samples in each epoch. The val_loader loads the validation data without shuffling. I used num_workers of 4 to parallelize the data loading process for faster performance.","metadata":{}},{"cell_type":"code","source":"batch_size = 64\nnum_workers = 2\n\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, num_workers=num_workers, shuffle=True)\nval_loader = torch.utils.data.DataLoader(val_dataset, shuffle=False)\n","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:31:06.548141Z","iopub.execute_input":"2023-05-01T10:31:06.549144Z","iopub.status.idle":"2023-05-01T10:31:06.554287Z","shell.execute_reply.started":"2023-05-01T10:31:06.549080Z","shell.execute_reply":"2023-05-01T10:31:06.552881Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's see the unique labels and their corresponding frequency count in the train_dataset. If the dataset is balanced, we would expect to see a roughly equal count of each label. However, if the dataset is imbalanced, it means that some labels occur much more frequently than others. \n\n> In this case, the output of the code shows that there is a class imbalance in the train_dataset, meaning that the frequency of the labels is not equally distributed. The output provides information about the count of each unique label in the train_dataset. \n\n> If there is a large difference in the count of each label, it suggests that the dataset is imbalanced, which could lead to poor model performance in accurately predicting the underrepresented class.","metadata":{}},{"cell_type":"code","source":"np.unique(train_dataset.targets, return_counts=True)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:31:09.145165Z","iopub.execute_input":"2023-05-01T10:31:09.145521Z","iopub.status.idle":"2023-05-01T10:31:09.155016Z","shell.execute_reply.started":"2023-05-01T10:31:09.145490Z","shell.execute_reply":"2023-05-01T10:31:09.153903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Architecture\n\nThe following code defines a PyTorch Lightning module called `PneumoniaModel` for a binary classification task of detecting pneumonia from chest X-rays. The model architecture used is `ResNet18`, which is a popular convolutional neural network architecture. The model is modified by changing the number of input channels to 1 (since the input images are grayscale) and by changing the output layer to a single neuron for binary classification. The `BCEWithLogitsLoss` loss function is used, which combines binary cross entropy with logistic sigmoid function. The Adam optimizer is used with a learning rate of `1e-4`. The `train_acc` and `val_acc` metrics are initialized for computing the accuracy of the model during training and validation.\n\n> The `forward` method defines the forward pass of the model, where the input data is passed through the `ResNet18` model and the predicted output is returned.\n\n> The `training_step` method defines the training step for the model, where an input batch of X-ray images and their corresponding labels are passed to the model. The predicted output is computed using the model and the loss is computed using the BCEWithLogitsLoss loss function. The training accuracy and loss are logged using the train_acc and log methods, respectively. The method returns the loss.\n\n> The `training_epoch_end` method logs the overall training accuracy of the model for the entire epoch.\n\n> The `validation_step` method defines the validation step for the model, where an input batch of X-ray images and their corresponding labels are passed to the model. The predicted output is computed using the model and the loss is computed using the BCEWithLogitsLoss loss function. The validation accuracy and loss are logged using the val_acc and log methods, respectively.\n\n> The `validation_epoch_end` method logs the overall validation accuracy of the model for the entire epoch.\n\n> The `configure_optimizers` method returns the optimizer used for training, which is Adam with a learning rate of 1e-4.","metadata":{}},{"cell_type":"code","source":"class PneumoniaModel(pl.LightningModule):\n    def __init__(self):\n        super(PneumoniaModel, self).__init__()\n        self.model = torchvision.models.resnet18()\n        self.model.conv1 = torch.nn.Conv2d(1, 64, kernel_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)\n        self.model.fc = torch.nn.Linear(in_features=512, out_features=1, bias=True)\n        \n        self.optimizer = torch.optim.Adam(self.model.parameters(), lr=1e-4)\n        self.loss_fn = torch.nn.BCEWithLogitsLoss(pos_weight=torch.tensor([3]))\n        \n        self.train_acc = torchmetrics.Accuracy(task='binary')\n        self.val_acc = torchmetrics.Accuracy(task='binary')\n        \n    def forward(self, data):\n        pred = self.model(data)\n        return pred\n    \n    def training_step(self, batch, batch_idx):\n        x_ray, label = batch\n        label = label.float()\n        pred = self(x_ray)[:,0]\n        loss = self.loss_fn(pred, label)\n        \n        self.log(\"Train loss\", loss)\n        self.log(\"Step Train ACC\", self.train_acc(torch.sigmoid(pred), label.int()))\n        \n        return loss\n    \n    def training_epoch_end(self, outs):\n        self.log(\"Train ACC\", self.train_acc.compute())\n        \n    def validation_step(self, batch, batch_idx):\n        x_ray, label = batch\n        label = label.float()\n        pred = self(x_ray)[:,0]\n        loss = self.loss_fn(pred, label)\n\n        self.log(\"Val loss\", loss)\n        self.log(\"Step Val ACC\", self.val_acc(torch.sigmoid(pred), label.int()))\n\n\n    def validation_epoch_end(self, outs):\n        self.log(\"Val ACC\", self.val_acc.compute())\n                 \n    def configure_optimizers(self):\n        return [self.optimizer]\n               \n","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:31:11.345382Z","iopub.execute_input":"2023-05-01T10:31:11.345991Z","iopub.status.idle":"2023-05-01T10:31:11.358666Z","shell.execute_reply.started":"2023-05-01T10:31:11.345949Z","shell.execute_reply":"2023-05-01T10:31:11.357517Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = PneumoniaModel()","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:31:13.235107Z","iopub.execute_input":"2023-05-01T10:31:13.235704Z","iopub.status.idle":"2023-05-01T10:31:13.431486Z","shell.execute_reply.started":"2023-05-01T10:31:13.235669Z","shell.execute_reply":"2023-05-01T10:31:13.430454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"A callback function called `ModelCheckpoint`, which is used to save the best performing model during training. The `monitor` parameter specifies the metric to monitor, which in this case is the validation accuracy (`Val ACC`). The `save_top_k` parameter specifies how many of the best models to save, with `10` indicating that the top 10 models will be saved. The `mode` parameter specifies whether to save the models with the highest or lowest value of the monitored metric, with `max` indicating that the models with the highest validation accuracy will be saved.","metadata":{}},{"cell_type":"code","source":"checkpoint_callback = ModelCheckpoint(\n    monitor = 'Val ACC',\n    save_top_k = 10,\n    mode = 'max'\n)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:31:16.940510Z","iopub.execute_input":"2023-05-01T10:31:16.941534Z","iopub.status.idle":"2023-05-01T10:31:16.948394Z","shell.execute_reply.started":"2023-05-01T10:31:16.941487Z","shell.execute_reply":"2023-05-01T10:31:16.947376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Let's initialize a PyTorch Lightning trainer object with the following configuration:\n\n- `devices=1`: Specifies that the model should be trained on a single GPU.\n- `logger=TensorBoardLogger(save_dir='./log')`: Specifies that logs should be written to a TensorBoard file in the `./log` directory.\n- `log_every_n_steps=1`: Specifies that logs should be written every training step.\n- `callbacks=checkpoint_callback`: Specifies that the `checkpoint_callback` object should be used to save model checkpoints.\n- `max_epochs=10`: Specifies the maximum number of epochs to train the model for. \n\nTogether, these settings indicate that the model will be trained on a single GPU, with logs written to a TensorBoard file and checkpoints saved at regular intervals. The training process will continue for a maximum of 10 epochs.","metadata":{}},{"cell_type":"markdown","source":"increase the epochs to get your desired accuracy","metadata":{}},{"cell_type":"code","source":"devices = 1\ntrainer = pl.Trainer(accelerator='gpu', devices=devices, logger=TensorBoardLogger(save_dir='./log'),\n                    log_every_n_steps=1,\n                    callbacks=checkpoint_callback, max_epochs=10)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:32:48.869408Z","iopub.execute_input":"2023-05-01T10:32:48.870167Z","iopub.status.idle":"2023-05-01T10:32:48.880000Z","shell.execute_reply.started":"2023-05-01T10:32:48.870117Z","shell.execute_reply":"2023-05-01T10:32:48.878995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainer.fit(model, train_loader, val_loader)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:33:16.400905Z","iopub.execute_input":"2023-05-01T10:33:16.401297Z","iopub.status.idle":"2023-05-01T10:55:47.173314Z","shell.execute_reply.started":"2023-05-01T10:33:16.401260Z","shell.execute_reply":"2023-05-01T10:55:47.172172Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\ndevice","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:55:47.177085Z","iopub.execute_input":"2023-05-01T10:55:47.177760Z","iopub.status.idle":"2023-05-01T10:55:47.188861Z","shell.execute_reply.started":"2023-05-01T10:55:47.177684Z","shell.execute_reply":"2023-05-01T10:55:47.187847Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"model.eval() will turned off the weight adjusting when we will inference","metadata":{}},{"cell_type":"code","source":"model.eval()\nmodel.to(device)","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:55:47.190955Z","iopub.execute_input":"2023-05-01T10:55:47.191375Z","iopub.status.idle":"2023-05-01T10:55:47.236207Z","shell.execute_reply.started":"2023-05-01T10:55:47.191337Z","shell.execute_reply":"2023-05-01T10:55:47.235167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Creating empty lists for predictions and labels. Then, it is iterating over the validation dataset and for each data and label, it is sending the data to the device (e.g. GPU), converting to float, and adding an extra dimension with `unsqueeze(0)`. Then, it is passing the data through the model and applying sigmoid activation to the output. The prediction is added to the `preds` list and the label to the `labels` list.\n\nFinally, the code is converting the `preds` and `labels` lists into PyTorch tensors.","metadata":{}},{"cell_type":"code","source":"preds = []\nlabels = []\n\nwith torch.no_grad():\n    for data, label in tqdm(val_dataset):\n        data = data.to(device).float().unsqueeze(0)\n        pred = torch.sigmoid(model(data)[0].cpu())\n        preds.append(pred)\n        labels.append(label)\n        \npreds = torch.tensor(preds)\nlabels = torch.tensor(labels).int()","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:55:47.238557Z","iopub.execute_input":"2023-05-01T10:55:47.239901Z","iopub.status.idle":"2023-05-01T10:56:12.563205Z","shell.execute_reply.started":"2023-05-01T10:55:47.239871Z","shell.execute_reply":"2023-05-01T10:56:12.562167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n1. `torchmetrics.Accuracy(task='binary')` initializes an instance of the `Accuracy` class from the `torchmetrics` library, which is used for computing the accuracy score of binary classification problems. The `(preds, labels)` argument passed to this instance is used to compute the accuracy score.\n\n2. `torchmetrics.Precision(task='binary')` initializes an instance of the `Precision` class from the `torchmetrics` library, which is used for computing the precision score of binary classification problems. The `(preds, labels)` argument passed to this instance is used to compute the precision score.\n\n3. `torchmetrics.Recall(task='binary')` initializes an instance of the `Recall` class from the `torchmetrics` library, which is used for computing the recall score of binary classification problems. The `(preds, labels)` argument passed to this instance is used to compute the recall score.\n\n4. `torchmetrics.ConfusionMatrix(task='binary', num_classes=2)` initializes an instance of the `ConfusionMatrix` class from the `torchmetrics` library, which is used for computing the confusion matrix of binary classification problems. The `(preds, labels)` argument passed to this instance is used to compute the confusion matrix.\n","metadata":{}},{"cell_type":"code","source":"acc = torchmetrics.Accuracy(task='binary')(preds, labels)\nprecision = torchmetrics.Precision(task='binary')(preds, labels)\nrecall = torchmetrics.Recall(task='binary')(preds, labels)\ncm = torchmetrics.ConfusionMatrix(task='binary', num_classes=2)(preds, labels)\n\nprint(f\"Val Accuracy {acc}\")\nprint(f\"Val Precision {precision}\")\nprint(f\"Val Recall {recall}\")\nprint(f\"Confusion Matrix {cm}\")","metadata":{"execution":{"iopub.status.busy":"2023-05-01T10:56:12.567546Z","iopub.execute_input":"2023-05-01T10:56:12.569908Z","iopub.status.idle":"2023-05-01T10:56:12.611181Z","shell.execute_reply.started":"2023-05-01T10:56:12.569867Z","shell.execute_reply":"2023-05-01T10:56:12.610167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}