{"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":"markdown","source":"# Whale/Dolphin Transfer Learning3\nhttps://www.kaggle.com/stpeteishii/whale-dolphin-transfer-learning3","metadata":{"papermill":{"duration":0.032779,"end_time":"2022-02-03T06:58:05.346259","exception":false,"start_time":"2022-02-03T06:58:05.31348","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import tensorflow as tf \nimport numpy as np\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt \ntf.__version__","metadata":{"executionInfo":{"elapsed":1908,"status":"ok","timestamp":1618246146641,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"DeVbF5nfoJRF","outputId":"15b9a77c-e47b-43ca-b558-be92a5d989b0","papermill":{"duration":4.180541,"end_time":"2022-02-03T06:58:09.559297","exception":false,"start_time":"2022-02-03T06:58:05.378756","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:03.411846Z","iopub.execute_input":"2022-02-07T13:00:03.412685Z","iopub.status.idle":"2022-02-07T13:00:08.027602Z","shell.execute_reply.started":"2022-02-07T13:00:03.412562Z","shell.execute_reply":"2022-02-07T13:00:08.026849Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Preprocessing with ImageDataGenerator","metadata":{"papermill":{"duration":0.03109,"end_time":"2022-02-03T06:58:09.622746","exception":false,"start_time":"2022-02-03T06:58:09.591656","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## Prepare ImageDataGenerator\nhttps://www.tensorflow.org/api_docs/python/tf/keras/preprocessing/image/ImageDataGenerator","metadata":{"id":"WniRffKlTSMW","papermill":{"duration":0.031189,"end_time":"2022-02-03T06:58:09.685229","exception":false,"start_time":"2022-02-03T06:58:09.65404","status":"completed"},"tags":[]}},{"cell_type":"code","source":"img_generator = tf.keras.preprocessing.image.ImageDataGenerator(\n                            #rotation_range=90,\n                            brightness_range=(0.5,1), \n                            #shear_range=0.2, \n                            #zoom_range=0.2,\n                            channel_shift_range=0.2,\n                            horizontal_flip=False,\n                            vertical_flip=False,\n                            rescale=1./255,\n                            validation_split=0.3)","metadata":{"executionInfo":{"elapsed":633,"status":"ok","timestamp":1618246342957,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"Yh7dePadTP-b","papermill":{"duration":1.009276,"end_time":"2022-02-03T06:58:10.726232","exception":false,"start_time":"2022-02-03T06:58:09.716956","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:08.029457Z","iopub.execute_input":"2022-02-07T13:00:08.029751Z","iopub.status.idle":"2022-02-07T13:00:09.1704Z","shell.execute_reply.started":"2022-02-07T13:00:08.029713Z","shell.execute_reply":"2022-02-07T13:00:09.169537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## img_generator.flow_from_dataframe","metadata":{"id":"3CnfcVi40nqq","papermill":{"duration":0.031576,"end_time":"2022-02-03T06:58:10.790322","exception":false,"start_time":"2022-02-03T06:58:10.758746","status":"completed"},"tags":[]}},{"cell_type":"code","source":"train_dir='../input/happy-whale-and-dolphin/train_images'\ntrain=pd.read_csv('../input/happy-whale-and-dolphin/train.csv')\ntrain2=train[['image','species']].copy()\ntrain2['path']=train2['image'].apply(lambda x: os.path.join(train_dir,x))","metadata":{"papermill":{"duration":0.224582,"end_time":"2022-02-03T06:58:11.046603","exception":false,"start_time":"2022-02-03T06:58:10.822021","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.174195Z","iopub.execute_input":"2022-02-07T13:00:09.174468Z","iopub.status.idle":"2022-02-07T13:00:09.398663Z","shell.execute_reply.started":"2022-02-07T13:00:09.174439Z","shell.execute_reply":"2022-02-07T13:00:09.39783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train2","metadata":{"papermill":{"duration":0.049438,"end_time":"2022-02-03T06:58:11.128144","exception":false,"start_time":"2022-02-03T06:58:11.078706","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.400328Z","iopub.execute_input":"2022-02-07T13:00:09.401032Z","iopub.status.idle":"2022-02-07T13:00:09.417999Z","shell.execute_reply.started":"2022-02-07T13:00:09.400996Z","shell.execute_reply":"2022-02-07T13:00:09.41724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Name0=train2['species'].unique().tolist()\nName=sorted(Name0)\nprint(len(Name))\nprint(Name)\nN=list(range(len(Name)))\nnormal_mapping=dict(zip(Name,N)) \nreverse_mapping=dict(zip(N,Name)) ","metadata":{"papermill":{"duration":0.047255,"end_time":"2022-02-03T06:58:11.208767","exception":false,"start_time":"2022-02-03T06:58:11.161512","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.419228Z","iopub.execute_input":"2022-02-07T13:00:09.421713Z","iopub.status.idle":"2022-02-07T13:00:09.4325Z","shell.execute_reply.started":"2022-02-07T13:00:09.421676Z","shell.execute_reply":"2022-02-07T13:00:09.431524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#train2['species']=train2['species'].map(normal_mapping)\n\ntrain3 = pd.DataFrame().assign(ImagePath=train2.loc[:,'path'], ImageClass=train2.loc[:,'species'])\ntrain3","metadata":{"papermill":{"duration":0.056905,"end_time":"2022-02-03T06:58:11.300197","exception":false,"start_time":"2022-02-03T06:58:11.243292","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.433794Z","iopub.execute_input":"2022-02-07T13:00:09.434262Z","iopub.status.idle":"2022-02-07T13:00:09.459323Z","shell.execute_reply.started":"2022-02-07T13:00:09.434216Z","shell.execute_reply":"2022-02-07T13:00:09.458477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dir='../input/happy-whale-and-dolphin/test_images'\ntest=pd.read_csv('../input/happy-whale-and-dolphin/sample_submission.csv')\ntest2=test.copy()\ntest2['path']=test2['image'].apply(lambda x: os.path.join(test_dir,x))","metadata":{"papermill":{"duration":0.146672,"end_time":"2022-02-03T06:58:11.4801","exception":false,"start_time":"2022-02-03T06:58:11.333428","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.460462Z","iopub.execute_input":"2022-02-07T13:00:09.460747Z","iopub.status.idle":"2022-02-07T13:00:09.596867Z","shell.execute_reply.started":"2022-02-07T13:00:09.460715Z","shell.execute_reply":"2022-02-07T13:00:09.596075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test2['species']='Tiger'  ### dummy data\n\ntest3 = pd.DataFrame().assign(ImagePath=test2.loc[:,'path'], ImageClass=test2.loc[:,'species'])\ntest3","metadata":{"papermill":{"duration":0.051853,"end_time":"2022-02-03T06:58:11.565669","exception":false,"start_time":"2022-02-03T06:58:11.513816","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.598314Z","iopub.execute_input":"2022-02-07T13:00:09.59853Z","iopub.status.idle":"2022-02-07T13:00:09.618218Z","shell.execute_reply.started":"2022-02-07T13:00:09.598503Z","shell.execute_reply":"2022-02-07T13:00:09.617361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_generator = tf.keras.preprocessing.image.ImageDataGenerator(\n    preprocessing_function=tf.keras.applications.mobilenet_v2.preprocess_input,\n    validation_split=0.2\n)\n\ntimg_generator = tf.keras.preprocessing.image.ImageDataGenerator(\n    preprocessing_function=tf.keras.applications.mobilenet_v2.preprocess_input\n)","metadata":{"execution":{"iopub.status.busy":"2022-02-07T13:00:09.619673Z","iopub.execute_input":"2022-02-07T13:00:09.620049Z","iopub.status.idle":"2022-02-07T13:00:09.626724Z","shell.execute_reply.started":"2022-02-07T13:00:09.620004Z","shell.execute_reply":"2022-02-07T13:00:09.625692Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#img_generator_flow_train = img_generator.flow_from_directory\n#img_generator_flow_train = img_generator.flow_from_dataframe\n\nimg_generator_flow_train = img_generator.flow_from_dataframe(\n    train3,\n    x_col='ImagePath',\n    y_col='ImageClass',\n    directory='',\n    target_size=(224, 224),\n    batch_size=64,\n    shuffle=True,\n    subset=\"training\",\n    class_mode='categorical',\n)\n\nimg_generator_flow_valid = img_generator.flow_from_dataframe(\n    train3,\n    x_col='ImagePath',\n    y_col='ImageClass',\n    directory='',\n    target_size=(224, 224),\n    batch_size=64,\n    shuffle=True,\n    subset=\"validation\",\n    class_mode='categorical',\n)\n","metadata":{"executionInfo":{"elapsed":806,"status":"ok","timestamp":1618246345412,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"_LvBCKUoV4ZJ","outputId":"4eaa9a71-a063-40b6-9d5e-b88e590c96de","papermill":{"duration":63.860655,"end_time":"2022-02-03T06:59:15.459163","exception":false,"start_time":"2022-02-03T06:58:11.598508","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:00:09.631035Z","iopub.execute_input":"2022-02-07T13:00:09.631262Z","iopub.status.idle":"2022-02-07T13:02:57.194855Z","shell.execute_reply.started":"2022-02-07T13:00:09.631236Z","shell.execute_reply":"2022-02-07T13:02:57.194028Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize a batch of images","metadata":{"id":"O4TrPF_01u_i","papermill":{"duration":0.036035,"end_time":"2022-02-03T06:59:41.837996","exception":false,"start_time":"2022-02-03T06:59:41.801961","status":"completed"},"tags":[]}},{"cell_type":"code","source":"imgs, labels = next(iter(img_generator_flow_train))\nfor img, label in zip(imgs, labels):\n    value=np.argmax(label)\n    plt.imshow(img)\n    plt.title('Species: '+reverse_mapping[value])\n    plt.axis(\"off\")\n    plt.show()","metadata":{"executionInfo":{"elapsed":12528,"status":"ok","timestamp":1617810476908,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"6Iwd3V0LWvIr","outputId":"a2c8fade-2953-418a-a35f-841f16d00c5e","papermill":{"duration":8.383197,"end_time":"2022-02-03T06:59:50.256209","exception":false,"start_time":"2022-02-03T06:59:41.873012","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:02:57.195949Z","iopub.execute_input":"2022-02-07T13:02:57.196188Z","iopub.status.idle":"2022-02-07T13:03:05.600632Z","shell.execute_reply.started":"2022-02-07T13:02:57.196159Z","shell.execute_reply":"2022-02-07T13:03:05.59936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Transfer Learning ","metadata":{"papermill":{"duration":0.130252,"end_time":"2022-02-03T06:59:50.795648","exception":false,"start_time":"2022-02-03T06:59:50.665396","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## Import a pretrained model\nhttps://www.tensorflow.org/api_docs/python/tf/keras/applications/InceptionV3","metadata":{"id":"DK_WyoLK2PcM","papermill":{"duration":0.13164,"end_time":"2022-02-03T06:59:51.058212","exception":false,"start_time":"2022-02-03T06:59:50.926572","status":"completed"},"tags":[]}},{"cell_type":"code","source":"base_model = tf.keras.applications.InceptionV3(input_shape=(224,224,3),\n                                               include_top=False,\n                                               weights = \"imagenet\"\n                                               )","metadata":{"executionInfo":{"elapsed":16833,"status":"ok","timestamp":1617810482762,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"oZx7RoskUhos","outputId":"2be71875-3c25-4abb-f6a8-6e5de521f0a8","papermill":{"duration":4.76373,"end_time":"2022-02-03T06:59:55.952703","exception":false,"start_time":"2022-02-03T06:59:51.188973","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:03:05.60272Z","iopub.execute_input":"2022-02-07T13:03:05.603041Z","iopub.status.idle":"2022-02-07T13:03:08.28978Z","shell.execute_reply.started":"2022-02-07T13:03:05.603Z","shell.execute_reply":"2022-02-07T13:03:08.28906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Set the weights of the imported model","metadata":{"id":"CfrYvfEbjmb2","papermill":{"duration":0.135842,"end_time":"2022-02-03T06:59:56.224585","exception":false,"start_time":"2022-02-03T06:59:56.088743","status":"completed"},"tags":[]}},{"cell_type":"code","source":"base_model.trainable = False","metadata":{"executionInfo":{"elapsed":14699,"status":"ok","timestamp":1617810482764,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"SscDh01oVHVX","papermill":{"duration":0.152428,"end_time":"2022-02-03T06:59:56.514185","exception":false,"start_time":"2022-02-03T06:59:56.361757","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:03:08.290893Z","iopub.execute_input":"2022-02-07T13:03:08.291116Z","iopub.status.idle":"2022-02-07T13:03:08.306904Z","shell.execute_reply.started":"2022-02-07T13:03:08.291089Z","shell.execute_reply":"2022-02-07T13:03:08.30619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create model","metadata":{"id":"I4h28SxejrZg","papermill":{"duration":0.135569,"end_time":"2022-02-03T06:59:56.784715","exception":false,"start_time":"2022-02-03T06:59:56.649146","status":"completed"},"tags":[]}},{"cell_type":"code","source":"model = tf.keras.Sequential([\n    base_model,\n    tf.keras.layers.MaxPooling2D(),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(len(Name), activation=\"softmax\")\n])","metadata":{"executionInfo":{"elapsed":13455,"status":"ok","timestamp":1617810483613,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"S9GL3TRYVSsD","papermill":{"duration":1.007879,"end_time":"2022-02-03T06:59:58.021288","exception":false,"start_time":"2022-02-03T06:59:57.013409","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:03:08.308067Z","iopub.execute_input":"2022-02-07T13:03:08.308261Z","iopub.status.idle":"2022-02-07T13:03:08.887447Z","shell.execute_reply.started":"2022-02-07T13:03:08.308237Z","shell.execute_reply":"2022-02-07T13:03:08.886616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"executionInfo":{"elapsed":6502,"status":"ok","timestamp":1617810483614,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"8uXDKmkInqMz","outputId":"97243ea3-adc4-4bc5-c987-b6c0d8b58629","papermill":{"duration":0.279014,"end_time":"2022-02-03T06:59:58.540444","exception":false,"start_time":"2022-02-03T06:59:58.26143","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:03:08.888549Z","iopub.execute_input":"2022-02-07T13:03:08.888752Z","iopub.status.idle":"2022-02-07T13:03:08.910155Z","shell.execute_reply.started":"2022-02-07T13:03:08.888726Z","shell.execute_reply":"2022-02-07T13:03:08.90771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Compile model","metadata":{"id":"uLCLa1t2j_UV","papermill":{"duration":0.136143,"end_time":"2022-02-03T06:59:58.903798","exception":false,"start_time":"2022-02-03T06:59:58.767655","status":"completed"},"tags":[]}},{"cell_type":"code","source":"model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate = 0.0001),\n              loss = tf.keras.losses.CategoricalCrossentropy(),\n              metrics = [tf.keras.metrics.CategoricalAccuracy()])","metadata":{"executionInfo":{"elapsed":737,"status":"ok","timestamp":1617810547219,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"Wj_KljwLVX6V","papermill":{"duration":0.161898,"end_time":"2022-02-03T06:59:59.203015","exception":false,"start_time":"2022-02-03T06:59:59.041117","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:03:08.911128Z","iopub.execute_input":"2022-02-07T13:03:08.911405Z","iopub.status.idle":"2022-02-07T13:03:08.936986Z","shell.execute_reply.started":"2022-02-07T13:03:08.911375Z","shell.execute_reply":"2022-02-07T13:03:08.936154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train the model","metadata":{"id":"aBcqCL3Nk-aD","papermill":{"duration":0.136231,"end_time":"2022-02-03T06:59:59.474564","exception":false,"start_time":"2022-02-03T06:59:59.338333","status":"completed"},"tags":[]}},{"cell_type":"code","source":"model.fit(img_generator_flow_train, \n          validation_data=img_generator_flow_valid, \n          steps_per_epoch=8, epochs=10)     #####","metadata":{"executionInfo":{"elapsed":1142617,"status":"ok","timestamp":1617811692118,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"Pb4XUVg5VZjJ","outputId":"902e32cb-d385-496c-bd4c-497081870948","papermill":{"duration":null,"end_time":null,"exception":false,"start_time":"2022-02-03T06:59:59.611834","status":"running"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:03:08.938098Z","iopub.execute_input":"2022-02-07T13:03:08.938358Z","iopub.status.idle":"2022-02-07T13:48:20.199638Z","shell.execute_reply.started":"2022-02-07T13:03:08.938291Z","shell.execute_reply":"2022-02-07T13:48:20.197379Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualize accuracy and loss","metadata":{"id":"ulgOch0WlLeh","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[]}},{"cell_type":"code","source":"# Visualise train / Valid Accuracy\nplt.plot(model.history.history[\"categorical_accuracy\"], c=\"r\", label=\"train_accuracy\")\nplt.plot(model.history.history[\"val_categorical_accuracy\"], c=\"b\", label=\"test_accuracy\")\nplt.legend(loc=\"upper left\")\nplt.show()","metadata":{"executionInfo":{"elapsed":662,"status":"ok","timestamp":1617813133811,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"Fr_xwcorg4qe","outputId":"48961f24-a93e-4361-d05f-e757c8ebb092","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:20.203824Z","iopub.execute_input":"2022-02-07T13:48:20.204551Z","iopub.status.idle":"2022-02-07T13:48:20.459702Z","shell.execute_reply.started":"2022-02-07T13:48:20.204493Z","shell.execute_reply":"2022-02-07T13:48:20.458124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualise train / Valid Loss\nplt.plot(model.history.history[\"loss\"], c=\"r\", label=\"train_loss\")\nplt.plot(model.history.history[\"val_loss\"], c=\"b\", label=\"test_loss\")\nplt.legend(loc=\"upper left\")\nplt.show()","metadata":{"executionInfo":{"elapsed":1134,"status":"ok","timestamp":1617813136938,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"HOsWwcEiX2gk","outputId":"0b086eed-f10c-43a4-cf21-ce58820a8a21","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:20.461564Z","iopub.execute_input":"2022-02-07T13:48:20.461933Z","iopub.status.idle":"2022-02-07T13:48:20.686399Z","shell.execute_reply.started":"2022-02-07T13:48:20.461885Z","shell.execute_reply":"2022-02-07T13:48:20.685746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Interpretation with Grad Cam\n","metadata":{"papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[]}},{"cell_type":"markdown","source":"## Create images and labels","metadata":{"id":"_pQhc-l2FNqx","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[]}},{"cell_type":"code","source":"imgs, labels = next(iter(img_generator_flow_valid))","metadata":{"executionInfo":{"elapsed":1217,"status":"ok","timestamp":1618246360869,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"lLplMCfeFf7R","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:20.687769Z","iopub.execute_input":"2022-02-07T13:48:20.688647Z","iopub.status.idle":"2022-02-07T13:48:22.816995Z","shell.execute_reply.started":"2022-02-07T13:48:20.688607Z","shell.execute_reply":"2022-02-07T13:48:22.816384Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(imgs.shape)\nprint(labels.shape)","metadata":{"execution":{"iopub.status.busy":"2022-02-07T13:48:22.818471Z","iopub.execute_input":"2022-02-07T13:48:22.819402Z","iopub.status.idle":"2022-02-07T13:48:22.825524Z","shell.execute_reply.started":"2022-02-07T13:48:22.819358Z","shell.execute_reply":"2022-02-07T13:48:22.824447Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for layer in model.layers:\n    print(layer.name)","metadata":{"executionInfo":{"elapsed":503,"status":"ok","timestamp":1618246456025,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"5V2mso_zALNz","outputId":"ec4e138c-5dfa-4a84-c805-a61f7c440326","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:22.826835Z","iopub.execute_input":"2022-02-07T13:48:22.827036Z","iopub.status.idle":"2022-02-07T13:48:22.838988Z","shell.execute_reply.started":"2022-02-07T13:48:22.827012Z","shell.execute_reply":"2022-02-07T13:48:22.838124Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = model.layers[0]","metadata":{"executionInfo":{"elapsed":503,"status":"ok","timestamp":1618246481805,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"6vRAshK7AWX4","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:22.841032Z","iopub.execute_input":"2022-02-07T13:48:22.841575Z","iopub.status.idle":"2022-02-07T13:48:22.848619Z","shell.execute_reply.started":"2022-02-07T13:48:22.84153Z","shell.execute_reply":"2022-02-07T13:48:22.847572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"last_conv_layer_name = \"mixed10\"\nclassifier_layer_names = [layer.name for layer in model.layers][1:]","metadata":{"executionInfo":{"elapsed":480,"status":"ok","timestamp":1618246519011,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"4dBZ-cwT__Q9","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:22.850786Z","iopub.execute_input":"2022-02-07T13:48:22.851107Z","iopub.status.idle":"2022-02-07T13:48:22.860914Z","shell.execute_reply.started":"2022-02-07T13:48:22.851065Z","shell.execute_reply":"2022-02-07T13:48:22.859833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# We start by setting up the dependencies we will use\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow import keras\n\n# Display\nfrom IPython.display import Image\nimport matplotlib.pyplot as plt\nimport matplotlib.cm as cm","metadata":{"executionInfo":{"elapsed":487,"status":"ok","timestamp":1618246522558,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"2MP08rJZK21C","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:22.86281Z","iopub.execute_input":"2022-02-07T13:48:22.863475Z","iopub.status.idle":"2022-02-07T13:48:22.87298Z","shell.execute_reply.started":"2022-02-07T13:48:22.863424Z","shell.execute_reply":"2022-02-07T13:48:22.872036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## make_gradcam_heatmap","metadata":{"papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[]}},{"cell_type":"code","source":"# The Grad-CAM algorithm\ndef get_img_array(img_path, size):\n    # `img` is a PIL image of size 299x299\n    img = keras.preprocessing.image.load_img(img_path, target_size=size)\n    # `array` is a float32 Numpy array of shape (299, 299, 3)\n    array = keras.preprocessing.image.img_to_array(img)\n    # We add a dimension to transform our array into a \"batch\"\n    # of size (1, 299, 299, 3)\n    array = np.expand_dims(array, axis=0)\n    return array\n\n\ndef make_gradcam_heatmap(\n    img_array, base_model, model, last_conv_layer_name, classifier_layer_names):\n    # First, we create a model that maps the input image to the activations\n    # of the last conv layer\n    last_conv_layer = base_model.get_layer(last_conv_layer_name)\n    last_conv_layer_model = keras.Model(base_model.inputs, last_conv_layer.output)\n\n    # Second, we create a model that maps the activations of the last conv\n    # layer to the final class predictions\n    classifier_input = keras.Input(shape=last_conv_layer.output.shape[1:])\n    x = classifier_input\n    for layer_name in classifier_layer_names:\n        x = model.get_layer(layer_name)(x)\n    classifier_model = keras.Model(classifier_input, x)\n\n    # Then, we compute the gradient of the top predicted class for our input image\n    # with respect to the activations of the last conv layer\n    with tf.GradientTape() as tape:\n        # Compute activations of the last conv layer and make the tape watch it\n        last_conv_layer_output = last_conv_layer_model(img_array)\n        tape.watch(last_conv_layer_output)\n        # Compute class predictions\n        preds = classifier_model(last_conv_layer_output)\n        top_pred_index = tf.argmax(preds[0])\n        top_class_channel = preds[:, top_pred_index]\n\n    # This is the gradient of the top predicted class with regard to\n    # the output feature map of the last conv layer\n    grads = tape.gradient(top_class_channel, last_conv_layer_output)\n\n    # This is a vector where each entry is the mean intensity of the gradient\n    # over a specific feature map channel\n    pooled_grads = tf.reduce_mean(grads, axis=(0, 1, 2))\n\n    # We multiply each channel in the feature map array\n    # by \"how important this channel is\" with regard to the top predicted class\n    last_conv_layer_output = last_conv_layer_output.numpy()[0]\n    pooled_grads = pooled_grads.numpy()\n    for i in range(pooled_grads.shape[-1]):\n        last_conv_layer_output[:, :, i] *= pooled_grads[i]\n\n    # The channel-wise mean of the resulting feature map\n    # is our heatmap of class activation\n    heatmap = np.mean(last_conv_layer_output, axis=-1)\n\n    # For visualization purpose, we will also normalize the heatmap between 0 & 1\n    heatmap = np.maximum(heatmap, 0) / np.max(heatmap)\n    return heatmap","metadata":{"executionInfo":{"elapsed":487,"status":"ok","timestamp":1618246524975,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"Kc0E2JuDHerF","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:22.875063Z","iopub.execute_input":"2022-02-07T13:48:22.876626Z","iopub.status.idle":"2022-02-07T13:48:22.898961Z","shell.execute_reply.started":"2022-02-07T13:48:22.876586Z","shell.execute_reply":"2022-02-07T13:48:22.897721Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predict valid data","metadata":{}},{"cell_type":"code","source":"# Print what the top predicted class is\npreds = model.predict(imgs) ##### 32\npred_labels = tf.argmax(preds, axis=-1) # +1\nprint(type(pred_labels))\npred_labels2=np.array(pred_labels)\nprint(type(pred_labels2))\nprint(pd.DataFrame(pred_labels2).value_counts())","metadata":{"execution":{"iopub.status.busy":"2022-02-07T13:48:22.90164Z","iopub.execute_input":"2022-02-07T13:48:22.902085Z","iopub.status.idle":"2022-02-07T13:48:26.5471Z","shell.execute_reply.started":"2022-02-07T13:48:22.902035Z","shell.execute_reply":"2022-02-07T13:48:26.546366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create heatmap","metadata":{"id":"WtpblKe7-uGq","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[]}},{"cell_type":"code","source":"# Generate class activation heatmap\nheatmaps = []\n\nfor img in imgs:\n    heatmap = make_gradcam_heatmap(\n    tf.expand_dims(img,axis=0),\n        base_model, model, \n        last_conv_layer_name, \n        classifier_layer_names\n  )\n    heatmaps.append(heatmap)\n\n# Display heatmap\nplt.matshow(heatmaps[0])\nplt.show()","metadata":{"executionInfo":{"elapsed":6373,"status":"ok","timestamp":1618247253746,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"2lBA5ugXIGcu","outputId":"fe900678-8a62-4262-fcaf-1f96f6c672d6","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:26.556256Z","iopub.execute_input":"2022-02-07T13:48:26.556846Z","iopub.status.idle":"2022-02-07T13:48:53.413143Z","shell.execute_reply.started":"2022-02-07T13:48:26.556791Z","shell.execute_reply":"2022-02-07T13:48:53.411608Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predicted label and heatmap","metadata":{"id":"yyCflQl4Bf3O","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[]}},{"cell_type":"code","source":"from pathlib import Path\n\nfor img, pred_label, true_label, heatmap in zip(imgs, pred_labels, labels, heatmaps): \n    # We rescale heatmap to a range 0-255\n    heatmap = np.uint8(255 * heatmap)\n\n    # We use jet colormap to colorize heatmap\n    jet = cm.get_cmap(\"jet\")\n\n    # We use RGB values of the colormap\n    jet_colors = jet(np.arange(256))[:, :3]\n    jet_heatmap = jet_colors[heatmap]\n\n    # We create an image with RGB colorized heatmap\n    jet_heatmap = keras.preprocessing.image.array_to_img(jet_heatmap)\n    jet_heatmap = jet_heatmap.resize((img.shape[1], img.shape[0]))\n    jet_heatmap = keras.preprocessing.image.img_to_array(jet_heatmap)\n\n    # Superimpose the heatmap on original image\n    superimposed_img = jet_heatmap * 0.003 + img\n    superimposed_img = keras.preprocessing.image.array_to_img(superimposed_img)\n\n    # Save the superimposed image\n    save_path = \"saved_img.jpg\"\n    superimposed_img.save(save_path)\n    \n    pred_label2=pred_label.numpy()\n    true_label2=np.argmax(true_label) # +1\n\n    print(\"Predicted Species: \",reverse_mapping[pred_label2])\n    print(\"Actual Species: \", reverse_mapping[true_label2])\n\n    display(Image(save_path))","metadata":{"executionInfo":{"elapsed":1899,"status":"ok","timestamp":1618247329229,"user":{"displayName":"Charles Tanguy","photoUrl":"","userId":"11930294859591867631"},"user_tz":-120},"id":"ApJvFBzOKGtH","outputId":"415818e7-2809-4dde-e4db-11df820448a3","papermill":{"duration":null,"end_time":null,"exception":null,"start_time":null,"status":"pending"},"tags":[],"execution":{"iopub.status.busy":"2022-02-07T13:48:53.548492Z","iopub.execute_input":"2022-02-07T13:48:53.548998Z","iopub.status.idle":"2022-02-07T13:48:53.979639Z","shell.execute_reply.started":"2022-02-07T13:48:53.548955Z","shell.execute_reply":"2022-02-07T13:48:53.978758Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Classification report","metadata":{}},{"cell_type":"code","source":"PRED=pred_labels2.tolist()","metadata":{"execution":{"iopub.status.busy":"2022-02-07T14:09:44.343243Z","iopub.execute_input":"2022-02-07T14:09:44.343722Z","iopub.status.idle":"2022-02-07T14:09:44.348526Z","shell.execute_reply.started":"2022-02-07T14:09:44.343673Z","shell.execute_reply":"2022-02-07T14:09:44.347628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LABEL=[]\nfor item in labels:   \n    LABEL+=[np.argmax(item)]","metadata":{"execution":{"iopub.status.busy":"2022-02-07T14:09:44.350164Z","iopub.execute_input":"2022-02-07T14:09:44.350538Z","iopub.status.idle":"2022-02-07T14:09:44.364326Z","shell.execute_reply.started":"2022-02-07T14:09:44.350502Z","shell.execute_reply":"2022-02-07T14:09:44.36358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(LABEL))\nprint(len(PRED))","metadata":{"execution":{"iopub.status.busy":"2022-02-07T14:09:44.365769Z","iopub.execute_input":"2022-02-07T14:09:44.366226Z","iopub.status.idle":"2022-02-07T14:09:44.381444Z","shell.execute_reply.started":"2022-02-07T14:09:44.366179Z","shell.execute_reply":"2022-02-07T14:09:44.380425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.metrics import classification_report\nprint(classification_report(LABEL,PRED))","metadata":{"execution":{"iopub.status.busy":"2022-02-07T14:09:44.384364Z","iopub.execute_input":"2022-02-07T14:09:44.384814Z","iopub.status.idle":"2022-02-07T14:09:46.145931Z","shell.execute_reply.started":"2022-02-07T14:09:44.384762Z","shell.execute_reply":"2022-02-07T14:09:46.14478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}