{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":65471,"databundleVersionId":7211464,"sourceType":"competition"}],"dockerImageVersionId":30626,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os \nos.environ['KERAS_BACKEND'] = 'tensorflow'\n# Math\nimport numpy as np \n# NN Buiding\nimport tensorflow as tf \nfrom tensorflow.keras.layers import (Input, \n                                     Conv2D, \n                                     MaxPooling2D, \n                                     Flatten, \n                                     Dense, \n                                     BatchNormalization, \n#                                      InstanceNormalization\n                                    )\nfrom tensorflow.data import Dataset\nfrom tensorflow.keras.callbacks import EarlyStopping, LearningRateScheduler, ModelCheckpoint\nfrom tensorflow.keras.metrics import Accuracy, Precision, Recall, AUC\n# Augmentation\n\n\n# Visualization \nimport matplotlib.pyplot as plt ","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-15T18:15:13.606997Z","iopub.execute_input":"2023-12-15T18:15:13.607565Z","iopub.status.idle":"2023-12-15T18:15:27.196035Z","shell.execute_reply.started":"2023-12-15T18:15:13.607531Z","shell.execute_reply":"2023-12-15T18:15:27.194545Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load Dataset","metadata":{}},{"cell_type":"code","source":"IMAGE_SHAPE = [100, 100, 1]\nNUM_CLASSES = 65 ","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:16:32.388646Z","iopub.execute_input":"2023-12-15T18:16:32.389018Z","iopub.status.idle":"2023-12-15T18:16:32.395228Z","shell.execute_reply.started":"2023-12-15T18:16:32.388986Z","shell.execute_reply":"2023-12-15T18:16:32.393463Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_filepaths_labels(folder_path):\n    file_paths = []\n    labels = []\n\n    # List all directories (labels) in the given folder\n    for label in os.listdir(folder_path):\n        label_path = os.path.join(folder_path, label)\n\n        # Check if the item in the directory is a subdirectory\n        if os.path.isdir(label_path):\n            # List all files in the subdirectory\n            files = os.listdir(label_path)\n            \n            # Create file paths and corresponding labels\n            file_paths.extend([os.path.join(label_path, file) for file in files])\n            labels.extend([int(label)] * len(files))\n\n    return file_paths, labels","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:16:33.354051Z","iopub.execute_input":"2023-12-15T18:16:33.354473Z","iopub.status.idle":"2023-12-15T18:16:33.362543Z","shell.execute_reply.started":"2023-12-15T18:16:33.354441Z","shell.execute_reply":"2023-12-15T18:16:33.360526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_decode_image(filepath, label):\n    # One-hot encoding the label\n    label = tf.one_hot(label, depth=NUM_CLASSES)\n\n    # Read and decode the image\n    image = tf.io.read_file(filepath)\n    image = tf.image.decode_image(image, channels=IMAGE_SHAPE[-1])\n    image = image * -1\n\n    image = tf.image.convert_image_dtype(image, tf.float32)\n    \n    # Normalize the image\n    # Resize the image while maintaining aspect ratio\n    image = tf.image.resize_with_pad(image, target_height=IMAGE_SHAPE[0], target_width=IMAGE_SHAPE[1], method = 'bicubic')\n\n    return image, label\n\ndef build_dataset(filepaths, labels, batch_size = 8, shuffle = True, prefetch = True): \n    \n    dataset = tf.data.Dataset.from_tensor_slices((filepaths, labels))\n    \n    dataset = dataset.map(lambda x, y: load_decode_image(x, y))\n    dataset = dataset.batch(batch_size)\n    \n    if shuffle: \n        dataset = dataset.shuffle(2)\n        \n    if prefetch: \n        dataset = dataset.prefetch(tf.data.AUTOTUNE)\n        \n    return dataset  ","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:16:34.381845Z","iopub.execute_input":"2023-12-15T18:16:34.382269Z","iopub.status.idle":"2023-12-15T18:16:34.392045Z","shell.execute_reply.started":"2023-12-15T18:16:34.382238Z","shell.execute_reply":"2023-12-15T18:16:34.390001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build Model","metadata":{}},{"cell_type":"code","source":"def enc_bl(n_filters, strides=2, bnorm=True) -> tf.keras.Model: \n    # Convolutional block with optional batch normalization\n    \n    # Convolutional layer with kernel size 2 and specified number of filters\n    # Use 'strides' instead of 'stribes' (typo) and specify padding='same'\n    conv_init = tf.keras.initializers.RandomNormal(mean=0.0, stddev=0.2)\n    head = tf.keras.Sequential([\n        Conv2D(n_filters, kernel_size=2, strides=1, padding='same', bias_initializer=conv_init), \n        MaxPooling2D(2, strides=strides)  # Corrected 'stribes' to 'strides'\n    ])\n    \n    if bnorm: \n        head.add(BatchNormalization())\n        \n    return head","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:16:36.105798Z","iopub.execute_input":"2023-12-15T18:16:36.106201Z","iopub.status.idle":"2023-12-15T18:16:36.114038Z","shell.execute_reply.started":"2023-12-15T18:16:36.106168Z","shell.execute_reply":"2023-12-15T18:16:36.112560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# inputs shape = [None, 256, 256, 1]\ndef build_model(inputs_shape, num_classes = 65) -> tf.keras.Model: \n    inputs = Input(shape = inputs_shape)\n    \n    x = enc_bl(16)(inputs) #    [None, 100, 100, 16]\n    x = enc_bl(32)(x) # shape : [None, 50, 50, 32]\n    x = enc_bl(64)(x) # shape : [None, 25, 25, 64] \n    x = enc_bl(128, strides = 5)(x) # [None, 5, 5, 128]\n    \n    x = Flatten()(x)\n    outputs = Dense(units = num_classes, activation='softmax')(x)\n    \n    return tf.keras.Model(inputs, outputs)","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:16:56.071965Z","iopub.execute_input":"2023-12-15T18:16:56.072338Z","iopub.status.idle":"2023-12-15T18:16:56.078690Z","shell.execute_reply.started":"2023-12-15T18:16:56.072307Z","shell.execute_reply":"2023-12-15T18:16:56.077723Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fileps, labels = load_filepaths_labels('/kaggle/input/arabic-letters-classification/Final_Arabic_Alpha_dataset/Final_Arabic_Alpha_dataset/train')\n\ndataset = build_dataset(fileps, labels, batch_size = 512, shuffle = False)\n\nmodel = build_model(IMAGE_SHAPE, 65)","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:16:59.100428Z","iopub.execute_input":"2023-12-15T18:16:59.100826Z","iopub.status.idle":"2023-12-15T18:16:59.683608Z","shell.execute_reply.started":"2023-12-15T18:16:59.100788Z","shell.execute_reply":"2023-12-15T18:16:59.682278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Use AdamW optimizer\noptimizer = tf.keras.optimizers.AdamW(learning_rate=1e-6)\n\n# Use more metrics\nmetrics = [Accuracy()]\n\n# Compile the model\nmodel.compile(optimizer=optimizer, loss='binary_crossentropy')\n\n# Define callbacks\n# early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)\nlr_scheduler = LearningRateScheduler(lambda epoch: 1e-6 * 0.9**epoch)\nmodel_checkpoint = ModelCheckpoint('best_model.h5', monitor='val_accuracy', save_best_only=True)\n# Add any other callbacks you may need\n\n\n# Train the model\nmodel.fit(dataset, \n          epochs=50,\n#           steps_per_epoch = 5, \n#           validation_data=val_dataset, \n          callbacks=[lr_scheduler, model_checkpoint]\n         )","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:17:06.644875Z","iopub.execute_input":"2023-12-15T18:17:06.645981Z","iopub.status.idle":"2023-12-15T18:17:18.485215Z","shell.execute_reply.started":"2023-12-15T18:17:06.645905Z","shell.execute_reply":"2023-12-15T18:17:18.483792Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.save('/kaggle/working/')","metadata":{"execution":{"iopub.status.busy":"2023-12-15T18:15:43.259958Z","iopub.status.idle":"2023-12-15T18:15:43.260372Z","shell.execute_reply.started":"2023-12-15T18:15:43.260201Z","shell.execute_reply":"2023-12-15T18:15:43.260239Z"},"trusted":true},"execution_count":null,"outputs":[]}]}