{"metadata":{"kernelspec":{"display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":11848,"databundleVersionId":862157,"sourceType":"competition"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false},"colab":{"provenance":[],"gpuType":"T4"},"accelerator":"GPU","widgets":{"application/vnd.jupyter.widget-state+json":{"b5805007cb504e02b20aa95940caf09d":{"model_module":"@jupyter-widgets/controls","model_name":"VBoxModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"VBoxModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"VBoxView","box_style":"","children":["IPY_MODEL_8420338df3004a76a54bfc7e5c09a15f"],"layout":"IPY_MODEL_3d0671711da945429cc32d163d22ef5c"}},"1ecbf775b2e64f5fb7ac0e14a8922cc0":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_13d4c38e3c4946cf860531930fdd9846","placeholder":"​","style":"IPY_MODEL_f59e3b29a17a49cb9f6c1b43ce05b051","value":"<center> <img\nsrc=https://www.kaggle.com/static/images/site-logo.png\nalt='Kaggle'> <br> Create an API token from <a\nhref=\"https://www.kaggle.com/settings/account\" target=\"_blank\">your Kaggle\nsettings page</a> and paste it below along with your Kaggle username. <br> </center>"}},"eebf9dcf851a4dfdaf372b24261d99ec":{"model_module":"@jupyter-widgets/controls","model_name":"TextModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"TextModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"TextView","continuous_update":true,"description":"Username:","description_tooltip":null,"disabled":false,"layout":"IPY_MODEL_42d53a6f61a242cc8a9509bde8464204","placeholder":"​","style":"IPY_MODEL_4ea97209820b4aa9942d67d7d24a72eb","value":"johnogilvie"}},"d42b07dfead9439e815602bf78a8746f":{"model_module":"@jupyter-widgets/controls","model_name":"PasswordModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"PasswordModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"PasswordView","continuous_update":true,"description":"Token:","description_tooltip":null,"disabled":false,"layout":"IPY_MODEL_3032c296c35147c2adb441e0a4a109a1","placeholder":"​","style":"IPY_MODEL_dc88843954c54b04aa71093ce85381b3","value":""}},"fef255fa719f4e37bfbaf3f89ad500b6":{"model_module":"@jupyter-widgets/controls","model_name":"ButtonModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"ButtonView","button_style":"","description":"Login","disabled":false,"icon":"","layout":"IPY_MODEL_5a780bdb0e0b4b80aca874d9f04f9fe9","style":"IPY_MODEL_7a2f32ffec8e4b45ade0427a79c6819b","tooltip":""}},"5027d840a92840a289ff5cc7e59fe9d0":{"model_module":"@jupyter-widgets/controls","model_name":"HTMLModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"HTMLModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"HTMLView","description":"","description_tooltip":null,"layout":"IPY_MODEL_ac77d96f885b4fdf8663a8062255a1e8","placeholder":"​","style":"IPY_MODEL_f3dff9655e5a43a8bb12edfd69c49e3b","value":"\n<b>Thank You</b></center>"}},"3d0671711da945429cc32d163d22ef5c":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":"center","align_self":null,"border":null,"bottom":null,"display":"flex","flex":null,"flex_flow":"column","grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":"50%"}},"13d4c38e3c4946cf860531930fdd9846":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f59e3b29a17a49cb9f6c1b43ce05b051":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"42d53a6f61a242cc8a9509bde8464204":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"4ea97209820b4aa9942d67d7d24a72eb":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"3032c296c35147c2adb441e0a4a109a1":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"dc88843954c54b04aa71093ce85381b3":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"5a780bdb0e0b4b80aca874d9f04f9fe9":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"7a2f32ffec8e4b45ade0427a79c6819b":{"model_module":"@jupyter-widgets/controls","model_name":"ButtonStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"ButtonStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","button_color":null,"font_weight":""}},"ac77d96f885b4fdf8663a8062255a1e8":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"f3dff9655e5a43a8bb12edfd69c49e3b":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"e6d971bcf8dc4abb88829bb0d38b1d08":{"model_module":"@jupyter-widgets/controls","model_name":"LabelModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_bc5c9e83d24e4d46b90e320f607507aa","placeholder":"​","style":"IPY_MODEL_1f05c951fadf404da4693032771dbbb1","value":"Connecting..."}},"bc5c9e83d24e4d46b90e320f607507aa":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"1f05c951fadf404da4693032771dbbb1":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}},"8420338df3004a76a54bfc7e5c09a15f":{"model_module":"@jupyter-widgets/controls","model_name":"LabelModel","model_module_version":"1.5.0","state":{"_dom_classes":[],"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"LabelModel","_view_count":null,"_view_module":"@jupyter-widgets/controls","_view_module_version":"1.5.0","_view_name":"LabelView","description":"","description_tooltip":null,"layout":"IPY_MODEL_fbdf2c55e97e4af0bc2eaec9e128ed49","placeholder":"​","style":"IPY_MODEL_757c86cc083d4c579f93568f4c01488e","value":"Kaggle credentials successfully validated."}},"fbdf2c55e97e4af0bc2eaec9e128ed49":{"model_module":"@jupyter-widgets/base","model_name":"LayoutModel","model_module_version":"1.2.0","state":{"_model_module":"@jupyter-widgets/base","_model_module_version":"1.2.0","_model_name":"LayoutModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"LayoutView","align_content":null,"align_items":null,"align_self":null,"border":null,"bottom":null,"display":null,"flex":null,"flex_flow":null,"grid_area":null,"grid_auto_columns":null,"grid_auto_flow":null,"grid_auto_rows":null,"grid_column":null,"grid_gap":null,"grid_row":null,"grid_template_areas":null,"grid_template_columns":null,"grid_template_rows":null,"height":null,"justify_content":null,"justify_items":null,"left":null,"margin":null,"max_height":null,"max_width":null,"min_height":null,"min_width":null,"object_fit":null,"object_position":null,"order":null,"overflow":null,"overflow_x":null,"overflow_y":null,"padding":null,"right":null,"top":null,"visibility":null,"width":null}},"757c86cc083d4c579f93568f4c01488e":{"model_module":"@jupyter-widgets/controls","model_name":"DescriptionStyleModel","model_module_version":"1.5.0","state":{"_model_module":"@jupyter-widgets/controls","_model_module_version":"1.5.0","_model_name":"DescriptionStyleModel","_view_count":null,"_view_module":"@jupyter-widgets/base","_view_module_version":"1.2.0","_view_name":"StyleView","description_width":""}}}}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## This notebook brings together in one place the best-performing model aspects from prior weeks of DSCI 598 Capstone\n* exploratory data analysis and preparation from Week3\n* https://www.kaggle.com/code/johnogilvie/jwo-histocancerdetect-eda-select-v1\n* 64x64 image size, Colab development from Week4\n* https://www.kaggle.com/code/johnogilvie/jwo-histocancerdetect-img-sizes-select-v1  \n* skipping image augmentation, from Week5\n* https://www.kaggle.com/code/johnogilvie/jwo-histocancerdetect-data-augs-select-v1  \n* transfer learning with DenseNet121, from Week6\n* https://www.kaggle.com/code/johnogilvie/jwo-histocancerdetect-transfer-select-v1\n* use of multiple convolutional layers, from Week7 and Week6\n* https://www.kaggle.com/code/johnogilvie/jwo-histocancerdetect-layers-select-v1\n* https://www.kaggle.com/code/johnogilvie/jwo-histocancerdetect-transfer-select-v1","metadata":{"id":"toYTJKVtZkNu"}},{"cell_type":"code","source":"# IMPORTANT: SOME KAGGLE DATA SOURCES ARE PRIVATE\n# RUN THIS CELL IN ORDER TO IMPORT YOUR KAGGLE DATA SOURCES.\nimport kagglehub\nkagglehub.login()\n","metadata":{"id":"DzYaHq3nZkNt","outputId":"91a47037-49a0-430a-fe9d-0fd9aedbcc8b"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# IMPORTANT: RUN THIS CELL IN ORDER TO IMPORT YOUR KAGGLE DATA SOURCES,\n# THEN FEEL FREE TO DELETE THIS CELL.\n# NOTE: THIS NOTEBOOK ENVIRONMENT DIFFERS FROM KAGGLE'S PYTHON\n# ENVIRONMENT SO THERE MAY BE MISSING LIBRARIES USED BY YOUR\n# NOTEBOOK.\n\nhistopathologic_cancer_detection_path = kagglehub.competition_download('histopathologic-cancer-detection')\n\nprint('Data source import complete.')\n","metadata":{"id":"xT-ENYMFZkNt","outputId":"df41c22c-f8fb-4348-81cb-a2b50dab9aa9"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Import packages","metadata":{"id":"AiPFxnThZkNv"}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.utils import shuffle\n\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import *\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras import models, layers, datasets\nfrom tensorflow.keras.activations import swish\nfrom tensorflow import keras","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:19.578822Z","iopub.execute_input":"2025-10-30T19:17:19.579496Z","iopub.status.idle":"2025-10-30T19:17:32.826462Z","shell.execute_reply.started":"2025-10-30T19:17:19.579461Z","shell.execute_reply":"2025-10-30T19:17:32.825931Z"},"id":"gARp1rP2ZkNv"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## View and prepare Data (Nulls check, Distributions, Image labels)","metadata":{"id":"ATTsiJutZkNw"}},{"cell_type":"code","source":"train = pd.read_csv(f'{histopathologic_cancer_detection_path}/train_labels.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:32.82716Z","iopub.execute_input":"2025-10-30T19:17:32.827616Z","iopub.status.idle":"2025-10-30T19:17:33.166373Z","shell.execute_reply.started":"2025-10-30T19:17:32.827597Z","shell.execute_reply":"2025-10-30T19:17:33.165816Z"},"id":"Y_EoOp6_ZkNw"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.isnull().sum().T","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:33.187585Z","iopub.execute_input":"2025-10-30T19:17:33.187756Z","iopub.status.idle":"2025-10-30T19:17:33.203536Z","shell.execute_reply.started":"2025-10-30T19:17:33.187742Z","shell.execute_reply":"2025-10-30T19:17:33.202912Z"},"id":"cVefefM5ZkNw","outputId":"9ae0703f-1861-4afd-9eb9-2aec7256dfe2"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"(train.label.value_counts()/len(train.label)).to_frame().T","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:33.204184Z","iopub.execute_input":"2025-10-30T19:17:33.204504Z","iopub.status.idle":"2025-10-30T19:17:33.221834Z","shell.execute_reply.started":"2025-10-30T19:17:33.204486Z","shell.execute_reply":"2025-10-30T19:17:33.221217Z"},"id":"cak2XOpyZkNw","outputId":"3b8a701f-82fa-4393-ac66-efc63ffdc2e0"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Challenge: The image ids are used as filenames for the images, but the ids are missing the \".tif\" extension.\n#You will need to add a copy to the DataFrame to store the complete filename rather than just the id\ntrain['filenames'] = train['id']+'.tif'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:33.222557Z","iopub.execute_input":"2025-10-30T19:17:33.222811Z","iopub.status.idle":"2025-10-30T19:17:33.260522Z","shell.execute_reply.started":"2025-10-30T19:17:33.222788Z","shell.execute_reply":"2025-10-30T19:17:33.259871Z"},"id":"itYi69MfZkNx"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:33.261192Z","iopub.execute_input":"2025-10-30T19:17:33.261422Z","iopub.status.idle":"2025-10-30T19:17:33.269709Z","shell.execute_reply.started":"2025-10-30T19:17:33.261405Z","shell.execute_reply":"2025-10-30T19:17:33.268942Z"},"id":"rW7i2FhtZkNx","outputId":"a34adce4-3dc9-4ee5-f544-bdfc05d73f9f"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Sample the Data to make training more efficient","metadata":{"id":"tdiEX3fJZkNx"}},{"cell_type":"code","source":"SS = 50000\nRS = 10\n\npositives = train[train['label']==1].sample(SS, random_state = RS)\nnegatives = train[train['label']==0].sample(SS, random_state = SS)\n\nnew_train = pd.concat([positives,negatives], axis = 0).reset_index(drop = True)\nnew_train = shuffle(new_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:34.277308Z","iopub.execute_input":"2025-10-30T19:17:34.277497Z","iopub.status.idle":"2025-10-30T19:17:34.351229Z","shell.execute_reply.started":"2025-10-30T19:17:34.277483Z","shell.execute_reply":"2025-10-30T19:17:34.350431Z"},"id":"SEboBRnOZkNx"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"(new_train.label.value_counts()/len(new_train)).to_frame().T","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:34.360326Z","iopub.execute_input":"2025-10-30T19:17:34.360807Z","iopub.status.idle":"2025-10-30T19:17:34.375092Z","shell.execute_reply.started":"2025-10-30T19:17:34.36079Z","shell.execute_reply":"2025-10-30T19:17:34.37441Z"},"id":"0rjES3gdZkNx","outputId":"10ba3ff6-a18c-494e-e381-4f204cbf8f8d"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# new_train = new_train.sample(frac=0.05)  # use only a fraction of the dataset","metadata":{"id":"vmhZY99GasNm"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Train_Test_Split","metadata":{"id":"mZqkDl17ZkNx"}},{"cell_type":"code","source":"train_df, val_df = train_test_split(new_train, test_size = .2, random_state = 10, stratify = new_train.label)\n\nprint(train_df.shape)\nprint(val_df.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:34.375866Z","iopub.execute_input":"2025-10-30T19:17:34.376167Z","iopub.status.idle":"2025-10-30T19:17:34.425624Z","shell.execute_reply.started":"2025-10-30T19:17:34.376149Z","shell.execute_reply":"2025-10-30T19:17:34.424839Z"},"id":"FWEDr0vWZkNx","outputId":"3089107a-d49d-48a8-9803-a54dd76ebdb4"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Rescale Images with ImageDataGenerator","metadata":{"id":"XsDvp3v2ZkNx"}},{"cell_type":"code","source":"train_images_path = f'{histopathologic_cancer_detection_path}/train'","metadata":{"id":"xtmvce1WbCLz"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Challenge: You will need to use an image data generator to load the files from disk.\ntrain_datagen = ImageDataGenerator(rescale = 1/255)\nval_datagen = ImageDataGenerator(rescale = 1/255)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:34.426412Z","iopub.execute_input":"2025-10-30T19:17:34.426749Z","iopub.status.idle":"2025-10-30T19:17:34.430143Z","shell.execute_reply.started":"2025-10-30T19:17:34.426726Z","shell.execute_reply":"2025-10-30T19:17:34.42949Z"},"id":"FpL3E74HZkNy"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"### Make labels into strings","metadata":{"id":"mLWr4HkfZkNy"}},{"cell_type":"code","source":"train_df['label'] = train_df['label'].astype(str)\nval_df['label'] = val_df['label'].astype(str)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:34.430772Z","iopub.execute_input":"2025-10-30T19:17:34.431034Z","iopub.status.idle":"2025-10-30T19:17:34.463712Z","shell.execute_reply.started":"2025-10-30T19:17:34.431009Z","shell.execute_reply":"2025-10-30T19:17:34.463051Z"},"id":"XQFdW27rZkNy"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Create loaders without using data augmentation\n* Images sized 64x64","metadata":{"id":"2WhFNRUTZkNy"}},{"cell_type":"code","source":"%%time\nbatch_size = 32\n\ntrain_loader = train_datagen.flow_from_dataframe(\n    dataframe = train_df,\n    directory = train_images_path,\n    x_col = 'filenames',\n    y_col = 'label',\n    batch_size = batch_size,\n    seed = 10,\n    shuffle = True,\n    class_mode = 'binary',\n    horizontal_flip = False,\n    vertical_flip = False,\n    height_shift_range = 0,\n    width_shift_range = 0,\n    rotation_range = 0,\n    target_size = (64,64)\n)\n\nval_loader = val_datagen.flow_from_dataframe(\n    dataframe = val_df,\n    directory = train_images_path,\n    x_col = 'filenames',\n    y_col = 'label',\n    batch_size = batch_size,\n    seed = 10,\n    shuffle = True,\n    class_mode = 'binary',\n    target_size = (64,64)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:17:34.464339Z","iopub.execute_input":"2025-10-30T19:17:34.464552Z","iopub.status.idle":"2025-10-30T19:20:25.492246Z","shell.execute_reply.started":"2025-10-30T19:17:34.464529Z","shell.execute_reply":"2025-10-30T19:20:25.491663Z"},"id":"J2k5r4xfZkNy","outputId":"c5ee8ca4-6c27-4589-da14-7a4a0fd6f38b"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"TR_STEPS = len(train_loader)\nVAL_STEPS = len(val_loader)\n\nprint(TR_STEPS)\nprint(VAL_STEPS)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:20:25.493001Z","iopub.execute_input":"2025-10-30T19:20:25.493248Z","iopub.status.idle":"2025-10-30T19:20:25.497344Z","shell.execute_reply.started":"2025-10-30T19:20:25.493222Z","shell.execute_reply":"2025-10-30T19:20:25.496661Z"},"id":"xZm_zI0MZkNy","outputId":"3710bc96-67a5-4385-fccc-1837c5275cf5"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Create model using best (of four tested) pretrained model as foundation","metadata":{"id":"OL2j-qRVfd24"}},{"cell_type":"markdown","source":"## Use callbacks for early stopping if the model doesn't improve\n","metadata":{"id":"MPYZO5yUZkNy"}},{"cell_type":"code","source":"early_stopping_callback = keras.callbacks.EarlyStopping(\n    monitor='val_AUC',\n    patience=10,\n    restore_best_weights=True,\n    mode='max',\n    verbose=1\n)\n\nlr_scheduler_callback = keras.callbacks.ReduceLROnPlateau(\n    monitor='val_AUC',\n    factor=0.5,\n    patience=5,\n    min_lr=1e-8,\n    mode='max',\n    verbose=1\n)\n\ncallbacks_list = [early_stopping_callback, lr_scheduler_callback]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:20:31.92824Z","iopub.execute_input":"2025-10-30T19:20:31.928465Z","iopub.status.idle":"2025-10-30T19:20:31.967154Z","shell.execute_reply.started":"2025-10-30T19:20:31.928441Z","shell.execute_reply":"2025-10-30T19:20:31.966468Z"},"id":"PKa1W_lXZkNy"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"num_epochs = 20","metadata":{"id":"2NUPXXIgf80u"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Function to display a model's performance\n","metadata":{"id":"mltWYdRhZkNy"}},{"cell_type":"code","source":"def display_perf(history, loss_title, auc_title):\n  epoch_range = range(1, len(history['loss'])+1)\n  plt.figure(figsize = [12,5])\n  plt.subplot(1,2,1)\n  plt.plot(epoch_range, history['loss'], label = 'Training')\n  plt.plot(epoch_range, history['val_loss'], label = 'Validation')\n  plt.xlabel('Epoch');plt.ylabel('Loss');plt.title(loss_title)\n\n  plt.subplot(1,2,2)\n  plt.plot(epoch_range, history['AUC'], label = 'Training')\n  plt.plot(epoch_range, history['val_AUC'], label = 'Validation')\n  plt.xlabel(\"Epoch\");plt.ylabel(\"AUC\");plt.title(auc_title)\n  plt.legend()\n  plt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T20:37:56.041209Z","iopub.execute_input":"2025-10-30T20:37:56.041474Z","iopub.status.idle":"2025-10-30T20:37:56.343301Z","shell.execute_reply.started":"2025-10-30T20:37:56.041451Z","shell.execute_reply":"2025-10-30T20:37:56.342759Z"},"id":"OetSr53GZkNy"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Get a sample batch from the validation loader\nsample_batch = next(iter(val_loader))\nsample_images, sample_labels = sample_batch\nsample = sample_images[0:1] # Take the first image in the batch","metadata":{"id":"c15bbzeDnyRR"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Create a model using the DenseNet121 model from keras as the foundation\n* Print the Architecture of the model\n* Input shape will be 64x64\n* Training only the last 30 layers of the model\n* Swish activation instead of the relu for the dense layers","metadata":{"id":"t1xVVrk_rchZ"}},{"cell_type":"code","source":"base_model_den=keras.applications.DenseNet121(\n    include_top=False,\n    weights=\"imagenet\",\n    input_tensor=None,\n    input_shape=(64,64,3),\n    pooling=None,\n    classes=2,\n    classifier_activation=\"Swish\",\n)\nbase_model_den.trainable = True\n\nfor layer in base_model_den.layers[:-30]:\n    layer.trainable = True\n\ncnn_model_den = models.Sequential([\n    base_model_den,\n    layers.GlobalAveragePooling2D(),\n    Dense(512, activation = 'swish'),\n    Dropout(.4),\n    Dense(256, activation = 'swish'),\n    Dropout(.3),\n    Dense(128, activation = 'swish'),\n    Dropout(.2),\n    Dense(1, activation = 'sigmoid')\n])\ncnn_model_den.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:20:25.498055Z","iopub.execute_input":"2025-10-30T19:20:25.498382Z","iopub.status.idle":"2025-10-30T19:20:31.912624Z","shell.execute_reply.started":"2025-10-30T19:20:25.498364Z","shell.execute_reply":"2025-10-30T19:20:31.911873Z"},"outputId":"4222742a-c085-4f52-a12a-40d6767847c0","id":"za0tg8MTrchZ"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"opt = tf.keras.optimizers.Adam(learning_rate = 1e-5)\ncnn_model_den.compile(loss = 'binary_crossentropy', optimizer = opt, metrics = ['AUC'])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:20:31.91346Z","iopub.execute_input":"2025-10-30T19:20:31.913818Z","iopub.status.idle":"2025-10-30T19:20:31.927595Z","shell.execute_reply.started":"2025-10-30T19:20:31.913793Z","shell.execute_reply":"2025-10-30T19:20:31.927084Z"},"id":"8qqaAiJ2rcha"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Run training iteration","metadata":{"id":"H_aohjjNrcha"}},{"cell_type":"code","source":"%%time\nhistory_den = cnn_model_den.fit(\n    x = train_loader,\n    steps_per_epoch = TR_STEPS,\n    epochs = num_epochs,\n    validation_data = val_loader,\n    validation_steps = VAL_STEPS,\n    verbose = 1,\n    callbacks = callbacks_list\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T19:20:31.967843Z","iopub.execute_input":"2025-10-30T19:20:31.968073Z","iopub.status.idle":"2025-10-30T20:37:56.030652Z","shell.execute_reply.started":"2025-10-30T19:20:31.968058Z","shell.execute_reply":"2025-10-30T20:37:56.029849Z"},"outputId":"660faee5-68cb-4381-befd-6bfb1a598b23","id":"11uya351rchb"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"lossden, aucden = cnn_model_den.evaluate(val_loader, verbose=0)\nprint(f\"DenseNet121 Test AUC: {aucden:.4f}\")","metadata":{"outputId":"422d2223-4cd1-4b4b-c0d3-7aa07e316959","id":"Q5tZinkFrchb"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Predict on new data\n\npredictionden = cnn_model_den.predict(sample)\nprint(f\"DenseNet121 predicted probability of class 1: {predictionden[0][0]:.4f}\")","metadata":{"outputId":"19c1bd88-9561-424e-b6f7-e175d5ba3bca","id":"_hspe6YBrchb"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"display_perf(history_den.history, 'DenseNet121 Training Loss', 'DenseNet121 Training AUC')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T20:37:56.036734Z","iopub.execute_input":"2025-10-30T20:37:56.036951Z","iopub.status.idle":"2025-10-30T20:37:56.040312Z","shell.execute_reply.started":"2025-10-30T20:37:56.036936Z","shell.execute_reply":"2025-10-30T20:37:56.039602Z"},"id":"mK8n8YMjZkNy","outputId":"bf4150a6-9aa0-4be6-f72d-5825b84edaa5"},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Save the model","metadata":{"id":"2bwZQls1ZkNz"}},{"cell_type":"code","source":"# save models in Google Drive\nfrom google.colab import drive\ndrive.mount('/content/drive')\nmodel_save_path = '/content/drive/MyDrive/Cancer_Detection_Models/'","metadata":{"id":"7f07Zs3z-A3B","outputId":"e894d4f9-97a6-47a2-9032-542bd5b7b0b3"},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pickle\nimport os\n\n# Create the directory if it doesn't exist\nos.makedirs(model_save_path, exist_ok=True)\n\ncnn_model_den.save(f'{model_save_path}/Cancer_Detection_model_denbest.keras')\npickle.dump(history_den.history, open(f'{model_save_path}/Cancer_Detection_model_denbest.pk1', 'wb'))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-30T20:37:56.345881Z","iopub.execute_input":"2025-10-30T20:37:56.346326Z","iopub.status.idle":"2025-10-30T20:37:57.325314Z","shell.execute_reply.started":"2025-10-30T20:37:56.346308Z","shell.execute_reply":"2025-10-30T20:37:57.324618Z"},"id":"C4MF9eVrL3va"},"outputs":[],"execution_count":null}]}