{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.11","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":104884,"sourceType":"datasetVersion","datasetId":54339}],"dockerImageVersionId":31040,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Importing Libraries","metadata":{}},{"cell_type":"code","source":"#1st step - Importing all the required Libraries\nimport pandas as pd\nimport numpy as np\nimport os\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\nimport torch\nimport torchvision\nfrom torchvision import datasets, transforms, models\nfrom torch.utils.data import DataLoader, Dataset\nimport torch.nn as nn\nimport torch.optim as optim\n\nfrom sklearn.metrics import accuracy_score, confusion_matrix, classification_report\nfrom PIL import Image","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:40:32.917057Z","iopub.execute_input":"2025-06-19T16:40:32.917369Z","iopub.status.idle":"2025-06-19T16:40:32.921831Z","shell.execute_reply.started":"2025-06-19T16:40:32.917348Z","shell.execute_reply":"2025-06-19T16:40:32.921035Z"}},"outputs":[],"execution_count":10},{"cell_type":"markdown","source":"# Loading the Dataset","metadata":{}},{"cell_type":"code","source":"#Loading the dataset\ndata = pd.read_csv(\"/kaggle/input/skin-cancer-mnist-ham10000/HAM10000_metadata.csv\")\ndata.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:40:38.950796Z","iopub.execute_input":"2025-06-19T16:40:38.95106Z","iopub.status.idle":"2025-06-19T16:40:38.976913Z","shell.execute_reply.started":"2025-06-19T16:40:38.951043Z","shell.execute_reply":"2025-06-19T16:40:38.976348Z"}},"outputs":[{"execution_count":11,"output_type":"execute_result","data":{"text/plain":"     lesion_id      image_id   dx dx_type   age   sex localization\n0  HAM_0000118  ISIC_0027419  bkl   histo  80.0  male        scalp\n1  HAM_0000118  ISIC_0025030  bkl   histo  80.0  male        scalp\n2  HAM_0002730  ISIC_0026769  bkl   histo  80.0  male        scalp\n3  HAM_0002730  ISIC_0025661  bkl   histo  80.0  male        scalp\n4  HAM_0001466  ISIC_0031633  bkl   histo  75.0  male          ear","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>lesion_id</th>\n      <th>image_id</th>\n      <th>dx</th>\n      <th>dx_type</th>\n      <th>age</th>\n      <th>sex</th>\n      <th>localization</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>HAM_0000118</td>\n      <td>ISIC_0027419</td>\n      <td>bkl</td>\n      <td>histo</td>\n      <td>80.0</td>\n      <td>male</td>\n      <td>scalp</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>HAM_0000118</td>\n      <td>ISIC_0025030</td>\n      <td>bkl</td>\n      <td>histo</td>\n      <td>80.0</td>\n      <td>male</td>\n      <td>scalp</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>HAM_0002730</td>\n      <td>ISIC_0026769</td>\n      <td>bkl</td>\n      <td>histo</td>\n      <td>80.0</td>\n      <td>male</td>\n      <td>scalp</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>HAM_0002730</td>\n      <td>ISIC_0025661</td>\n      <td>bkl</td>\n      <td>histo</td>\n      <td>80.0</td>\n      <td>male</td>\n      <td>scalp</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>HAM_0001466</td>\n      <td>ISIC_0031633</td>\n      <td>bkl</td>\n      <td>histo</td>\n      <td>75.0</td>\n      <td>male</td>\n      <td>ear</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}],"execution_count":11},{"cell_type":"markdown","source":"# Filtering the dataset to only include 3 labels ","metadata":{}},{"cell_type":"code","source":"#filtering the dataset to only include mel,nv,bkl labels\nchosen_classes = ['mel','nv', 'bkl']\ndata = data[data['dx'].isin(chosen_classes)]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:41:53.723271Z","iopub.execute_input":"2025-06-19T16:41:53.723815Z","iopub.status.idle":"2025-06-19T16:41:53.729775Z","shell.execute_reply.started":"2025-06-19T16:41:53.723789Z","shell.execute_reply":"2025-06-19T16:41:53.729125Z"}},"outputs":[],"execution_count":12},{"cell_type":"code","source":"#map the labels to numeric values\nlabel_map = {'mel':0, 'nv':1, 'bkl':2}\ndata['label'] = data['dx'].map(label_map)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:41:57.226793Z","iopub.execute_input":"2025-06-19T16:41:57.227104Z","iopub.status.idle":"2025-06-19T16:41:57.232797Z","shell.execute_reply.started":"2025-06-19T16:41:57.227053Z","shell.execute_reply":"2025-06-19T16:41:57.232138Z"}},"outputs":[],"execution_count":13},{"cell_type":"markdown","source":"# Dividing the Dataset","metadata":{}},{"cell_type":"code","source":"#dividing dataset to training, testing, and validation data\nfrom sklearn.model_selection import train_test_split\ntrain_data, temp_data = train_test_split(data, test_size = 0.3, stratify = data['label'], random_state = 42)\nvalidation_data, test_data = train_test_split(temp_data, test_size = 0.5, stratify = temp_data['label'], random_state = 42 )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:42:00.292846Z","iopub.execute_input":"2025-06-19T16:42:00.293524Z","iopub.status.idle":"2025-06-19T16:42:00.308934Z","shell.execute_reply.started":"2025-06-19T16:42:00.293491Z","shell.execute_reply":"2025-06-19T16:42:00.308052Z"}},"outputs":[],"execution_count":14},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{}},{"cell_type":"code","source":"#adding a file path column\ntrain_data['filename'] = train_data['image_id'] + '.jpg'\ntest_data['filename'] = test_data['image_id'] + '.jpg'\nvalidation_data['filename'] = validation_data['image_id'] + '.jpg'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:42:03.299875Z","iopub.execute_input":"2025-06-19T16:42:03.30019Z","iopub.status.idle":"2025-06-19T16:42:03.307159Z","shell.execute_reply.started":"2025-06-19T16:42:03.300167Z","shell.execute_reply":"2025-06-19T16:42:03.30658Z"}},"outputs":[],"execution_count":15},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\ntrain_mod = ImageDataGenerator(rescale = 1./255, rotation_range = 16, horizontal_flip = True, zoom_range = 0.1)\n    \n\ntest_mod = ImageDataGenerator(rescale = 1./255)\nval_mod = ImageDataGenerator(rescale = 1./255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:42:07.067609Z","iopub.execute_input":"2025-06-19T16:42:07.067867Z","iopub.status.idle":"2025-06-19T16:42:07.072231Z","shell.execute_reply.started":"2025-06-19T16:42:07.067848Z","shell.execute_reply":"2025-06-19T16:42:07.071638Z"}},"outputs":[],"execution_count":16},{"cell_type":"code","source":"import os\nimport shutil\nsource1 = '/kaggle/input/skin-cancer-mnist-ham10000/HAM10000_images_part_1'\nsource2 = '/kaggle/input/skin-cancer-mnist-ham10000/HAM10000_images_part_2'\ndestination = 'HAM10000_images'\n\nos.makedirs(destination, exist_ok = True)\nfor folder in [source1, source2]:\n    for file in os.listdir(folder):\n        if file.endswith('.jpg'):\n            shutil.copy(os.path.join(folder,file), os.path.join(destination,file))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:42:10.54063Z","iopub.execute_input":"2025-06-19T16:42:10.541403Z","iopub.status.idle":"2025-06-19T16:44:24.199552Z","shell.execute_reply.started":"2025-06-19T16:42:10.54136Z","shell.execute_reply":"2025-06-19T16:44:24.198921Z"}},"outputs":[],"execution_count":17},{"cell_type":"code","source":"#creating generators\n\ntrain_gen = train_mod.flow_from_dataframe(dataframe = train_data, \ndirectory = 'HAM10000_images/',\nx_col = 'filename',\ny_col = 'dx',\ntarget_size = (224,224),\nbatch_size = 32,\nclass_mode = 'categorical'\n                                         )\n\nval_gen = val_mod.flow_from_dataframe(dataframe = validation_data, \ndirectory = 'HAM10000_images/',\nx_col = 'filename',\ny_col = 'dx',\ntarget_size = (224,224),\nbatch_size = 32,\nclass_mode = 'categorical'\n                                         )\ntest_gen = test_mod.flow_from_dataframe(dataframe = test_data, \ndirectory = 'HAM10000_images/',\nx_col = 'filename',\ny_col = 'dx',\ntarget_size = (224,224),\nbatch_size = 32,\nclass_mode = 'categorical'\n                                         )\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:44:31.028326Z","iopub.execute_input":"2025-06-19T16:44:31.029001Z","iopub.status.idle":"2025-06-19T16:44:31.10802Z","shell.execute_reply.started":"2025-06-19T16:44:31.028973Z","shell.execute_reply":"2025-06-19T16:44:31.107217Z"}},"outputs":[{"name":"stdout","text":"Found 6241 validated image filenames belonging to 3 classes.\nFound 1338 validated image filenames belonging to 3 classes.\nFound 1338 validated image filenames belonging to 3 classes.\n","output_type":"stream"}],"execution_count":18},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.layers import Dense, GlobalAveragePooling2D, Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom sklearn.metrics import classification_report, confusion_matrix\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:44:37.187199Z","iopub.execute_input":"2025-06-19T16:44:37.187777Z","iopub.status.idle":"2025-06-19T16:44:37.202527Z","shell.execute_reply.started":"2025-06-19T16:44:37.187757Z","shell.execute_reply":"2025-06-19T16:44:37.201883Z"}},"outputs":[],"execution_count":19},{"cell_type":"markdown","source":"# Model Training","metadata":{}},{"cell_type":"code","source":"model_base = ResNet50(weights = 'imagenet', include_top = False, input_shape = (224,224,3))\n#Removing top layers\nmodel_base.Trainable = False\n\n#Adding custom Layers\nnew_layer = model_base.output\nnew_layer = GlobalAveragePooling2D()(new_layer)\nnew_layer = Dropout(0.3)(new_layer)\nfinal_predictions = Dense(3, activation = 'softmax')(new_layer)\n\nfinal_model = Model(inputs = model_base.input, outputs = final_predictions )\n\n#compiling the model\nfinal_model.compile(optimizer = Adam(), loss = 'categorical_crossentropy', metrics = ['accuracy'])\n\n#training the model\nhistory = final_model.fit(train_gen, \n                         validation_data = val_gen,\n                         epochs = 10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T16:44:42.171048Z","iopub.execute_input":"2025-06-19T16:44:42.171596Z","iopub.status.idle":"2025-06-19T17:05:46.531849Z","shell.execute_reply.started":"2025-06-19T16:44:42.171567Z","shell.execute_reply":"2025-06-19T17:05:46.531273Z"}},"outputs":[{"name":"stderr","text":"I0000 00:00:1750351482.757115      35 gpu_device.cc:2022] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 13942 MB memory:  -> device: 0, name: Tesla T4, pci bus id: 0000:00:04.0, compute capability: 7.5\nI0000 00:00:1750351482.757998      35 gpu_device.cc:2022] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 13942 MB memory:  -> device: 1, name: Tesla T4, pci bus id: 0000:00:05.0, compute capability: 7.5\n","output_type":"stream"},{"name":"stdout","text":"Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/resnet/resnet50_weights_tf_dim_ordering_tf_kernels_notop.h5\n\u001b[1m94765736/94765736\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 0us/step\n","output_type":"stream"},{"name":"stderr","text":"/usr/local/lib/python3.11/dist-packages/keras/src/trainers/data_adapters/py_dataset_adapter.py:121: UserWarning: Your `PyDataset` class should call `super().__init__(**kwargs)` in its constructor. `**kwargs` can include `workers`, `use_multiprocessing`, `max_queue_size`. Do not pass these arguments to `fit()`, as they will be ignored.\n  self._warn_if_super_not_called()\n","output_type":"stream"},{"name":"stdout","text":"Epoch 1/10\n","output_type":"stream"},{"name":"stderr","text":"WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1750351539.571600     100 service.cc:148] XLA service 0x78b5c8001c40 initialized for platform CUDA (this does not guarantee that XLA will be used). Devices:\nI0000 00:00:1750351539.573592     100 service.cc:156]   StreamExecutor device (0): Tesla T4, Compute Capability 7.5\nI0000 00:00:1750351539.573616     100 service.cc:156]   StreamExecutor device (1): Tesla T4, Compute Capability 7.5\nI0000 00:00:1750351544.677549     100 cuda_dnn.cc:529] Loaded cuDNN version 90300\nI0000 00:00:1750351568.665769     100 device_compiler.h:188] Compiled cluster using XLA!  This line is logged at most once for the lifetime of the process.\n","output_type":"stream"},{"name":"stdout","text":"\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m226s\u001b[0m 744ms/step - accuracy: 0.7572 - loss: 0.6662 - val_accuracy: 0.7519 - val_loss: 0.8711\nEpoch 2/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m117s\u001b[0m 593ms/step - accuracy: 0.7800 - loss: 0.5348 - val_accuracy: 0.7519 - val_loss: 0.9229\nEpoch 3/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m114s\u001b[0m 583ms/step - accuracy: 0.7811 - loss: 0.5548 - val_accuracy: 0.7519 - val_loss: 125.5597\nEpoch 4/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m116s\u001b[0m 590ms/step - accuracy: 0.7831 - loss: 0.5565 - val_accuracy: 0.7070 - val_loss: 1.0213\nEpoch 5/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m116s\u001b[0m 591ms/step - accuracy: 0.7929 - loss: 0.5083 - val_accuracy: 0.6644 - val_loss: 0.9804\nEpoch 6/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m113s\u001b[0m 575ms/step - accuracy: 0.8053 - loss: 0.5078 - val_accuracy: 0.7175 - val_loss: 0.6906\nEpoch 7/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m114s\u001b[0m 580ms/step - accuracy: 0.7990 - loss: 0.5098 - val_accuracy: 0.5561 - val_loss: 0.9290\nEpoch 8/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m113s\u001b[0m 575ms/step - accuracy: 0.7901 - loss: 0.6143 - val_accuracy: 0.7683 - val_loss: 0.7824\nEpoch 9/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m114s\u001b[0m 581ms/step - accuracy: 0.7770 - loss: 0.5399 - val_accuracy: 0.7945 - val_loss: 0.5201\nEpoch 10/10\n\u001b[1m196/196\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m115s\u001b[0m 586ms/step - accuracy: 0.8027 - loss: 0.4935 - val_accuracy: 0.8027 - val_loss: 0.5020\n","output_type":"stream"}],"execution_count":20},{"cell_type":"markdown","source":"# Model Evaluation","metadata":{}},{"cell_type":"code","source":"loss, accuracy = final_model.evaluate(test_gen)\nprint(\"accuracy is\", accuracy)\n\ntrue_output = test_gen.classes\npredicted_output = final_model.predict(test_gen)\nprediction = np.argmax(predicted_output, axis = 1)\n\nlabels = list(test_gen.class_indices.keys())\nprint(\"Classification Report\")\nprint(classification_report(true_output, prediction, target_names = labels))\n\ncm = confusion_matrix(true_output, prediction)\nplt.figure(figsize=(5,4))\n\nsns.heatmap(cm, annot = True, fmt='d', cmap = 'Blues', xticklabels = labels, yticklabels = labels)\nplt.title('Confusion Matrix')\nplt.xlabel('Predicted')\nplt.ylabel('Actual')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-06-19T17:27:10.694282Z","iopub.execute_input":"2025-06-19T17:27:10.694901Z","iopub.status.idle":"2025-06-19T17:27:36.89391Z","shell.execute_reply.started":"2025-06-19T17:27:10.694878Z","shell.execute_reply":"2025-06-19T17:27:36.893216Z"}},"outputs":[{"name":"stdout","text":"\u001b[1m42/42\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m9s\u001b[0m 200ms/step - accuracy: 0.7965 - loss: 0.4790\naccuracy is 0.8064274787902832\n\u001b[1m42/42\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m16s\u001b[0m 293ms/step\nClassification Report\n              precision    recall  f1-score   support\n\n         bkl       0.15      0.18      0.16       165\n         mel       0.17      0.04      0.07       167\n          nv       0.76      0.83      0.79      1006\n\n    accuracy                           0.65      1338\n   macro avg       0.36      0.35      0.34      1338\nweighted avg       0.61      0.65      0.63      1338\n\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"<Figure size 500x400 with 2 Axes>","image/png":"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\n"},"metadata":{}}],"execution_count":21},{"cell_type":"markdown","source":"# Model Summary and Evaluation ","metadata":{}},{"cell_type":"markdown","source":"**Model Summary**- In this project, I used the pre-trained model ResNet50, as it is a very powerful model for image classification tasks. First, I removed the top layer, and then added new layers - Pooling layer, dropout layer so as to prevent overfitting, and finally the dense layer with softmax as activation function. Softmax is used for multiclass classification. For training the model - categorical cross entropy is used as loss function, and adam optimizer is used. Preprocessing is done by ImageDataGenerator. \n\n**Model Evaluation** - After training the model, we tested the model using the test set. The accuracy is 80.64% and loss is 0.48. The confusion matrix also displays that model is able to predict well. Nevus class showed the highest accuracy, and the model performed fairly for rest of the classes. Hence we can say that transfer learning is a good technique for skin condition classification, and can perform better with fine-tuning and by using more balanced dataset. ","metadata":{}}]}