{"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":30615,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <div> <center> <b> NN Arabic Handwriting Recognition </b> </center> </div>\n\n## <b> Credentials: </b> (E-JUST Submission)\n- Name: Mohamed Mostafa Kamel \n- ID: 320210126\n- Group: 1\n- Section: CNC3\n\n## <b> Notebook Workflow: </b>\n- Environment Setup\n- Data Pre-processing\n- Data Visualization\n- Model Definition\n- Training the Model\n- Prediction\n","metadata":{}},{"cell_type":"markdown","source":"## Environment Setup:\n### Importing Packages","metadata":{}},{"cell_type":"code","source":"import os\nimport cv2\nimport numpy as np\nimport pandas as pd\nfrom matplotlib import pyplot as plt\nimport tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras import Sequential\nfrom tensorflow.keras import layers\nfrom tensorflow.keras import regularizers\nfrom tensorflow.keras.optimizers import Adam\n","metadata":{"execution":{"iopub.status.busy":"2023-12-22T14:26:42.058864Z","iopub.execute_input":"2023-12-22T14:26:42.059355Z","iopub.status.idle":"2023-12-22T14:26:57.861972Z","shell.execute_reply.started":"2023-12-22T14:26:42.059321Z","shell.execute_reply":"2023-12-22T14:26:57.86027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading the Datasets:","metadata":{}},{"cell_type":"code","source":"datasets = ['/kaggle/input/arabic-letters-classification/Final_Arabic_Alpha_dataset/Final_Arabic_Alpha_dataset/train',\\\n            '/kaggle/input/arabic-letters-classification/Final_Arabic_Alpha_dataset/Final_Arabic_Alpha_dataset/test',\n           '/kaggle/input/arabic-letters-classification/Final_Arabic_Alpha_dataset/Final_Arabic_Alpha_dataset']\nNUM_CLASS = 65\nIMAGE_SIZE = (128,128)\nBATCH_SIZE = 256\nSEED = 43\nLABEL_NAMES = [i for i in range(NUM_CLASS)]","metadata":{"execution":{"iopub.status.busy":"2023-12-22T14:31:28.133621Z","iopub.execute_input":"2023-12-22T14:31:28.134121Z","iopub.status.idle":"2023-12-22T14:31:28.140599Z","shell.execute_reply.started":"2023-12-22T14:31:28.134082Z","shell.execute_reply":"2023-12-22T14:31:28.139682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"- There are 65 classes to classify into (0-64)\n- Images must be resized to a consistent size in order to train properly.","metadata":{}},{"cell_type":"markdown","source":"## Data Pre-processing:\nSplitting training data into 'Training' and 'Validation' for the model to train on.","metadata":{}},{"cell_type":"code","source":"train_images = tf.keras.utils.image_dataset_from_directory(\n    datasets[0],\n    validation_split=0.2,\n    color_mode=\"grayscale\",\n    label_mode=\"categorical\",\n    subset=\"training\",\n    shuffle=True,\n    seed=SEED,\n    image_size=IMAGE_SIZE,\n    batch_size=BATCH_SIZE)\n","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:00:45.19584Z","iopub.execute_input":"2023-12-22T15:00:45.19782Z","iopub.status.idle":"2023-12-22T15:00:49.003301Z","shell.execute_reply.started":"2023-12-22T15:00:45.197715Z","shell.execute_reply":"2023-12-22T15:00:49.001978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_validation = tf.keras.utils.image_dataset_from_directory(\n    datasets[0],\n    validation_split=0.2,\n    color_mode=\"grayscale\",\n    label_mode=\"categorical\",\n    subset=\"validation\",\n    shuffle=True,\n    seed=SEED,\n    image_size=IMAGE_SIZE,\n    batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:05:52.507088Z","iopub.execute_input":"2023-12-22T15:05:52.507567Z","iopub.status.idle":"2023-12-22T15:06:00.381718Z","shell.execute_reply.started":"2023-12-22T15:05:52.507534Z","shell.execute_reply":"2023-12-22T15:06:00.380409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Data Visualization:","metadata":{}},{"cell_type":"code","source":"class_names = train_images.class_names\nplt.figure(figsize=(10, 10))\nfor images, labels in train_images.take(1): # Takes a batch and shows the first 9 images\n    for i in range(9):\n        ax = plt.subplot(3, 3, i + 1)\n        plt.imshow(images[i].numpy().astype(\"uint8\"), cmap=plt.cm.Greys_r)\n        plt.title(class_names[np.where(np.array(labels[i])==1)[0][0]])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:08:00.653078Z","iopub.execute_input":"2023-12-22T15:08:00.653579Z","iopub.status.idle":"2023-12-22T15:08:06.348224Z","shell.execute_reply.started":"2023-12-22T15:08:00.653531Z","shell.execute_reply":"2023-12-22T15:08:06.34701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model Definition:","metadata":{}},{"cell_type":"code","source":"model = tf.keras.Sequential([\n    tf.keras.layers.Rescaling(1./255),\n    tf.keras.layers.RandomZoom(height_factor=(-.2,.3), width_factor=(-.2,.3)),\n    tf.keras.layers.RandomRotation((-.2,.3)),\n    tf.keras.layers.Conv2D(16, (3, 3), activation = 'relu', padding = 'same',  input_shape=(IMAGE_SIZE[0],IMAGE_SIZE[1],1)),\n    tf.keras.layers.MaxPooling2D(2, 2),\n    tf.keras.layers.Conv2D(32, (3, 3), activation = 'relu', padding = 'same'),\n    tf.keras.layers.MaxPooling2D(2, 2),\n    tf.keras.layers.Conv2D(64, (3, 3), activation = 'relu', padding = 'same'),\n    tf.keras.layers.MaxPooling2D(2, 2),\n    tf.keras.layers.Conv2D(128, (3, 3), activation = 'relu', padding = 'same'),\n    tf.keras.layers.MaxPooling2D(2, 2),\n    tf.keras.layers.Flatten(),\n    tf.keras.layers.Dense(256, activation='relu'),\n    tf.keras.layers.Dense(NUM_CLASS, activation=tf.nn.softmax)\n])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:32:35.681333Z","iopub.execute_input":"2023-12-22T15:32:35.681797Z","iopub.status.idle":"2023-12-22T15:32:35.715579Z","shell.execute_reply.started":"2023-12-22T15:32:35.681753Z","shell.execute_reply":"2023-12-22T15:32:35.714401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model Summary:","metadata":{}},{"cell_type":"code","source":"model.build(input_shape=(None, IMAGE_SIZE[0], IMAGE_SIZE[1], 1))\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:32:39.503622Z","iopub.execute_input":"2023-12-22T15:32:39.504268Z","iopub.status.idle":"2023-12-22T15:32:39.873616Z","shell.execute_reply.started":"2023-12-22T15:32:39.504215Z","shell.execute_reply":"2023-12-22T15:32:39.872186Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model Optimization:","metadata":{}},{"cell_type":"code","source":"model.compile(\n    optimizer = Adam(learning_rate= 0.001),\n    loss = 'categorical_crossentropy',\n    metrics=['accuracy']\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:48:28.171417Z","iopub.execute_input":"2023-12-22T15:48:28.171891Z","iopub.status.idle":"2023-12-22T15:48:28.207966Z","shell.execute_reply.started":"2023-12-22T15:48:28.171857Z","shell.execute_reply":"2023-12-22T15:48:28.206035Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Training the Model:","metadata":{}},{"cell_type":"code","source":"h1 = model.fit(train_images,\n              validation_data=train_validation,\n              epochs=50)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T15:51:42.445814Z","iopub.execute_input":"2023-12-22T15:51:42.446353Z","iopub.status.idle":"2023-12-22T21:10:07.295532Z","shell.execute_reply.started":"2023-12-22T15:51:42.446317Z","shell.execute_reply":"2023-12-22T21:10:07.294424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"<b>accuracy and loss curves:</b>","metadata":{}},{"cell_type":"code","source":"# Plotting the training and validation loss curves\nplt.figure(figsize=(12, 6))\n\n# Plotting the training loss\nplt.subplot(1, 2, 1)\nplt.plot(h1.history['loss'], label='Training Loss')\nplt.plot(h1.history['val_loss'], label='Validation Loss')\nplt.title('Training and Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\n# Plotting the training and validation accuracy curves\nplt.subplot(1, 2, 2)\nplt.plot(h1.history['accuracy'], label='Training Accuracy')\nplt.plot(h1.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:15:10.780787Z","iopub.execute_input":"2023-12-22T21:15:10.781307Z","iopub.status.idle":"2023-12-22T21:15:11.451622Z","shell.execute_reply.started":"2023-12-22T21:15:10.781269Z","shell.execute_reply":"2023-12-22T21:15:11.450431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Saving the Model:","metadata":{}},{"cell_type":"markdown","source":"Keras format:","metadata":{}},{"cell_type":"code","source":"model.save('nn-arabic-handwriting-320210126.keras')","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:35:08.99724Z","iopub.execute_input":"2023-12-22T21:35:08.997742Z","iopub.status.idle":"2023-12-22T21:35:09.192967Z","shell.execute_reply.started":"2023-12-22T21:35:08.997705Z","shell.execute_reply":"2023-12-22T21:35:09.191808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Loading the Model:","metadata":{}},{"cell_type":"code","source":"model = tf.keras.models.load_model('nn-arabic-handwriting-320210126.keras')","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:35:17.881667Z","iopub.execute_input":"2023-12-22T21:35:17.882102Z","iopub.status.idle":"2023-12-22T21:35:18.652396Z","shell.execute_reply.started":"2023-12-22T21:35:17.882067Z","shell.execute_reply":"2023-12-22T21:35:18.651218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Prediction:","metadata":{}},{"cell_type":"markdown","source":"Loading the 'Test' dataset:","metadata":{}},{"cell_type":"code","source":"test_images = tf.keras.utils.image_dataset_from_directory(\n        datasets[1],\n        labels=None,\n        color_mode=\"grayscale\",\n        label_mode=\"categorical\",\n        shuffle=False,\n        image_size=IMAGE_SIZE,\n        batch_size=BATCH_SIZE)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:35:27.434867Z","iopub.execute_input":"2023-12-22T21:35:27.435302Z","iopub.status.idle":"2023-12-22T21:35:35.249176Z","shell.execute_reply.started":"2023-12-22T21:35:27.435267Z","shell.execute_reply":"2023-12-22T21:35:35.248122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 10))\nfor images in test_images.take(1): # Takes a batch and shows the first 9 images\n    for i in range(9):\n        ax = plt.subplot(3, 3, i + 1)\n        plt.imshow(images[i].numpy().astype(\"uint8\"), cmap=plt.cm.Greys_r)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:35:45.018854Z","iopub.execute_input":"2023-12-22T21:35:45.019311Z","iopub.status.idle":"2023-12-22T21:35:47.219511Z","shell.execute_reply.started":"2023-12-22T21:35:45.019278Z","shell.execute_reply":"2023-12-22T21:35:47.218229Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for images in test_images:\n    print(images.shape)\n    break","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:37:47.12382Z","iopub.execute_input":"2023-12-22T21:37:47.124354Z","iopub.status.idle":"2023-12-22T21:37:47.248393Z","shell.execute_reply.started":"2023-12-22T21:37:47.124314Z","shell.execute_reply":"2023-12-22T21:37:47.247255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(test_images)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:37:51.530826Z","iopub.execute_input":"2023-12-22T21:37:51.531297Z","iopub.status.idle":"2023-12-22T21:38:24.973501Z","shell.execute_reply.started":"2023-12-22T21:37:51.531261Z","shell.execute_reply":"2023-12-22T21:38:24.972531Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_list = os.listdir(datasets[1])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:38:55.57297Z","iopub.execute_input":"2023-12-22T21:38:55.573982Z","iopub.status.idle":"2023-12-22T21:38:55.586152Z","shell.execute_reply.started":"2023-12-22T21:38:55.573933Z","shell.execute_reply":"2023-12-22T21:38:55.584747Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions[1][29]","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:38:59.454928Z","iopub.execute_input":"2023-12-22T21:38:59.455653Z","iopub.status.idle":"2023-12-22T21:38:59.462344Z","shell.execute_reply.started":"2023-12-22T21:38:59.455614Z","shell.execute_reply":"2023-12-22T21:38:59.461434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Making 'predictions.csv':","metadata":{}},{"cell_type":"code","source":"predictions.shape","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:21.35363Z","iopub.execute_input":"2023-12-22T21:48:21.354114Z","iopub.status.idle":"2023-12-22T21:48:21.362298Z","shell.execute_reply.started":"2023-12-22T21:48:21.354079Z","shell.execute_reply":"2023-12-22T21:48:21.360967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions = pd.DataFrame(columns=['ID','Label'], dtype=(np.int32,np.int32))\n\npredictions_mod = np.argmax(predictions, 1)\n\nfor idx,image in enumerate(sorted(img_list)):\n#     print(image, predictions_mod[idx])\n    df2 = pd.DataFrame([[int(image.split(\".\")[0]), int(predictions_mod[idx])]], columns=['ID','Label'])\n    df_predictions = pd.concat([df_predictions, df2])","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:25.360224Z","iopub.execute_input":"2023-12-22T21:48:25.361394Z","iopub.status.idle":"2023-12-22T21:48:31.055146Z","shell.execute_reply.started":"2023-12-22T21:48:25.361354Z","shell.execute_reply":"2023-12-22T21:48:31.053927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(predictions_mod)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:34.19635Z","iopub.execute_input":"2023-12-22T21:48:34.196755Z","iopub.status.idle":"2023-12-22T21:48:34.204265Z","shell.execute_reply.started":"2023-12-22T21:48:34.196723Z","shell.execute_reply":"2023-12-22T21:48:34.203452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:36.857654Z","iopub.execute_input":"2023-12-22T21:48:36.858827Z","iopub.status.idle":"2023-12-22T21:48:36.881398Z","shell.execute_reply.started":"2023-12-22T21:48:36.85879Z","shell.execute_reply":"2023-12-22T21:48:36.880082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions.sort_values(by='ID', inplace=True)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:44.74866Z","iopub.execute_input":"2023-12-22T21:48:44.749096Z","iopub.status.idle":"2023-12-22T21:48:44.760332Z","shell.execute_reply.started":"2023-12-22T21:48:44.749064Z","shell.execute_reply":"2023-12-22T21:48:44.758872Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:47.696998Z","iopub.execute_input":"2023-12-22T21:48:47.697442Z","iopub.status.idle":"2023-12-22T21:48:47.711864Z","shell.execute_reply.started":"2023-12-22T21:48:47.697406Z","shell.execute_reply":"2023-12-22T21:48:47.710593Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions.to_csv('Mohamed_Mostafa_320210126_predictions.csv', index=False, header=True) ","metadata":{"execution":{"iopub.status.busy":"2023-12-22T21:48:52.826423Z","iopub.execute_input":"2023-12-22T21:48:52.826842Z","iopub.status.idle":"2023-12-22T21:48:52.859316Z","shell.execute_reply.started":"2023-12-22T21:48:52.82681Z","shell.execute_reply":"2023-12-22T21:48:52.858033Z"},"trusted":true},"execution_count":null,"outputs":[]}]}