{"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":30627,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, MaxPool2D , Flatten\nfrom keras import layers\nfrom tensorflow import data as tf_data\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras.optimizers import Adam\nimport tensorflow as tf","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-23T19:16:37.171717Z","iopub.execute_input":"2023-12-23T19:16:37.171994Z","iopub.status.idle":"2023-12-23T19:16:54.637582Z","shell.execute_reply.started":"2023-12-23T19:16:37.171970Z","shell.execute_reply":"2023-12-23T19:16:54.636524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Preparation","metadata":{}},{"cell_type":"code","source":"dataset = ['/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/train',\n           '/kaggle/input/arabic-letters-classification/Final_Arabic_Alpha_dataset/Final_Arabic_Alpha_dataset']\n# 0 = test, 1 = train 2, 3 = Both\n\npng_size = [150, 150]\nbatch_size = 512\nseed = 500\nclasses = 65","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:16:54.639215Z","iopub.execute_input":"2023-12-23T19:16:54.639807Z","iopub.status.idle":"2023-12-23T19:16:54.645438Z","shell.execute_reply.started":"2023-12-23T19:16:54.639775Z","shell.execute_reply":"2023-12-23T19:16:54.644361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Creating Datasets","metadata":{}},{"cell_type":"code","source":"# Create training dataset\ntrain_ds = tf.keras.utils.image_dataset_from_directory(\n    dataset[1],\n    validation_split=0.2,\n    subset=\"training\",\n    color_mode='grayscale',\n    label_mode=\"categorical\",\n    shuffle=True,\n    seed=seed,\n    image_size=png_size,\n    batch_size=batch_size,\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:16:54.647084Z","iopub.execute_input":"2023-12-23T19:16:54.647912Z","iopub.status.idle":"2023-12-23T19:17:03.109279Z","shell.execute_reply.started":"2023-12-23T19:16:54.647874Z","shell.execute_reply":"2023-12-23T19:17:03.108506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_ds = tf.keras.utils.image_dataset_from_directory(\n    dataset[1],\n    validation_split=0.2,\n    subset=\"validation\",\n    color_mode='grayscale',\n    label_mode=\"categorical\",\n    shuffle=True,\n    seed=seed,\n    image_size=png_size,\n    batch_size=batch_size,\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:17:03.111444Z","iopub.execute_input":"2023-12-23T19:17:03.111763Z","iopub.status.idle":"2023-12-23T19:17:16.424762Z","shell.execute_reply.started":"2023-12-23T19:17:03.111736Z","shell.execute_reply":"2023-12-23T19:17:16.423970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Visualization","metadata":{}},{"cell_type":"code","source":"def visualize_dataset(dataset, num_samples=5):\n    # Get a batch of images and labels from the dataset\n    for images, labels in dataset.take(1):\n        # Select a few random samples\n        random_indices = np.random.choice(images.shape[0], num_samples, replace=False)\n\n        # Plot the selected samples\n        plt.figure(figsize=(15, 3))\n        for i, index in enumerate(random_indices, 1):\n            plt.subplot(1, num_samples, i)\n            plt.imshow(images[index].numpy().astype(\"uint8\"))\n            plt.title(f\"Class: {np.argmax(labels[index])}\")\n            plt.axis(\"off\")\n        plt.show()\n\n# Visualize a few samples from the training dataset\nvisualize_dataset(train_ds)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:17:16.425866Z","iopub.execute_input":"2023-12-23T19:17:16.426148Z","iopub.status.idle":"2023-12-23T19:17:23.347588Z","shell.execute_reply.started":"2023-12-23T19:17:16.426123Z","shell.execute_reply":"2023-12-23T19:17:23.346592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### The Model","metadata":{}},{"cell_type":"code","source":"# CNN model\nmodel = Sequential([\n    tf.keras.layers.Rescaling(1./255),\n    layers.InputLayer(input_shape=(png_size[0], png_size[1], 3)),\n    layers.Conv2D(32, (3, 3), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(64, (3, 3), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Conv2D(128, (3, 3), activation='relu'),\n    layers.MaxPooling2D((2, 2)),\n    layers.Flatten(),\n    layers.Dense(128, activation='relu'),\n    layers.Dense(classes, activation='softmax')  # Output layer with 'classes' units for classification\n])\n\n# Compile the model\nmodel.compile(optimizer=Adam(), loss='categorical_crossentropy', metrics=['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:17:23.348947Z","iopub.execute_input":"2023-12-23T19:17:23.349294Z","iopub.status.idle":"2023-12-23T19:17:23.411923Z","shell.execute_reply.started":"2023-12-23T19:17:23.349266Z","shell.execute_reply":"2023-12-23T19:17:23.411198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model\nhistory = model.fit(train_ds, validation_data=val_ds, epochs=20)\n\n# Evaluate the model on the validation set\naccuracy = model.evaluate(val_ds)\nprint(f\"Validation Accuracy: {accuracy[1] * 100:.2f}%\")","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:17:23.413208Z","iopub.execute_input":"2023-12-23T19:17:23.413589Z","iopub.status.idle":"2023-12-23T19:26:53.876862Z","shell.execute_reply.started":"2023-12-23T19:17:23.413555Z","shell.execute_reply":"2023-12-23T19:26:53.875965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Evaluation","metadata":{}},{"cell_type":"code","source":"plt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:26:53.878075Z","iopub.execute_input":"2023-12-23T19:26:53.878685Z","iopub.status.idle":"2023-12-23T19:26:54.140621Z","shell.execute_reply.started":"2023-12-23T19:26:53.878650Z","shell.execute_reply":"2023-12-23T19:26:54.139725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\nplt.title('Model Accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'test'], loc='upper left')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:26:54.141727Z","iopub.execute_input":"2023-12-23T19:26:54.141989Z","iopub.status.idle":"2023-12-23T19:26:54.383338Z","shell.execute_reply.started":"2023-12-23T19:26:54.141966Z","shell.execute_reply":"2023-12-23T19:26:54.382436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Save the model","metadata":{}},{"cell_type":"code","source":"model.save(\"320210338_AID_ArabicLettersClassification.keras\")","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:26:54.388226Z","iopub.execute_input":"2023-12-23T19:26:54.388646Z","iopub.status.idle":"2023-12-23T19:26:54.661108Z","shell.execute_reply.started":"2023-12-23T19:26:54.388617Z","shell.execute_reply":"2023-12-23T19:26:54.660112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Prediction","metadata":{}},{"cell_type":"code","source":"# Create training dataset\ntest_ds = tf.keras.utils.image_dataset_from_directory(\n    dataset[0],\n    labels=None,\n    color_mode='grayscale',\n    label_mode=\"categorical\",\n    seed=seed,\n    shuffle=False,\n    image_size=png_size,\n    batch_size=batch_size,\n)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:26:54.662434Z","iopub.execute_input":"2023-12-23T19:26:54.662732Z","iopub.status.idle":"2023-12-23T19:27:09.077582Z","shell.execute_reply.started":"2023-12-23T19:26:54.662707Z","shell.execute_reply":"2023-12-23T19:27:09.076650Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = model.predict(test_ds)\n\ndef visualize_predictions(images, predictions):\n    plt.figure(figsize=(600, 600))\n    \n    for i in range(9):\n        plt.subplot(1, images.shape[0], i + 4)\n        plt.imshow(images[i].numpy().astype(\"uint8\"))\n        predicted_label = np.argmax(predictions[i])\n        plt.title(f'Predicted: {predicted_label}')\n        plt.axis('off')\n    plt.show()\n    \nfor images in test_ds.take(1):\n    visualize_predictions(images, predictions)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:27:09.078846Z","iopub.execute_input":"2023-12-23T19:27:09.079183Z","iopub.status.idle":"2023-12-23T19:27:37.003264Z","shell.execute_reply.started":"2023-12-23T19:27:09.079150Z","shell.execute_reply":"2023-12-23T19:27:37.002395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels_list = sorted(os.listdir(dataset[1]))\nprint(labels_list)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T19:27:37.004630Z","iopub.execute_input":"2023-12-23T19:27:37.004983Z","iopub.status.idle":"2023-12-23T19:27:37.012169Z","shell.execute_reply.started":"2023-12-23T19:27:37.004949Z","shell.execute_reply":"2023-12-23T19:27:37.011133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img_list = sorted(os.listdir(dataset[0]))\ndf_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    df2 = pd.DataFrame([[int(image.split(\".\")[0]), int(labels_list[predictions_mod[idx]])]], columns=['ID','Label'])\n    df_predictions = pd.concat([df_predictions, df2])","metadata":{"execution":{"iopub.status.busy":"2023-12-23T20:07:02.956283Z","iopub.execute_input":"2023-12-23T20:07:02.956665Z","iopub.status.idle":"2023-12-23T20:07:07.803615Z","shell.execute_reply.started":"2023-12-23T20:07:02.956634Z","shell.execute_reply":"2023-12-23T20:07:07.802586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(predictions_mod)","metadata":{"execution":{"iopub.status.busy":"2023-12-23T20:07:19.690610Z","iopub.execute_input":"2023-12-23T20:07:19.690957Z","iopub.status.idle":"2023-12-23T20:07:19.695961Z","shell.execute_reply.started":"2023-12-23T20:07:19.690930Z","shell.execute_reply":"2023-12-23T20:07:19.695045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions.head()","metadata":{"execution":{"iopub.status.busy":"2023-12-23T20:07:31.675243Z","iopub.execute_input":"2023-12-23T20:07:31.676155Z","iopub.status.idle":"2023-12-23T20:07:31.693013Z","shell.execute_reply.started":"2023-12-23T20:07:31.676120Z","shell.execute_reply":"2023-12-23T20:07:31.691978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_predictions.sort_values(by='ID', inplace=True)\ndf_predictions.reset_index(drop=True)\ndf_predictions.to_csv('predictions.csv', index=False, header=True) \ndf_predictions.to_csv('submission.csv', index=False, header=True) ","metadata":{"execution":{"iopub.status.busy":"2023-12-23T20:09:40.047366Z","iopub.execute_input":"2023-12-23T20:09:40.048259Z","iopub.status.idle":"2023-12-23T20:09:40.095690Z","shell.execute_reply.started":"2023-12-23T20:09:40.048224Z","shell.execute_reply":"2023-12-23T20:09:40.094816Z"},"trusted":true},"execution_count":null,"outputs":[]}]}