{"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 # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\n%matplotlib inline\n\nimport glob\n\nimport matplotlib.image as mpimg\nimport matplotlib.pyplot as plt\n\nimport pydicom\nimport random\n\nimport tensorflow as tf\nprint(tf.__version__)\nfrom tensorflow.keras.optimizers import RMSprop\n\nfrom tqdm import tqdm\nimport cv2\nfrom joblib import Parallel, delayed\nimport shutil","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-12-14T04:16:47.6019Z","iopub.execute_input":"2022-12-14T04:16:47.602452Z","iopub.status.idle":"2022-12-14T04:16:49.974589Z","shell.execute_reply.started":"2022-12-14T04:16:47.60234Z","shell.execute_reply":"2022-12-14T04:16:49.973375Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Config","metadata":{}},{"cell_type":"code","source":"target_size = 256\n","metadata":{"execution":{"iopub.status.busy":"2022-12-14T04:16:50.763198Z","iopub.execute_input":"2022-12-14T04:16:50.764315Z","iopub.status.idle":"2022-12-14T04:16:50.769683Z","shell.execute_reply.started":"2022-12-14T04:16:50.764268Z","shell.execute_reply":"2022-12-14T04:16:50.768372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## UDFs","metadata":{}},{"cell_type":"code","source":"def img2roi(path):\n    img = cv2.imread(path)\n    img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n    # Binarize the image\n    bin_img = cv2.threshold(img, 20, 255, cv2.THRESH_BINARY)[1]\n\n    # Make contours around the binarized image, keep only the largest contour\n    contours, _ = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n    contour = max(contours, key=cv2.contourArea)\n\n    # Find ROI from largest contour\n    ys = contour.squeeze()[:, 0]\n    xs = contour.squeeze()[:, 1]\n    roi =  img[np.min(xs):np.max(xs), np.min(ys):np.max(ys)]\n    \n    roi = cv2.resize(roi, (img.shape[1], img.shape[0]))\n    roi = cv2.cvtColor(roi,cv2.COLOR_GRAY2RGB)\n#     roi = np.expand_dims(roi, axis =-1)\n    return roi\n\n# function for plotting the accuracy and loss vs epochs\ndef plot_loss_acc(history):\n    '''Plots the training and validation loss and accuracy from a history object'''\n    acc = history.history['accuracy']\n    val_acc = history.history['val_accuracy']\n    loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    epochs = range(len(acc))\n\n    plt.plot(epochs, acc, 'bo', label='Training accuracy')\n    plt.plot(epochs, val_acc, 'b', label='Validation accuracy')\n    plt.title('Training and validation accuracy')\n\n    plt.figure()\n\n    plt.plot(epochs, loss, 'bo', label='Training Loss')\n    plt.plot(epochs, val_loss, 'b', label='Validation Loss')\n    plt.title('Training and validation loss')\n    plt.legend()\n\n    plt.show()\n","metadata":{"execution":{"iopub.status.busy":"2022-12-14T04:16:52.253546Z","iopub.execute_input":"2022-12-14T04:16:52.253969Z","iopub.status.idle":"2022-12-14T04:16:52.26745Z","shell.execute_reply.started":"2022-12-14T04:16:52.25393Z","shell.execute_reply":"2022-12-14T04:16:52.266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"save_folder = '/kaggle/input/rsna-breast-cancer-' + str(target_size)+'-pngs'\nf_names = os.listdir(save_folder)\nprint(len(f_names))","metadata":{"execution":{"iopub.status.busy":"2022-12-14T04:16:52.867123Z","iopub.execute_input":"2022-12-14T04:16:52.867505Z","iopub.status.idle":"2022-12-14T04:16:52.896394Z","shell.execute_reply.started":"2022-12-14T04:16:52.867473Z","shell.execute_reply":"2022-12-14T04:16:52.894955Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Download the weights for the inception-V3 model:","metadata":{}},{"cell_type":"code","source":"!wget --no-check-certificate \\\n    https://storage.googleapis.com/mledu-datasets/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5 \\\n    -O /tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5","metadata":{"execution":{"iopub.status.busy":"2022-12-14T04:16:54.450109Z","iopub.execute_input":"2022-12-14T04:16:54.45123Z","iopub.status.idle":"2022-12-14T04:16:56.459313Z","shell.execute_reply.started":"2022-12-14T04:16:54.451181Z","shell.execute_reply":"2022-12-14T04:16:56.457646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_dir = \"/tmp/cancer_data_\" + str(target_size)\n\nos.makedirs(os.path.join(base_dir,'train'), exist_ok=True)\nos.makedirs(os.path.join(base_dir,'train','cancer'), exist_ok=True)\nos.makedirs(os.path.join(base_dir,'train','non-cancer'), exist_ok=True)\n\nos.makedirs(os.path.join(base_dir,'validation'), exist_ok=True)\nos.makedirs(os.path.join(base_dir,'validation','cancer'), exist_ok=True)\nos.makedirs(os.path.join(base_dir,'validation','non-cancer'), exist_ok=True)\n\ntrain_dir = os.path.join(base_dir, 'train')\nvalidation_dir = os.path.join(base_dir, 'validation')\n\n# Directory with training cat/dog pictures\ntrain_cancer_dir = os.path.join(train_dir, 'cancer')\ntrain_non_cancer_dir = os.path.join(train_dir, 'non-cancer')\n\n# Directory with validation cat/dog pictures\nvalidation_cancer_dir = os.path.join(validation_dir, 'cancer')\nvalidation_non_cancer_dir = os.path.join(validation_dir, 'non-cancer')","metadata":{"execution":{"iopub.status.busy":"2022-12-14T04:16:56.462179Z","iopub.execute_input":"2022-12-14T04:16:56.462664Z","iopub.status.idle":"2022-12-14T04:16:56.473758Z","shell.execute_reply.started":"2022-12-14T04:16:56.462616Z","shell.execute_reply":"2022-12-14T04:16:56.472783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/rsna-breast-cancer-detection/train.csv')\nprint(f'shape of the train data: {df.shape}')\nprint(f\"number of the patients: {len(df['patient_id'].unique())}\")\nprint(f\"number of the unique images: {len(df['image_id'].unique().tolist())} \\n\")\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-12-14T04:17:47.855968Z","iopub.execute_input":"2022-12-14T04:17:47.858743Z","iopub.status.idle":"2022-12-14T04:17:48.10004Z","shell.execute_reply.started":"2022-12-14T04:17:47.858671Z","shell.execute_reply":"2022-12-14T04:17:48.098584Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Move the files into correct folders for tensorflow","metadata":{}},{"cell_type":"code","source":"random.seed(1)\nN = len(df['patient_id'].unique().tolist())\nN = 1000\nsample_ids = random.sample(df['patient_id'].unique().tolist(),N)\nsplit_ratio = 0.8\ntrain_ids  = sample_ids[:int(split_ratio * len(sample_ids))]\nvalidation_ids = sample_ids[int(split_ratio * len(sample_ids)):]\n\nfor v in tqdm(f_names):\n    patient_id = int(v.split('_')[0])\n    image_id = int(v.split('_')[1][:-4])\n\n    # train data\n    if patient_id in train_ids and df.loc[df['image_id']==image_id,'cancer'].values[0]==1:\n        cv2.imwrite(os.path.join(train_cancer_dir,v), img2roi(os.path.join(save_folder, v)))\n#         (img * 255).astype(np.uint8)\n#         shutil.copy(os.path.join(save_folder, v),os.path.join(train_cancer_dir,v))\n    elif patient_id in train_ids and df.loc[df['image_id']==image_id,'cancer'].values[0]==0:\n        cv2.imwrite(os.path.join(train_non_cancer_dir,v), img2roi(os.path.join(save_folder, v)))\n#         shutil.copy(os.path.join(save_folder, v),os.path.join(train_non_cancer_dir,v))\n    # validation data\n    elif patient_id in validation_ids and df.loc[df['image_id']==image_id,'cancer'].values[0]==1:\n        cv2.imwrite(os.path.join(validation_cancer_dir,v), img2roi(os.path.join(save_folder, v)))\n#         shutil.copy(os.path.join(save_folder, v),os.path.join(validation_cancer_dir,v))\n    elif patient_id in validation_ids and df.loc[df['image_id']==image_id,'cancer'].values[0]==0:\n        cv2.imwrite(os.path.join(validation_non_cancer_dir,v), img2roi(os.path.join(save_folder, v)))\n#         shutil.copy(os.path.join(save_folder, v),os.path.join(validation_non_cancer_dir,v))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications.inception_v3 import InceptionV3\nfrom tensorflow.keras import layers\n\n# Set the weights file you downloaded into a variable\nlocal_weights_file = '/tmp/inception_v3_weights_tf_dim_ordering_tf_kernels_notop.h5'\n\n# Initialize the base model.\n# Set the input shape and remove the dense layers.\npre_trained_model = InceptionV3(input_shape = (target_size, target_size, 3), \n                                include_top = False, \n                                weights = None)\n\n# Load the pre-trained weights you downloaded.\npre_trained_model.load_weights(local_weights_file)\n\n# Freeze the weights of the layers.\nfor layer in pre_trained_model.layers:\n  layer.trainable = False","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Choose `mixed_7` as the last layer of your base model\nlast_layer = pre_trained_model.get_layer('mixed7')\nprint('last layer output shape: ', last_layer.output_shape)\nlast_output = last_layer.output","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n# All images will be rescaled by 1./255.\ntrain_datagen = ImageDataGenerator(rescale = 1.0/255.)\ntest_datagen  = ImageDataGenerator(rescale = 1.0/255.)\ntrain_generator = train_datagen.flow_from_directory(train_dir,\n                                                    batch_size=50,\n                                                    class_mode='binary',\n#                                                     color_mode='grayscale',\n                                                    target_size=(target_size, target_size))     \nvalidation_generator =  test_datagen.flow_from_directory(validation_dir,\n                                                         batch_size=50,\n                                                         class_mode  = 'binary',\n#                                                          color_mode='grayscale',\n                                                         target_size = (target_size, target_size))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.optimizers import RMSprop\nfrom tensorflow.keras import Model\n\ndef create_model(pre_trained_model):\n    \n    last_layer = pre_trained_model.get_layer('mixed7')\n    last_output = last_layer.output\n    \n    # Flatten the output layer to 1 dimension\n    x = layers.Flatten()(last_output)\n    # Add a fully connected layer with 1,024 hidden units and ReLU activation\n    x = layers.Dense(1024, activation='relu')(x)\n    # Add a dropout rate of 0.2\n    x = layers.Dropout(0.2)(x)                  \n    # Add a final sigmoid layer for classification\n    x = layers.Dense  (1, activation='sigmoid')(x)           \n\n    # Append the dense network to the base model\n    return(Model(pre_trained_model.input, x))\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# def create_model():\n#     '''Creates a CNN with 4 convolutional layers'''\n#     model = tf.keras.models.Sequential([\n#       tf.keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(512, 512,3)),\n#       tf.keras.layers.MaxPooling2D(2, 2),\n#       tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n#       tf.keras.layers.MaxPooling2D(2,2),\n#       tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n#       tf.keras.layers.MaxPooling2D(2,2),\n#       tf.keras.layers.Conv2D(128, (3,3), activation='relu'),\n#       tf.keras.layers.MaxPooling2D(2,2),\n#       tf.keras.layers.Flatten(),\n#       tf.keras.layers.Dense(512, activation='relu'),\n#       tf.keras.layers.Dense(1, activation='sigmoid')\n#     ])\n\n#     return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model(pre_trained_model)\nmodel.compile(loss='binary_crossentropy',\n            optimizer=RMSprop(learning_rate=1e-4),\n            metrics=['accuracy','Recall','Precision'])\n# model.summary()\nhistory = model.fit(\n            train_generator,\n            epochs=5,\n            validation_data=validation_generator,\n            verbose=1, batch_size=50\n            )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Look at the results and model performance","metadata":{}},{"cell_type":"code","source":"# Plot training results\nplot_loss_acc(history)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save the model","metadata":{}},{"cell_type":"code","source":"# model.save('/kaggle/working/model_v3')\n# model.save('/kaggle/working/my_model.h5')\nmodel.save_weights('/kaggle/working/inceptionv3-.h5')","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}