{"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":20270,"databundleVersionId":1222630,"sourceType":"competition"},{"sourceId":1243687,"sourceType":"datasetVersion","datasetId":690737}],"dockerImageVersionId":30665,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Kaggle notebook:https://www.kaggle.com/hemalathaaae/resnet50-skin-melanoma","metadata":{"execution":{"iopub.status.busy":"2024-03-02T17:54:52.002373Z","iopub.execute_input":"2024-03-02T17:54:52.003213Z","iopub.status.idle":"2024-03-02T17:54:59.992024Z","shell.execute_reply.started":"2024-03-02T17:54:52.003181Z","shell.execute_reply":"2024-03-02T17:54:59.991004Z"}}},{"cell_type":"markdown","source":"Wandb Link: https://wandb.ai/hemalathaa/Skin%20Melanoma%20Project%20?nw=nwuserhemalathaaelumalai","metadata":{}},{"cell_type":"markdown","source":"# Importing Necessary Libraries","metadata":{}},{"cell_type":"code","source":"import torch\nimport torchvision\nimport torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torch.utils.data import DataLoader, TensorDataset\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.utils import resample\nimport numpy as np\nimport cv2\nimport pandas as pd\nimport time\nimport wandb","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:16:51.532648Z","iopub.execute_input":"2024-03-03T06:16:51.533025Z","iopub.status.idle":"2024-03-03T06:17:00.225541Z","shell.execute_reply.started":"2024-03-03T06:16:51.532996Z","shell.execute_reply":"2024-03-03T06:17:00.224593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading Image Dataset","metadata":{}},{"cell_type":"code","source":"image_path = '/kaggle/input/melanoma-merged-external-data-512x512-jpeg/512x512-dataset-melanoma/512x512-dataset-melanoma/'\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:20.208333Z","iopub.execute_input":"2024-03-03T06:17:20.208694Z","iopub.status.idle":"2024-03-03T06:17:20.213108Z","shell.execute_reply.started":"2024-03-03T06:17:20.208665Z","shell.execute_reply":"2024-03-03T06:17:20.21217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''# Define the function to load and preprocess images\ndef load_and_preprocess_images(image_paths):\n    images = []\n    for path in image_paths:\n        # Load image using OpenCV\n        img = cv2.imread(image_path + path + '.jpg')\n        # Convert image to grayscale\n        #img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n        images.append(img)\n    return np.array(images)'''","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:29.557621Z","iopub.execute_input":"2024-03-03T06:17:29.558018Z","iopub.status.idle":"2024-03-03T06:17:29.566752Z","shell.execute_reply.started":"2024-03-03T06:17:29.557988Z","shell.execute_reply":"2024-03-03T06:17:29.56555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the function to load and preprocess images\ndef load_and_preprocess_images(image_paths):\n    images = []\n    for path in image_paths:\n        # Load image using OpenCV\n        img = cv2.imread(image_path + path + '.jpg')\n        # Resize image to (512, 512)\n        img = cv2.resize(img, (512, 512))\n        # Convert image to RGB\n        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)\n        images.append(img)\n    return np.array(images)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:34.14902Z","iopub.execute_input":"2024-03-03T06:17:34.149787Z","iopub.status.idle":"2024-03-03T06:17:34.155226Z","shell.execute_reply.started":"2024-03-03T06:17:34.149756Z","shell.execute_reply":"2024-03-03T06:17:34.154181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(\"/kaggle/input/siim-isic-melanoma-classification/train.csv\")\ntrain_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:37.313235Z","iopub.execute_input":"2024-03-03T06:17:37.314012Z","iopub.status.idle":"2024-03-03T06:17:37.416288Z","shell.execute_reply.started":"2024-03-03T06:17:37.313984Z","shell.execute_reply":"2024-03-03T06:17:37.415307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_distribution = train_df['target'].value_counts()\nclass_distribution","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:42.002327Z","iopub.execute_input":"2024-03-03T06:17:42.00311Z","iopub.status.idle":"2024-03-03T06:17:42.016366Z","shell.execute_reply.started":"2024-03-03T06:17:42.00308Z","shell.execute_reply":"2024-03-03T06:17:42.015394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = train_df['image_name'] #images\ny = train_df['target'] #target\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:45.196399Z","iopub.execute_input":"2024-03-03T06:17:45.197316Z","iopub.status.idle":"2024-03-03T06:17:45.201532Z","shell.execute_reply.started":"2024-03-03T06:17:45.197282Z","shell.execute_reply":"2024-03-03T06:17:45.200485Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Assuming X and y are your original data and labels\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:46.932532Z","iopub.execute_input":"2024-03-03T06:17:46.932911Z","iopub.status.idle":"2024-03-03T06:17:46.946277Z","shell.execute_reply.started":"2024-03-03T06:17:46.932883Z","shell.execute_reply":"2024-03-03T06:17:46.945346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Separate majority and minority classes in training data\nmajority_class = X_train[y_train == 0]\nminority_class = X_train[y_train == 1]\n\nprint(\"Length of Majority \",len(majority_class),\"Minority\",len(minority_class))\n\nundersampled_majority_class = resample(majority_class,\n                                        replace=False,\n                                        n_samples=len(minority_class),\n                                        random_state=42)\n\t\t\t\t\t\t\t\t\t\t\nprint(\"Length of undersampled_majority \",len(undersampled_majority_class))\n\n# Load and preprocess images for majority class\nundersampled_majority_images = load_and_preprocess_images(undersampled_majority_class)\n# Convert labels to float\nundersampled_majority_labels = np.zeros(len(undersampled_majority_images))\n\n# Load and preprocess images for minority class\nminority_images = load_and_preprocess_images(minority_class)\n# Convert labels to float\nminority_labels = np.ones(len(minority_images))\n\n# Combine minority class with undersampled majority class\nundersampled_X_train = np.concatenate([undersampled_majority_images, minority_images])\nundersampled_y_train = np.concatenate([undersampled_majority_labels, minority_labels])\n\nundersampled_X_train_tensor = torch.tensor(undersampled_X_train, dtype=torch.float32)\nundersampled_y_train_tensor = torch.tensor(undersampled_y_train, dtype=torch.float32)\n\n# Shuffle the data\nshuffled_indices = np.random.permutation(len(undersampled_y_train))\nundersampled_X_train = undersampled_X_train_tensor[shuffled_indices]\nundersampled_y_train = undersampled_y_train_tensor[shuffled_indices]","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:17:50.982839Z","iopub.execute_input":"2024-03-03T06:17:50.983663Z","iopub.status.idle":"2024-03-03T06:18:06.286594Z","shell.execute_reply.started":"2024-03-03T06:17:50.983631Z","shell.execute_reply":"2024-03-03T06:18:06.285749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define transformations\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))\n])\n\n# Create a custom dataset\nundersampled_dataset = TensorDataset(undersampled_X_train_tensor, undersampled_y_train_tensor.long())\n\n\n# Define data loader\nbatch_size = 32\nundersampled_dataset.transform =  transform\nundersampled_dataloader = DataLoader(undersampled_dataset, batch_size=batch_size, shuffle=True)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:18:06.288501Z","iopub.execute_input":"2024-03-03T06:18:06.288868Z","iopub.status.idle":"2024-03-03T06:18:06.298469Z","shell.execute_reply.started":"2024-03-03T06:18:06.288837Z","shell.execute_reply":"2024-03-03T06:18:06.297525Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Assuming X_test contains the image pixel data\nX_test_processed = load_and_preprocess_images(X_test)\ny_test_numpy = y_test.astype(np.float32).to_numpy()\n\n# Define the validation dataset\nvalidation_dataset = TensorDataset(torch.tensor(X_test_processed), torch.tensor(y_test_numpy))\n\n# Define the batch size\nbatch_size = 32\n\n# Define the validation dataloader\nvalidation_dataloader = DataLoader(validation_dataset, batch_size=batch_size, shuffle=False)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:18:06.299541Z","iopub.execute_input":"2024-03-03T06:18:06.300233Z","iopub.status.idle":"2024-03-03T06:19:37.593394Z","shell.execute_reply.started":"2024-03-03T06:18:06.300202Z","shell.execute_reply":"2024-03-03T06:19:37.592328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:19:37.595434Z","iopub.execute_input":"2024-03-03T06:19:37.595786Z","iopub.status.idle":"2024-03-03T06:19:37.622496Z","shell.execute_reply.started":"2024-03-03T06:19:37.595755Z","shell.execute_reply":"2024-03-03T06:19:37.621609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import wandb\nwandb.init(project='Skin Melanoma Project ', save_code=True,name=\"VGG19_ADAM\")","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:21:47.923471Z","iopub.execute_input":"2024-03-03T06:21:47.92388Z","iopub.status.idle":"2024-03-03T06:22:22.661513Z","shell.execute_reply.started":"2024-03-03T06:21:47.923848Z","shell.execute_reply":"2024-03-03T06:22:22.660417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport torchvision.models as models\n\n# Load pre-trained VGG19 model\nmodel = torchvision.models.vgg19(pretrained=True)\n\n# Freeze the pre-trained layers\nfor param in model.parameters():\n    param.requires_grad = False\n\n# Modify the last fully connected layer\nnum_features = model.classifier[6].in_features\nmodel.classifier[6] = nn.Linear(num_features, 2)  # Assuming 2 classes for classification\n\n# Move the model to the appropriate device\nmodel.to(device)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:22:22.663305Z","iopub.execute_input":"2024-03-03T06:22:22.663631Z","iopub.status.idle":"2024-03-03T06:22:30.383207Z","shell.execute_reply.started":"2024-03-03T06:22:22.663602Z","shell.execute_reply":"2024-03-03T06:22:30.382163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#criterion = nn.CrossEntropyLoss()\n#optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\nimport torch.optim as optim\n\n# Define the criterion (loss function)\ncriterion = nn.BCEWithLogitsLoss()\n\n# Define the optimizer\noptimizer = optim.Adam(model.parameters(), lr=0.0001)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:22:37.417964Z","iopub.execute_input":"2024-03-03T06:22:37.418325Z","iopub.status.idle":"2024-03-03T06:22:37.423478Z","shell.execute_reply.started":"2024-03-03T06:22:37.418299Z","shell.execute_reply":"2024-03-03T06:22:37.422574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\nnum_epochs = 10\nfor epoch in range(num_epochs):\n    model.train()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n    start_time = time.time()\n    \n    for inputs, labels in undersampled_dataloader:\n        optimizer.zero_grad()                \n        inputs = inputs.permute(0, 3, 1, 2)  # Rearrange dimensions\n        inputs, labels = inputs.to(device), labels.to(device)\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()    \n        \n        # Calculate accuracy\n        _, predicted = torch.max(outputs, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n    \n    end_time = time.time()\n    epoch_time = end_time - start_time\n    \n    epoch_loss = running_loss / len(undersampled_dataloader)\n    epoch_accuracy = 100 * correct / total\n    \n    # Log training loss and accuracy to Wandb\n    wandb.log({\"loss\": epoch_loss, \"accuracy\": epoch_accuracy, \"epoch\": epoch+1})\n    \n    print(f\"Epoch {epoch+1}, Train Loss: {epoch_loss}, Train Accuracy: {epoch_accuracy}%, Time: {epoch_time} seconds\")\n    \n    # Validation loop\n    model.eval()\n    val_running_loss = 0.0\n    val_correct = 0\n    val_total = 0\n\n    with torch.no_grad():\n        for val_inputs, val_labels in validation_dataloader:\n            # Ensure correct data type and device for input data\n            val_inputs = val_inputs.to(device, dtype=torch.float32)\n            val_labels = val_labels.to(device, dtype=torch.long)\n\n            # Rearrange dimensions if necessary\n            val_inputs = val_inputs.permute(0, 3, 1, 2)\n\n            # Forward pass\n            val_outputs = model(val_inputs)\n\n            # Calculate loss\n            val_loss = criterion(val_outputs, val_labels)\n            val_running_loss += val_loss.item()\n\n            # Calculate accuracy\n            _, val_predicted = torch.max(val_outputs, 1)\n            val_total += val_labels.size(0)\n            val_correct += (val_predicted == val_labels).sum().item()\n\n    # Calculate validation loss and accuracy\n    val_epoch_loss = val_running_loss / len(validation_dataloader)\n    val_epoch_accuracy = 100 * val_correct / val_total\n\n    # Log validation loss and accuracy to Wandb\n    wandb.log({\"val_loss\": val_epoch_loss, \"val_accuracy\": val_epoch_accuracy, \"epoch\": epoch+1})\n\n    print(f\"Epoch {epoch+1}, Val Loss: {val_epoch_loss}, Val Accuracy: {val_epoch_accuracy}%\")\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:22:39.863571Z","iopub.execute_input":"2024-03-03T06:22:39.86402Z","iopub.status.idle":"2024-03-03T06:47:29.026515Z","shell.execute_reply.started":"2024-03-03T06:22:39.863986Z","shell.execute_reply":"2024-03-03T06:47:29.025506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import precision_score, recall_score, f1_score\n\n# Move model to the same device as the input data\nmodel.to(device)\n\n# Validation loop\nmodel.eval()\nval_running_loss = 0.0\nval_correct = 0\nval_total = 0\nval_preds = []\nval_labels = []\n\nwith torch.no_grad():\n    for val_inputs, val_labels_batch in validation_dataloader:\n        # Ensure correct data type and device for input data\n        val_inputs = val_inputs.to(device, dtype=torch.float32)\n        val_labels_batch = val_labels_batch.to(device, dtype=torch.long)\n\n        # Rearrange dimensions if necessary\n        val_inputs = val_inputs.permute(0, 3, 1, 2)\n\n        # Forward pass\n        val_outputs = model(val_inputs)\n\n        # Calculate loss\n        val_loss = criterion(val_outputs, val_labels_batch)\n        val_running_loss += val_loss.item()\n\n        # Append predictions and true labels\n        val_preds.extend(torch.argmax(val_outputs, axis=1).cpu().numpy())\n        val_labels.extend(val_labels_batch.cpu().numpy())\n\n        # Calculate accuracy\n        val_total += val_labels_batch.size(0)\n        val_correct += (torch.argmax(val_outputs, axis=1) == val_labels_batch).sum().item()\n\n# Calculate validation loss\nval_epoch_loss = val_running_loss / len(validation_dataloader)\n\n# Calculate validation accuracy\nval_epoch_accuracy = 100 * val_correct / val_total\n\n# Calculate precision, recall, and F1 score\nprecision = precision_score(val_labels, val_preds, average='weighted')\nrecall = recall_score(val_labels, val_preds, average='weighted')\nf1 = f1_score(val_labels, val_preds, average='weighted')\n\n# Log validation loss, accuracy, precision, recall, and F1 score to Wandb\nwandb.log({\"val_loss\": val_epoch_loss, \"val_accuracy\": val_epoch_accuracy, \"precision\": precision, \"recall\": recall, \"f1_score\": f1, \"epoch\": epoch+1})\n\nprint(f\"Epoch {epoch+1}, Val Loss: {val_epoch_loss}, Val Accuracy: {val_epoch_accuracy}%, Precision: {precision}, Recall: {recall}, F1 Score: {f1}\")\n\nprint(\"Precision:\", precision)\nprint(\"Recall:\", recall)\nprint(\"F1 Score:\", f1)\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:49:51.923297Z","iopub.execute_input":"2024-03-03T06:49:51.923964Z","iopub.status.idle":"2024-03-03T06:52:02.515165Z","shell.execute_reply.started":"2024-03-03T06:49:51.923933Z","shell.execute_reply":"2024-03-03T06:52:02.513907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import confusion_matrix\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\n# Calculate confusion matrix\nconf_matrix = confusion_matrix(val_labels, val_preds)\n\n# Log confusion matrix to Wandb\nwandb.log({\"confusion_matrix\": wandb.plot.confusion_matrix(probs=None,\n                                                           y_true=val_labels,\n                                                           preds=val_preds,\n                                                           class_names=[0, 1],\n                                                           title=\"Confusion Matrix\")})\n\n# Plot confusion matrix\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt=\"d\", cmap=\"Blues\")\nplt.xlabel(\"Predicted labels\")\nplt.ylabel(\"True labels\")\nplt.title(\"Confusion Matrix\")\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2024-03-03T06:52:27.0397Z","iopub.execute_input":"2024-03-03T06:52:27.040106Z","iopub.status.idle":"2024-03-03T06:52:27.646662Z","shell.execute_reply.started":"2024-03-03T06:52:27.040077Z","shell.execute_reply":"2024-03-03T06:52:27.645588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load and preprocess test images\ntest_image_paths = ['/kaggle/input/melanoma-resized-images-512512/test/test/' + img_name + '.jpg' for img_name in test_df['image_name']]\ntest_images = load_and_preprocess_images(test_image_paths)\n\n# Convert test images to tensor\ntest_images_tensor = torch.tensor(test_images, dtype=torch.float32)\n# Create test dataset\ntest_dataset = TensorDataset(test_images_tensor)\n\n# Define test data loader\ntest_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n# Define test data loader\ntest_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)\n\ndef test_model(test_loader, model, device, test_df):\n    model.eval()\n    predictions = []\n    image_names = []\n\n    test_start_time = time.time()\n    with torch.no_grad():\n        for i, data in enumerate(test_loader):\n            data = data.to(device)\n            outputs = model(data)\n\n            probabilities = (torch.sigmoid(outputs) >= 0.5).cpu().numpy()\n            predictions.extend(probabilities.flatten())\n\n            image_names.extend(test_df['image_name'][i * test_loader.batch_size:(i + 1) * test_loader.batch_size])\n\n    test_end_time = time.time()\n    test_time = test_end_time - test_start_time\n\n    submission_df = pd.DataFrame({'image_name': image_names, 'target': predictions})\n    submission_df.to_csv('submission.csv', index=False)\n\n    print(f'Test Evaluation and Submission CSV is generated in: {test_time} seconds')","metadata":{},"execution_count":null,"outputs":[]}]}