{"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":"code","source":"import numpy as np\nimport pandas as pd\nimport tensorflow as tf\nfrom sklearn.preprocessing import StandardScaler\nfrom keras.preprocessing.image import ImageDataGenerator\nimport shutil\nfrom keras.utils import to_categorical\nfrom sklearn.compose import make_column_transformer\nfrom sklearn.model_selection import train_test_split\nimport keras,os\nfrom keras.models import Sequential, Model\nfrom keras.layers import Dense, Conv2D, MaxPool2D , Flatten, concatenate\nfrom keras.optimizers import Adam","metadata":{"execution":{"iopub.status.busy":"2021-07-21T12:03:39.984905Z","iopub.execute_input":"2021-07-21T12:03:39.985304Z","iopub.status.idle":"2021-07-21T12:03:46.954387Z","shell.execute_reply.started":"2021-07-21T12:03:39.985207Z","shell.execute_reply":"2021-07-21T12:03:46.953458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = pd.read_csv('../input/siim-isic-melanoma-classification/train.csv').dropna()","metadata":{"execution":{"iopub.status.busy":"2021-07-21T12:04:08.074463Z","iopub.execute_input":"2021-07-21T12:04:08.075104Z","iopub.status.idle":"2021-07-21T12:04:08.199856Z","shell.execute_reply.started":"2021-07-21T12:04:08.075055Z","shell.execute_reply":"2021-07-21T12:04:08.198756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Get count of malignant vs benign \nprint(data.target.value_counts())\nprint()\n#Get unique values of anatom_site_general_challenge\nprint(data.anatom_site_general_challenge.value_counts())\nprint()\n#Get unique values of sex\nprint(data.sex.value_counts())\nprint()\n#Get unique values of diagnosis\nprint(data.diagnosis.value_counts())","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Sort into two directories","metadata":{}},{"cell_type":"code","source":"!mkdir ./ImData\n!mkdir ./ImData/Benign\n!mkdir ./ImData/Malignant","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Benign = \"./ImData/Benign/\"\nMalignant = \"./ImData/Malignant/\"\nimagePath = \"../input/siim-isic-melanoma-classification/jpeg/train/\"\nsortlist = []\ndata.apply(lambda row: sortlist.append([row.image_name, row.target]),axis = 1)\ncount = 0\nfor i in sortlist:\n    imgpath = imagePath + i[0] + \".jpg\"\n    if i[1] == 0:\n        if count < 10000:\n            shutil.copy2(imgpath, Benign + i[0] + \".jpg\")\n            count+=1\n    else:\n        shutil.copy2(imgpath, Malignant + i[0] + \".jpg\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = data.set_index('image_name')\nimage_folder = './ImData'\nimage_generator = ImageDataGenerator(rescale=1./255).flow_from_directory(\n        image_folder, shuffle=False, class_mode='binary', batch_size=10575)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_files = pd.Series(image_generator.filenames)\nimage_files = list(image_files.str.split(\"/\", expand=True)[1].str[:-4])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, labels = next(image_generator)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Only keep the images loaded ","metadata":{}},{"cell_type":"code","source":"\ndata = data.loc[image_files]\ndata.shape","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{}},{"cell_type":"code","source":"data = data.reindex(image_files)\ndataY = pd.DataFrame(data.target)\ndata = data.drop('target',axis=1)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data = pd.concat([data, pd.get_dummies(data.anatom_site_general_challenge)], axis = 1)\ndata = pd.concat([data, pd.get_dummies(data.sex)], axis = 1)\ndata = pd.concat([data, pd.get_dummies(data.diagnosis)], axis = 1)\ndata = data.drop(['patient_id', 'sex', 'anatom_site_general_challenge', 'diagnosis', 'benign_malignant'], axis = 1)\ndata.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ct = make_column_transformer((StandardScaler(), ['age_approx']))\ndata.age_approx = ct.fit_transform(data)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Concatenate dataY and data so that the corresponding label get sorted in order as well when train test split is applied\ndata = pd.concat([data,dataY], axis =1)\ndata.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(data.shape)\nprint(images.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"trainAttr, testAttr, trainImg, testImg = train_test_split(data, images, test_size=0.25, random_state=42)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Y = pd.DataFrame(trainAttr.target)\ntrainAttrX = trainAttr.drop('target', axis =1) \nprint(trainAttrX.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create Model","metadata":{}},{"cell_type":"markdown","source":"### Model of image part of the data","metadata":{}},{"cell_type":"code","source":"modelImg = Sequential()\nmodelImg.add(Conv2D(input_shape=(256,256,3),filters=64,kernel_size=(3,3),padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=64,kernel_size=(3,3),padding=\"same\", activation=\"relu\"))\nmodelImg.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))\nmodelImg.add(Conv2D(filters=128, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=128, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))\nmodelImg.add(Conv2D(filters=256, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=256, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=256, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))\nmodelImg.add(Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))\nmodelImg.add(Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(Conv2D(filters=512, kernel_size=(3,3), padding=\"same\", activation=\"relu\"))\nmodelImg.add(MaxPool2D(pool_size=(2,2),strides=(2,2)))\nmodelImg.add(Flatten())\nmodelImg.add(Dense(units=4096,activation=\"relu\"))\nmodelImg.add(Dense(units=512,activation=\"relu\"))\nmodelImg.add(Dense(units=128,activation=\"relu\"))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"modelImg.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model for the metadata given with images","metadata":{}},{"cell_type":"code","source":"modelAttr = Sequential()\nmodelAttr.add(Dense(8, input_dim=13, activation=\"relu\"))\nmodelAttr.add(Dense(4, activation=\"relu\"))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"modelAttr.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Combining both models using keras functional api","metadata":{}},{"cell_type":"code","source":"#Concatenate the weights/outputs from both modelImg and modelAttr\ncombinedInput = concatenate([modelImg.output, modelAttr.output])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"x = Dense(128, activation=\"relu\")(combinedInput)\nx = Dense(64, activation=\"relu\")(x)\nx = Dense(1, activation=\"softmax\")(x)\nmodelCombined = Model(inputs = [modelImg.input, modelAttr.input], outputs = x)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"modelCombined.summary()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"opt = Adam(lr=1e-3, decay=1e-3 / 200)\nmodelCombined.compile(loss=\"binary_crossentropy\", metrics=['acc'], optimizer=opt)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"modelCombined_history = modelCombined.fit([trainImg, trainAttrX], Y, epochs=5, batch_size=10)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}