{"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":"!pip -q install tensorflow==2.3.0","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:40:55.868695Z","iopub.execute_input":"2022-03-09T09:40:55.869097Z","iopub.status.idle":"2022-03-09T09:41:02.523484Z","shell.execute_reply.started":"2022-03-09T09:40:55.869054Z","shell.execute_reply":"2022-03-09T09:41:02.52242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Basics / Data manipulation\nimport numpy as np\nimport pandas as pd\nfrom tqdm.notebook import tqdm\nimport zipfile\nimport os\n\n# Visualization\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport cv2\nimport skimage.io\n\n# ML\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom sklearn.model_selection import train_test_split\n\n%matplotlib inline","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:41:02.526562Z","iopub.execute_input":"2022-03-09T09:41:02.526803Z","iopub.status.idle":"2022-03-09T09:41:06.33842Z","shell.execute_reply.started":"2022-03-09T09:41:02.526774Z","shell.execute_reply":"2022-03-09T09:41:06.337697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data\n10k+ of .tiff images\n*    **80%** for training \n*    **20%** for internal testing\n            *  10% Validation\n            *  10% Testing","metadata":{"editable":false}},{"cell_type":"markdown","source":"# Checking if GPU is being used","metadata":{"editable":false}},{"cell_type":"markdown","source":"try:\n    tpu = tf.distribute.cluster_resolver.TPUClusterResolver()  # TPU detection\n    print(\"Running on TPU \", tpu.cluster_spec().as_dict()[\"worker\"])\n    tf.config.experimental_connect_to_cluster(tpu)\n    tf.tpu.experimental.initialize_tpu_system(tpu)\n    strategy = tf.distribute.experimental.TPUStrategy(tpu)\nexcept ValueError:\n    print(\"Not connected to a TPU runtime. Using CPU/GPU strategy\")\n    strategy = tf.distribute.MirroredStrategy()","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T03:51:55.28264Z","iopub.status.idle":"2022-03-09T03:51:55.283006Z","shell.execute_reply.started":"2022-03-09T03:51:55.282819Z","shell.execute_reply":"2022-03-09T03:51:55.282843Z"}}},{"cell_type":"markdown","source":"# Unzipping the images\nwith zipfile.ZipFile(\"../input/pc-data-dataset-gen/train.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"../input/pc-data-dataset-gen/validation.zip\",\"r\") as z:\n    z.extractall(\".\")\n    \nwith zipfile.ZipFile(\"../input/pc-data-dataset-gen/test.zip\",\"r\") as z:\n    z.extractall(\".\")","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-02-18T09:02:49.597315Z","iopub.execute_input":"2022-02-18T09:02:49.597824Z","iopub.status.idle":"2022-02-18T09:03:47.262421Z","shell.execute_reply.started":"2022-02-18T09:02:49.597785Z","shell.execute_reply":"2022-02-18T09:03:47.261456Z"}}},{"cell_type":"markdown","source":"# Set-up NASNetMobile","metadata":{"editable":false}},{"cell_type":"code","source":"from tensorflow.keras import models\nfrom tensorflow.keras import layers\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom sklearn import model_selection\nfrom tensorflow.keras import optimizers\n#Use this to check if the GPU is configured correctly\nfrom tensorflow.python.client import device_lib\nprint(device_lib.list_local_devices())\n\n\nfrom tensorflow.keras.applications import NASNetMobile","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:41:06.339818Z","iopub.execute_input":"2022-03-09T09:41:06.340115Z","iopub.status.idle":"2022-03-09T09:41:07.185198Z","shell.execute_reply.started":"2022-03-09T09:41:06.340078Z","shell.execute_reply":"2022-03-09T09:41:07.184181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.applications.efficientnet import EfficientNetB6\nconv_base = NASNetMobile(weights=\"imagenet\", include_top=False, input_shape=(224, 224, 3))","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:41:07.186651Z","iopub.execute_input":"2022-03-09T09:41:07.186947Z","iopub.status.idle":"2022-03-09T09:41:14.750876Z","shell.execute_reply.started":"2022-03-09T09:41:07.186909Z","shell.execute_reply":"2022-03-09T09:41:14.750102Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = models.Sequential()\nmodel.add(conv_base)\nmodel.add(layers.GlobalMaxPooling2D(name=\"gap\"))\n# Avoid overfitting\nmodel.add(layers.Dropout(rate=0.5))\nmodel.add(layers.Dense(10, activation=\"softmax\", name=\"fc_out\"))\nconv_base.trainable = True\n\nmodel.compile(\n    loss=\"categorical_crossentropy\",\n    optimizer=optimizers.RMSprop(lr=2e-5),\n    metrics=[\"acc\"],\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:41:14.752436Z","iopub.execute_input":"2022-03-09T09:41:14.752734Z","iopub.status.idle":"2022-03-09T09:41:18.493966Z","shell.execute_reply.started":"2022-03-09T09:41:14.752697Z","shell.execute_reply":"2022-03-09T09:41:18.493229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### CAUTION ###\n\nvariations = [\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\"]\n#variations = [\"A\", \"B\"]\n\ndef zippity(variant):\n    print(f'Variation {variant}')\n\n    with zipfile.ZipFile(f'../input/8-fold-pc-dataset-gen-{variations.index(variant) + 1}-8-{variant.lower()}/train{variant}.zip','r') as z:\n        z.extractall(\".\")\n    \n    with zipfile.ZipFile(f'../input/8-fold-pc-dataset-gen-{variations.index(variant) + 1}-8-{variant.lower()}/validation{variant}.zip','r') as z:\n        z.extractall(\".\")\n    \n    with zipfile.ZipFile(f'../input/8-fold-pc-dataset-gen-{variations.index(variant) + 1}-8-{variant.lower()}/test{variant}.zip',\"r\") as z:\n        z.extractall(\".\")","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:41:18.495301Z","iopub.execute_input":"2022-03-09T09:41:18.495586Z","iopub.status.idle":"2022-03-09T09:41:18.503352Z","shell.execute_reply.started":"2022-03-09T09:41:18.495551Z","shell.execute_reply":"2022-03-09T09:41:18.502443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def zappity():\n    # Deleting image folders to avoid over-saturate the output\n    !rm -r train\n    !rm -r validation\n#     !rm -r test","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:41:18.507093Z","iopub.execute_input":"2022-03-09T09:41:18.507544Z","iopub.status.idle":"2022-03-09T09:41:18.516261Z","shell.execute_reply.started":"2022-03-09T09:41:18.507503Z","shell.execute_reply":"2022-03-09T09:41:18.515489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":" image_gen = ImageDataGenerator(\n                                width_shift_range=0.1,\n                                height_shift_range=0.1,\n                                rescale=1/255,\n                                shear_range=0.2,\n                                zoom_range=0.2,\n                                horizontal_flip=True,\n                                fill_mode=\"nearest\"\n                                )","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:41:18.518327Z","iopub.execute_input":"2022-03-09T09:41:18.518792Z","iopub.status.idle":"2022-03-09T09:41:18.526785Z","shell.execute_reply.started":"2022-03-09T09:41:18.518753Z","shell.execute_reply":"2022-03-09T09:41:18.526058Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"from tensorflow.keras.applications import EfficientNetB6\nfrom keras.layers import Dense\nconv_base = tensorflow.keras.applications.efficientnet.EfficientNetB6(weights=\"imagenet\", include_top=False, input_shape=(224, 224, 3))","metadata":{}},{"cell_type":"markdown","source":"# Configuration of the NASNetMobile\nconv_base = NASNetMobile(weights=\"imagenet\", include_top=False, input_shape=(224, 224, 3))","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-02-15T17:03:43.434442Z","iopub.execute_input":"2022-02-15T17:03:43.434873Z","iopub.status.idle":"2022-02-15T17:03:51.729574Z","shell.execute_reply.started":"2022-02-15T17:03:43.434836Z","shell.execute_reply":"2022-02-15T17:03:51.728841Z"}}},{"cell_type":"markdown","source":"# Model \nThe model will have the follow configuration:\n______________\n1st layer: NASNetMobile (224, 224, 3) input images\n______________\n2nd layer: GlobalMaxPooling2D\n______________\n3rd layer: Dropout with learning rate = 2e-5\n______________\n4th layer: Denser layer x 6 that will classify the image","metadata":{"editable":false}},{"cell_type":"code","source":"model.summary()","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:41:18.530273Z","iopub.execute_input":"2022-03-09T09:41:18.530599Z","iopub.status.idle":"2022-03-09T09:41:18.614847Z","shell.execute_reply.started":"2022-03-09T09:41:18.530565Z","shell.execute_reply":"2022-03-09T09:41:18.614201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Augmentation\n\nBefore training, we preprocess a little bit the image, in order to have a better perfomance on the predictions","metadata":{"editable":false}},{"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:41:18.616999Z","iopub.execute_input":"2022-03-09T09:41:18.617485Z","iopub.status.idle":"2022-03-09T09:41:18.621951Z","shell.execute_reply.started":"2022-03-09T09:41:18.617436Z","shell.execute_reply":"2022-03-09T09:41:18.62109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"batch_size = 32\n\ndef which_image_gen(which):\n    if(which == \"train\"):\n        which_gen = image_gen.flow_from_directory(\"./train\",\n                                                  target_size=(224, 224),\n                                                  batch_size=batch_size,\n                                                  class_mode=\"categorical\")\n        \n    \n    elif(which == \"valid\"):\n        which_gen = image_gen.flow_from_directory(\"./validation\",\n                                                  target_size=(224, 224),\n                                                  batch_size=batch_size,\n                                                  class_mode=\"categorical\")\n    \n    elif(which == \"test\"):\n        which_gen = image_gen.flow_from_directory(\"./test\",\n                                                  target_size=(224, 224),\n                                                  batch_size=batch_size,\n                                                  class_mode=\"categorical\")\n    return which_gen","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:41:18.623346Z","iopub.execute_input":"2022-03-09T09:41:18.62378Z","iopub.status.idle":"2022-03-09T09:41:18.632353Z","shell.execute_reply.started":"2022-03-09T09:41:18.623741Z","shell.execute_reply":"2022-03-09T09:41:18.631603Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for variety in variations:\n    zippity(variety)\n    \n    train_image_gen = which_image_gen(\"train\")\n    validation_image_gen = which_image_gen(\"valid\")\n    test_image_gen = which_image_gen(\"test\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Flowing through directories to see the classes and the number of images\nprint(image_gen.flow_from_directory(\"./train\"))\nprint(image_gen.flow_from_directory(\"./validation\"))\nprint(image_gen.flow_from_directory(\"./test\"))","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T07:52:29.199811Z","iopub.execute_input":"2022-03-09T07:52:29.200638Z","iopub.status.idle":"2022-03-09T07:52:29.646888Z","shell.execute_reply.started":"2022-03-09T07:52:29.200588Z","shell.execute_reply":"2022-03-09T07:52:29.645164Z"}}},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"train_image_gen.class_indices\nvalidation_image_gen.class_indices\ntest_image_gen.class_indices","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T08:43:14.532063Z","iopub.execute_input":"2022-03-09T08:43:14.532363Z","iopub.status.idle":"2022-03-09T08:43:14.960377Z","shell.execute_reply.started":"2022-03-09T08:43:14.532319Z","shell.execute_reply":"2022-03-09T08:43:14.959203Z"}}},{"cell_type":"code","source":"NUMBER_OF_TRAINING_IMAGES = len(pd.read_csv('../input/8-fold-pc-dataset-gen-0-8/training.csv'))\nNUMBER_OF_VALIDATION_IMAGES = len(pd.read_csv('../input/8-fold-pc-dataset-gen-0-8/validation.csv'))\nNUMBER_OF_TESTING_IMAGES = len(pd.read_csv('../input/8-fold-pc-dataset-gen-0-8/testing.csv'))","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:45:07.688663Z","iopub.status.idle":"2022-03-09T09:45:07.689309Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for variety in variations:\n#     zippity(variety)\n    \n#     train_image_gen = which_image_gen(\"train\")\n#     validation_image_gen = which_image_gen(\"valid\")\n    ","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:45:07.690469Z","iopub.status.idle":"2022-03-09T09:45:07.691071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"results = model.fit(\n    train_image_gen,\n    steps_per_epoch=NUMBER_OF_TRAINING_IMAGES // batch_size,\n    epochs=100,\n    validation_data=validation_image_gen,\n    validation_steps=NUMBER_OF_VALIDATION_IMAGES // batch_size,\n    verbose=1,\n    use_multiprocessing=True,\n    workers=4,\n)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-02-18T08:17:27.648072Z","iopub.execute_input":"2022-02-18T08:17:27.648407Z","iopub.status.idle":"2022-02-18T08:18:31.211154Z","shell.execute_reply.started":"2022-02-18T08:17:27.648364Z","shell.execute_reply":"2022-02-18T08:18:31.209079Z"}}},{"cell_type":"code","source":"results = model.fit(\n    train_image_gen,\n    steps_per_epoch=NUMBER_OF_TRAINING_IMAGES // batch_size,\n    epochs=30,\n    validation_data=validation_image_gen,\n    validation_steps=NUMBER_OF_VALIDATION_IMAGES // batch_size,\n    verbose=1,\n    use_multiprocessing=True,\n    workers=4,\n)","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:45:07.692178Z","iopub.status.idle":"2022-03-09T09:45:07.692744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Saving the synaptic weights of the model\nmodel.save(\"./NASNetMobile-model.h5\")","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:45:07.693811Z","iopub.status.idle":"2022-03-09T09:45:07.694399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# zappity()","metadata":{"execution":{"iopub.status.busy":"2022-03-09T09:45:07.695463Z","iopub.status.idle":"2022-03-09T09:45:07.696109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"results_df = pd.DataFrame({\"epoch\":[i + 1 for i in range(len(results.history[\"acc\"]))], \"acc\":results.history[\"acc\"], \"val_acc\":results.history[\"val_acc\"], \"loss\":results.history[\"loss\"], \"val_loss\":results.history[\"val_loss\"]})\nresults_df","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:45:07.697352Z","iopub.status.idle":"2022-03-09T09:45:07.697975Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_hist_acc(hist):\n    plt.plot(hist.history[\"acc\"])\n    plt.plot(hist.history[\"val_acc\"])\n    plt.title(\"Model Accuracy\")\n    plt.ylabel(\"Accuracy\")\n    plt.xlabel(\"Epoch\")\n    plt.legend([\"Accuracy\", \"Validation Accuracy\"], loc=\"upper left\")\n    plt.show()\n\nplot_hist_acc(results)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:45:07.699123Z","iopub.status.idle":"2022-03-09T09:45:07.699693Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_hist_loss(hist):\n    plt.plot(hist.history[\"loss\"])\n    plt.plot(hist.history[\"val_loss\"])\n    plt.title(\"Model Loss\")\n    plt.ylabel(\"Accuracy\")\n    plt.xlabel(\"Epoch\")\n    plt.legend([\"Loss\", \"Validation Loss\"], loc=\"upper left\")\n    plt.show()\n\nplot_hist_loss(results)","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:45:07.700776Z","iopub.status.idle":"2022-03-09T09:45:07.701364Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Testing","metadata":{"editable":false}},{"cell_type":"markdown","source":"from sklearn.metrics import confusion_matrix, classification_report\n","metadata":{"editable":false}},{"cell_type":"markdown","source":"test_generator = ImageDataGenerator()\ntest_data_generator = test_generator.flow_from_directory(\n    \"./test\", # Put your path here\n    target_size=(224, 224),\n    batch_size=32,\n    shuffle=False)\ntest_steps_per_epoch = np.math.ceil(test_data_generator.samples / test_data_generator.batch_size)\n\npredictions = model.predict_generator(test_data_generator, steps=test_steps_per_epoch)\n# Get most likely class\npredicted_classes = np.argmax(predictions, axis=1)","metadata":{"editable":false}},{"cell_type":"markdown","source":"true_classes = test_data_generator.classes\nclass_labels = list(test_data_generator.class_indices.keys())   ","metadata":{"editable":false}},{"cell_type":"markdown","source":"report = classification_report(true_classes, predicted_classes, target_names=class_labels)\nprint(report)   ","metadata":{"editable":false}},{"cell_type":"code","source":"# Deleting image folders to avoid over-saturate the output\n!rm -r train\n!rm -r validation\n!rm -r test","metadata":{"editable":false,"execution":{"iopub.status.busy":"2022-03-09T09:45:07.70243Z","iopub.status.idle":"2022-03-09T09:45:07.703009Z"},"trusted":true},"execution_count":null,"outputs":[]}]}