{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":63134,"databundleVersionId":6880857,"sourceType":"competition"}],"dockerImageVersionId":30588,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Common\nimport os\nimport numpy as np \nimport pandas as pd\nfrom glob import glob\nimport tensorflow as tf\nimport tensorflow_hub as hub\nfrom IPython.display import clear_output as cls\n\n# Data \nfrom tensorflow.keras.utils import load_img, img_to_array\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# Data Visualization\nimport plotly.express as px\nimport matplotlib.pyplot as plt\n\n# Model \nfrom keras.models import Sequential, load_model\nfrom keras.layers import GlobalAvgPool2D as GAP, Dense, Dropout\n\n# Callbacks \nfrom keras.callbacks import EarlyStopping, ModelCheckpoint\n\n# Pre-Trained Model\nfrom tensorflow.keras.applications import ResNet50V2","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:10.992465Z","iopub.execute_input":"2023-11-21T18:47:10.992762Z","iopub.status.idle":"2023-11-21T18:47:24.023825Z","shell.execute_reply.started":"2023-11-21T18:47:10.992736Z","shell.execute_reply":"2023-11-21T18:47:24.022865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import random\nimport os\nimport glob\nimport time\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport plotly.express as px\n\nimport seaborn as sns\n\nimport tensorflow as tf\nimport tensorflow_hub as hub\nfrom tensorflow.keras import layers, Sequential\nfrom tensorflow.keras.utils import plot_model\n\nfrom sklearn.preprocessing import LabelEncoder\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import classification_report, precision_recall_fscore_support\nfrom sklearn.metrics import accuracy_score, top_k_accuracy_score, f1_score, matthews_corrcoef\nfrom sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay\nfrom scikitplot.metrics import plot_roc","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:24.025428Z","iopub.execute_input":"2023-11-21T18:47:24.025987Z","iopub.status.idle":"2023-11-21T18:47:24.676257Z","shell.execute_reply.started":"2023-11-21T18:47:24.025958Z","shell.execute_reply":"2023-11-21T18:47:24.675125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nEPOCHS = 50\nBATCH_SIZE = 32\nSEED = 42\nTF_SEED = 768\nHEIGHT = 224\nWIDTH = 224\nCHANNELS = 3\nIMAGE_SIZE = (224, 224, 3)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:24.677625Z","iopub.execute_input":"2023-11-21T18:47:24.677992Z","iopub.status.idle":"2023-11-21T18:47:24.683195Z","shell.execute_reply.started":"2023-11-21T18:47:24.677956Z","shell.execute_reply":"2023-11-21T18:47:24.681995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATASET_PATH = \"/kaggle/input/anyas-gojo-revival-aerospace-enigma/train\"\n\ntrain_path = '/kaggle/input/anyas-gojo-revival-aerospace-enigma/train/'\ntest_path = '/kaggle/input/anyas-gojo-revival-aerospace-enigma/test/'\n\nclass_names = sorted(os.listdir(train_path))\nn_classes = len(class_names)\n\n# Class Distribution\nclass_dis = [len(os.listdir(train_path + name)) for name in class_names]\n\n# Show\nprint(f\"Total Number of Classes : {n_classes} \\nClass Names : {class_names}\")","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:24.685933Z","iopub.execute_input":"2023-11-21T18:47:24.686411Z","iopub.status.idle":"2023-11-21T18:47:25.129161Z","shell.execute_reply.started":"2023-11-21T18:47:24.686384Z","shell.execute_reply":"2023-11-21T18:47:25.128140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig = px.pie(names=class_names, values=class_dis, title=\"Training Class Distribution\", hole=0.4)\nfig.update_layout({'title':{'x':0.48}})\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:25.130319Z","iopub.execute_input":"2023-11-21T18:47:25.130605Z","iopub.status.idle":"2023-11-21T18:47:26.555550Z","shell.execute_reply.started":"2023-11-21T18:47:25.130578Z","shell.execute_reply":"2023-11-21T18:47:26.554655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def _load(image_path):\n    # Read and decode an image file to a uint8 tensor\n    image = tf.io.read_file(image_path)\n    image = tf.io.decode_jpeg(image, channels=3)\n\n    # Resize image\n    image = tf.image.resize(image, [CFG.HEIGHT, CFG.WIDTH],\n                            method=tf.image.ResizeMethod.LANCZOS3)\n\n    # Convert image dtype to float32 and NORMALIZE!!!\n    image = tf.cast(image, tf.float32)/255.\n\n    # Return image\n    return image\n\ndef view_sample(image, label, color_map='gray', fig_size=(8, 10)):\n    plt.figure(figsize=fig_size)\n    plt.imshow(tf.image.rgb_to_grayscale(image), cmap=color_map)\n    plt.title(f'Label: {label}', fontsize=16)\n    return","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:26.556873Z","iopub.execute_input":"2023-11-21T18:47:26.557174Z","iopub.status.idle":"2023-11-21T18:47:26.563937Z","shell.execute_reply.started":"2023-11-21T18:47:26.557149Z","shell.execute_reply":"2023-11-21T18:47:26.562900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Visualize \nfig = px.bar(x=class_names, y=class_dis, title=\"Training Class Distribution\", color=class_names)\nfig.update_layout({'title':{'x':0.48}})\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:26.565110Z","iopub.execute_input":"2023-11-21T18:47:26.565831Z","iopub.status.idle":"2023-11-21T18:47:26.696365Z","shell.execute_reply.started":"2023-11-21T18:47:26.565757Z","shell.execute_reply":"2023-11-21T18:47:26.695403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# !rm /kaggle/working/data -r","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:26.697501Z","iopub.execute_input":"2023-11-21T18:47:26.697745Z","iopub.status.idle":"2023-11-21T18:47:26.701656Z","shell.execute_reply.started":"2023-11-21T18:47:26.697723Z","shell.execute_reply":"2023-11-21T18:47:26.700727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install split-folders","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:26.702971Z","iopub.execute_input":"2023-11-21T18:47:26.703306Z","iopub.status.idle":"2023-11-21T18:47:39.407911Z","shell.execute_reply.started":"2023-11-21T18:47:26.703282Z","shell.execute_reply":"2023-11-21T18:47:39.406740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import splitfolders\nsplitfolders.ratio('/kaggle/input/anyas-gojo-revival-aerospace-enigma/train', output=\"data\", seed=1337, ratio=(.80, 0.20)) ","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:39.411698Z","iopub.execute_input":"2023-11-21T18:47:39.412017Z","iopub.status.idle":"2023-11-21T18:47:50.751686Z","shell.execute_reply.started":"2023-11-21T18:47:39.411991Z","shell.execute_reply":"2023-11-21T18:47:50.750810Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import load_img, img_to_array\nfrom keras.preprocessing.image import ImageDataGenerator\n\n# Initialize Generator\ntrain_gen = ImageDataGenerator(rescale=1/255., rotation_range=10, horizontal_flip=True)\nvalid_gen = ImageDataGenerator(rescale=1/255.)\ntest_gen = ImageDataGenerator(rescale=1/255)\n\n# # Load Data\ntrain_path = \"/kaggle/input/anyas-gojo-revival-aerospace-enigma/train\"\nvalid_path = \"/kaggle/working/data/val\"\ntrain_ds = train_gen.flow_from_directory(train_path, class_mode='binary', target_size=(224,224), shuffle=True, batch_size=32) \nvalid_ds = valid_gen.flow_from_directory(valid_path, class_mode='binary', target_size=(224,224), shuffle=True, batch_size=32) \n","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:47:50.752953Z","iopub.execute_input":"2023-11-21T18:47:50.753263Z","iopub.status.idle":"2023-11-21T18:47:50.862943Z","shell.execute_reply.started":"2023-11-21T18:47:50.753234Z","shell.execute_reply":"2023-11-21T18:47:50.862211Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# # Build augmentation layer\n# augmentation_layer = Sequential([\n#     layers.RandomFlip(mode='horizontal_and_vertical', seed=CFG.TF_SEED),\n#     layers.RandomZoom(height_factor=(-0.1, 0.1), width_factor=(-0.1, 0.1), seed=CFG.TF_SEED),\n# ], name='augmentation_layer')","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:48:07.076817Z","iopub.execute_input":"2023-11-21T18:48:07.077235Z","iopub.status.idle":"2023-11-21T18:48:07.081885Z","shell.execute_reply.started":"2023-11-21T18:48:07.077200Z","shell.execute_reply":"2023-11-21T18:48:07.080874Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def show_images(GRID=[5,5], model=None, size=(20,20), data=train_ds):\n    n_rows = GRID[0]\n    n_cols = GRID[1]\n    n_images = n_cols * n_rows\n    \n    i = 1\n    plt.figure(figsize=size)\n    for images, labels in data:\n        id = np.random.randint(len(images))\n        image, label = images[id], class_names[int(labels[id])]\n        \n        plt.subplot(n_rows, n_cols, i)\n        plt.imshow(image)\n        \n        if model is None:\n            title = f\"Class : {label}\"\n        else:\n            pred = class_names[int(np.argmax(model.predict(image[np.newaxis, ...])))]\n            title = f\"Org : {label}, Pred : {pred}\"\n            cls()\n        \n        plt.title(title)\n        plt.axis('off')\n        \n        i+=1\n        if i>=(n_images+1):\n            break\n            \n    plt.tight_layout()\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:48:09.632452Z","iopub.execute_input":"2023-11-21T18:48:09.632823Z","iopub.status.idle":"2023-11-21T18:48:09.641778Z","shell.execute_reply.started":"2023-11-21T18:48:09.632792Z","shell.execute_reply":"2023-11-21T18:48:09.640870Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_image(path):\n    '''This function will load the image present at the given location'''\n    image = tf.cast(tf.image.resize(img_to_array(load_img(path))/255., (256,256)), tf.float32)\n    return image\ndef show_image(image, title=None):\n    plt.imshow(image)\n    plt.axis('off')\n    plt.title(title)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:48:10.163648Z","iopub.execute_input":"2023-11-21T18:48:10.164380Z","iopub.status.idle":"2023-11-21T18:48:10.169987Z","shell.execute_reply.started":"2023-11-21T18:48:10.164347Z","shell.execute_reply":"2023-11-21T18:48:10.169090Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_images(data=train_ds)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:48:10.567901Z","iopub.execute_input":"2023-11-21T18:48:10.568295Z","iopub.status.idle":"2023-11-21T18:48:27.188033Z","shell.execute_reply.started":"2023-11-21T18:48:10.568262Z","shell.execute_reply":"2023-11-21T18:48:27.186827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bit_model_url = \"https://tfhub.dev/google/bit/m-r50x1/1\"\nbit_module = hub.KerasLayer(bit_model_url)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:48:27.190075Z","iopub.execute_input":"2023-11-21T18:48:27.190551Z","iopub.status.idle":"2023-11-21T18:49:03.596050Z","shell.execute_reply.started":"2023-11-21T18:48:27.190505Z","shell.execute_reply":"2023-11-21T18:49:03.595285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = Sequential([\n    bit_module,\n    Dense(n_classes, activation='softmax', kernel_initializer='zeros')\n], name='bit-custom')","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:49:03.597225Z","iopub.execute_input":"2023-11-21T18:49:03.597525Z","iopub.status.idle":"2023-11-21T18:49:03.613730Z","shell.execute_reply.started":"2023-11-21T18:49:03.597499Z","shell.execute_reply":"2023-11-21T18:49:03.612823Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 32\nlr = 1e-3 * BATCH_SIZE/512\nprint(f\"Learning rate : {lr}\")","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:49:03.616249Z","iopub.execute_input":"2023-11-21T18:49:03.616535Z","iopub.status.idle":"2023-11-21T18:49:03.625239Z","shell.execute_reply.started":"2023-11-21T18:49:03.616511Z","shell.execute_reply":"2023-11-21T18:49:03.624323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SCHEDULE_BOUNDARIES = [\n    200,\n    300,\n    400,\n] ","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:49:03.626314Z","iopub.execute_input":"2023-11-21T18:49:03.626581Z","iopub.status.idle":"2023-11-21T18:49:03.636220Z","shell.execute_reply.started":"2023-11-21T18:49:03.626557Z","shell.execute_reply":"2023-11-21T18:49:03.635409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lr_schedule = tf.keras.optimizers.schedules.PiecewiseConstantDecay(\n    boundaries=SCHEDULE_BOUNDARIES,\n    values=[\n        lr,\n        lr * 0.1,\n        lr * 0.01,\n        lr * 0.001,\n    ],\n)\noptimizer = tf.keras.optimizers.SGD(learning_rate=lr_schedule, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:49:03.637349Z","iopub.execute_input":"2023-11-21T18:49:03.637624Z","iopub.status.idle":"2023-11-21T18:49:03.695963Z","shell.execute_reply.started":"2023-11-21T18:49:03.637601Z","shell.execute_reply":"2023-11-21T18:49:03.695163Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    loss='sparse_categorical_crossentropy',\n    optimizer=optimizer,\n    metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:49:40.433154Z","iopub.execute_input":"2023-11-21T18:49:40.434054Z","iopub.status.idle":"2023-11-21T18:49:40.450069Z","shell.execute_reply.started":"2023-11-21T18:49:40.434019Z","shell.execute_reply":"2023-11-21T18:49:40.449131Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cbs = [EarlyStopping(patience=5, restore_best_weights=True), ModelCheckpoint('bit-custom.h5', save_best_only=True)]","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:49:52.093324Z","iopub.execute_input":"2023-11-21T18:49:52.093676Z","iopub.status.idle":"2023-11-21T18:49:52.098746Z","shell.execute_reply.started":"2023-11-21T18:49:52.093650Z","shell.execute_reply":"2023-11-21T18:49:52.097606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nhistory = model.fit(train_ds, validation_data=valid_ds, epochs=25, callbacks=cbs)\n","metadata":{"execution":{"iopub.status.busy":"2023-11-21T18:50:00.891985Z","iopub.execute_input":"2023-11-21T18:50:00.892477Z","iopub.status.idle":"2023-11-21T19:11:31.021513Z","shell.execute_reply.started":"2023-11-21T18:50:00.892438Z","shell.execute_reply":"2023-11-21T19:11:31.020418Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame(history.history).plot(figsize=(8,5))\nplt.grid()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:11:31.023587Z","iopub.execute_input":"2023-11-21T19:11:31.023888Z","iopub.status.idle":"2023-11-21T19:11:31.268577Z","shell.execute_reply.started":"2023-11-21T19:11:31.023863Z","shell.execute_reply":"2023-11-21T19:11:31.267683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"path=\"/kaggle/input/anyas-gojo-revival-aerospace-enigma/test\"\nans={}\nfor file in os.listdir(path):\n  val=os.path.splitext(file)[0]\n  test_image=tf.keras.utils.load_img(path+'/'+file,target_size=(256,256))\n  test_image=tf.keras.utils.img_to_array(test_image)\n  test_image=np.expand_dims(test_image,axis=0)\n  pred=model.predict(test_image)\n  output_class=class_names[np.argmax(pred)]\n  ans[file]=output_class","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:11:31.270178Z","iopub.execute_input":"2023-11-21T19:11:31.270525Z","iopub.status.idle":"2023-11-21T19:11:56.236187Z","shell.execute_reply.started":"2023-11-21T19:11:31.270498Z","shell.execute_reply":"2023-11-21T19:11:56.235404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\ndf= pd.DataFrame([ans.keys(), ans.values()]).T\ndf.columns= ['image_path', 'Class']\n\ndf.set_index('image_path', inplace=True)\n\ndf.to_csv('output.csv')","metadata":{"execution":{"iopub.status.busy":"2023-11-21T19:11:56.238337Z","iopub.execute_input":"2023-11-21T19:11:56.238689Z","iopub.status.idle":"2023-11-21T19:11:56.260280Z","shell.execute_reply.started":"2023-11-21T19:11:56.238657Z","shell.execute_reply":"2023-11-21T19:11:56.259334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}