{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30665,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Loading the libraries","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.image as mpimg\nimport plotly.express as px\nimport seaborn as sns\n%matplotlib inline\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix\nimport itertools\n\n\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPool2D\nfrom keras.optimizers import Adam\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import ReduceLROnPlateau , LearningRateScheduler, EarlyStopping\n\n\nsns.set(style='white', context='notebook', palette='deep') # seaborn style ","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:10.994943Z","iopub.execute_input":"2024-03-02T14:35:10.995367Z","iopub.status.idle":"2024-03-02T14:35:11.006723Z","shell.execute_reply.started":"2024-03-02T14:35:10.995337Z","shell.execute_reply":"2024-03-02T14:35:11.005716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loading The Data","metadata":{}},{"cell_type":"code","source":"# loding the data pathes \ntrain =pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ntest  =pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\nprint (\"the shape of train data is \" , train.shape )\nprint (\"the shape of test data is \" , test.shape )","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:11.008341Z","iopub.execute_input":"2024-03-02T14:35:11.008652Z","iopub.status.idle":"2024-03-02T14:35:15.062520Z","shell.execute_reply.started":"2024-03-02T14:35:11.008629Z","shell.execute_reply":"2024-03-02T14:35:15.061618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X_train=train.drop(labels = [\"label\"],axis = 1)\ny_train=train['label']","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.135073Z","iopub.execute_input":"2024-03-02T14:35:15.135340Z","iopub.status.idle":"2024-03-02T14:35:15.220319Z","shell.execute_reply.started":"2024-03-02T14:35:15.135308Z","shell.execute_reply":"2024-03-02T14:35:15.219493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# know the number of image in each class \ndf=y_train.value_counts().reset_index()\ndf","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.221625Z","iopub.execute_input":"2024-03-02T14:35:15.221987Z","iopub.status.idle":"2024-03-02T14:35:15.234453Z","shell.execute_reply.started":"2024-03-02T14:35:15.221938Z","shell.execute_reply":"2024-03-02T14:35:15.233425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Preprocessing","metadata":{}},{"cell_type":"markdown","source":"## Normalization ","metadata":{}},{"cell_type":"code","source":"X_train = X_train / 255.0\ntest = test / 255.0","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.235732Z","iopub.execute_input":"2024-03-02T14:35:15.236031Z","iopub.status.idle":"2024-03-02T14:35:15.352757Z","shell.execute_reply.started":"2024-03-02T14:35:15.235995Z","shell.execute_reply":"2024-03-02T14:35:15.352020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Reshaping","metadata":{}},{"cell_type":"code","source":"# Reshape image in 3 dimensions (height = 28px, width = 28px , canal = 1)\nX_train = X_train.values.reshape(-1,28,28,1)\ntest = test.values.reshape(-1,28,28,1)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.353598Z","iopub.execute_input":"2024-03-02T14:35:15.353863Z","iopub.status.idle":"2024-03-02T14:35:15.358744Z","shell.execute_reply.started":"2024-03-02T14:35:15.353841Z","shell.execute_reply":"2024-03-02T14:35:15.357877Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Encoding the labels","metadata":{}},{"cell_type":"code","source":"# encoding the labels\nfrom tensorflow.keras.utils import to_categorical\n\ny_train = to_categorical(y_train, num_classes=10)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.359860Z","iopub.execute_input":"2024-03-02T14:35:15.360735Z","iopub.status.idle":"2024-03-02T14:35:15.369914Z","shell.execute_reply.started":"2024-03-02T14:35:15.360711Z","shell.execute_reply":"2024-03-02T14:35:15.368950Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Split the data to train & validation sets","metadata":{}},{"cell_type":"code","source":"# Split the train and the validation set for the fitting\nX_train, X_val, Y_train, Y_val = train_test_split(X_train, y_train, test_size = 0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.372957Z","iopub.execute_input":"2024-03-02T14:35:15.373237Z","iopub.status.idle":"2024-03-02T14:35:15.766327Z","shell.execute_reply.started":"2024-03-02T14:35:15.373215Z","shell.execute_reply":"2024-03-02T14:35:15.765524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CNN Model ","metadata":{}},{"cell_type":"code","source":"model = Sequential()\n\nmodel.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',\n                 activation ='relu', input_shape = (28,28,1)))\nmodel.add(Conv2D(filters = 32, kernel_size = (5,5),padding = 'Same',\n                 activation ='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2)))\nmodel.add(Dropout(0.25))\n\n\nmodel.add(Conv2D(filters = 64, kernel_size = (3,3),padding = 'Same',\n                 activation ='relu'))\nmodel.add(Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same',\n                 activation ='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(filters = 128, kernel_size = (3,3),padding = 'Same',\n                 activation ='relu'))\nmodel.add(MaxPool2D(pool_size=(2,2), strides=(2,2)))\nmodel.add(Dropout(0.25))\n\nmodel.add(Flatten())\nmodel.add(Dense(256, activation = \"relu\"))\nmodel.add(Dropout(0.5))\nmodel.add(Dense(10, activation = \"softmax\"))","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.767434Z","iopub.execute_input":"2024-03-02T14:35:15.767803Z","iopub.status.idle":"2024-03-02T14:35:15.916559Z","shell.execute_reply.started":"2024-03-02T14:35:15.767770Z","shell.execute_reply":"2024-03-02T14:35:15.915631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\ndef scheduler(epoch, learning_rate):\n    if epoch < 10:\n        return learning_rate\n    else:\n        return float(learning_rate * tf.math.exp(-0.1))\n\nreduce_lr = LearningRateScheduler(scheduler)\n# reduce_lr = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3,verbose=3,min_lr=0.00000001)\nearly_stop = EarlyStopping(monitor='val_loss', patience=8, restore_best_weights=True)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.917622Z","iopub.execute_input":"2024-03-02T14:35:15.917902Z","iopub.status.idle":"2024-03-02T14:35:15.923542Z","shell.execute_reply.started":"2024-03-02T14:35:15.917877Z","shell.execute_reply":"2024-03-02T14:35:15.922546Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss='categorical_crossentropy', optimizer=Adam(learning_rate=0.001, beta_1=0.9, beta_2=0.999 ),metrics = ['accuracy'])","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.924684Z","iopub.execute_input":"2024-03-02T14:35:15.924989Z","iopub.status.idle":"2024-03-02T14:35:15.936449Z","shell.execute_reply.started":"2024-03-02T14:35:15.924942Z","shell.execute_reply":"2024-03-02T14:35:15.935487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Augmentation","metadata":{}},{"cell_type":"code","source":"datagen = ImageDataGenerator(\n    rotation_range=10,          # Random rotation between 0 and 10 degrees\n    width_shift_range=0.1,      # Randomly shift images horizontally (fraction of total width)\n    height_shift_range=0.1,     # Randomly shift images vertically (fraction of total height)\n    zoom_range=0.1,             # Randomly zoom in/out on images\n    horizontal_flip=False,      # Randomly flip images horizontally\n    vertical_flip=False,        # Randomly flip images vertically\n)\n\ndatagen.fit(X_train)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:15.937480Z","iopub.execute_input":"2024-03-02T14:35:15.937779Z","iopub.status.idle":"2024-03-02T14:35:16.025395Z","shell.execute_reply.started":"2024-03-02T14:35:15.937741Z","shell.execute_reply":"2024-03-02T14:35:16.024354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"hist=model.fit(datagen.flow(X_train, Y_train, batch_size=256), \n                epochs=50, validation_data=(X_val, Y_val),\n                callbacks=[reduce_lr,early_stop],verbose=1,steps_per_epoch = X_train.shape[0]//256)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:16.026658Z","iopub.execute_input":"2024-03-02T14:35:16.026925Z","iopub.status.idle":"2024-03-02T14:35:16.240443Z","shell.execute_reply.started":"2024-03-02T14:35:16.026903Z","shell.execute_reply":"2024-03-02T14:35:16.239184Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model Accuracy","metadata":{}},{"cell_type":"code","source":"final_loss, final_acc = model.evaluate(X_val, Y_val, verbose=0)\nprint(\"Final loss: {0:.4f}, final accuracy: {1:.4f}\".format(final_loss, final_acc))","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:16.241521Z","iopub.status.idle":"2024-03-02T14:35:16.242012Z","shell.execute_reply.started":"2024-03-02T14:35:16.241749Z","shell.execute_reply":"2024-03-02T14:35:16.241768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluate the model","metadata":{}},{"cell_type":"code","source":"# Define needed variables\ntr_acc = hist.history['accuracy']\ntr_loss = hist.history['loss']\nval_acc = hist.history['val_accuracy']\nval_loss = hist.history['val_loss']\nindex_loss = np.argmin(val_loss)\nval_lowest = val_loss[index_loss]\nindex_acc = np.argmax(val_acc)\nacc_highest = val_acc[index_acc]\nEpochs = [i+1 for i in range(len(tr_acc))]\nloss_label = f'best epoch= {str(index_loss + 1)}'\nacc_label = f'best epoch= {str(index_acc + 1)}'\n\n# Plot training history\nplt.figure(figsize= (20, 8))\nplt.style.use('fivethirtyeight')\n\nplt.subplot(1, 2, 1)\nplt.plot(Epochs, tr_loss, 'r', label= 'Training loss')\nplt.plot(Epochs, val_loss, 'g', label= 'Validation loss')\nplt.scatter(index_loss + 1, val_lowest, s= 150, c= 'blue', label= loss_label)\nplt.title('Training and Validation Loss')\nplt.xlabel('Epochs')\nplt.ylabel('Loss')\nplt.legend()\n\nplt.subplot(1, 2, 2)\nplt.plot(Epochs, tr_acc, 'r', label= 'Training Accuracy')\nplt.plot(Epochs, val_acc, 'g', label= 'Validation Accuracy')\nplt.scatter(index_acc + 1 , acc_highest, s= 150, c= 'blue', label= acc_label)\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epochs')\nplt.ylabel('Accuracy')\nplt.legend()\n\nplt.tight_layout\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:16.243553Z","iopub.status.idle":"2024-03-02T14:35:16.243863Z","shell.execute_reply.started":"2024-03-02T14:35:16.243712Z","shell.execute_reply":"2024-03-02T14:35:16.243725Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Confusion Matrix ","metadata":{}},{"cell_type":"code","source":"def plot_confusion_matrix(cm, classes,normalize=False,title='Confusion matrix',cmap=plt.cm.Blues):\n\n    plt.figure(figsize=(16, 12))  \n    plt.imshow(cm, interpolation='nearest', cmap=cmap)\n    plt.title(title)\n    plt.colorbar()\n    tick_marks = np.arange(len(classes))\n    plt.xticks(tick_marks, classes, rotation=45)\n    plt.yticks(tick_marks, classes)\n\n    if normalize:\n        cm = cm.astype('float') / cm.sum(axis=1)[:, np.newaxis]\n\n    thresh = cm.max() / 2.\n    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):\n        plt.text(j, i, cm[i, j],\n                 horizontalalignment=\"center\",\n                 color=\"white\" if cm[i, j] > thresh else \"black\")\n\n    plt.tight_layout()\n    plt.ylabel('True label')\n    plt.xlabel('Predicted label')\n\n# Predict the values from the validation dataset\nY_pred = model.predict(X_val)\n# Convert predictions classes to one hot vectors \nY_pred_classes = np.argmax(Y_pred,axis = 1) \n# Convert validation observations to one hot vectors\nY_true = np.argmax(Y_val,axis = 1) \n# compute the confusion matrix\nconfusion_mtx = confusion_matrix(Y_true, Y_pred_classes) \n# plot the confusion matrix\nplot_confusion_matrix(confusion_mtx, classes = range(10)) ","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:16.245494Z","iopub.status.idle":"2024-03-02T14:35:16.245833Z","shell.execute_reply.started":"2024-03-02T14:35:16.245669Z","shell.execute_reply":"2024-03-02T14:35:16.245684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Save the results","metadata":{}},{"cell_type":"code","source":"results = model.predict(test)\n\n# select the indix with the maximum probability\nresults = np.argmax(results,axis = 1)\n\nresults = pd.Series(results,name=\"Label\")\n\nsubmission = pd.concat([pd.Series(range(1,28001),name = \"ImageId\"),results],axis = 1)\n\nsubmission.to_csv(\"digit_recognation.csv\",index=False)","metadata":{"execution":{"iopub.status.busy":"2024-03-02T14:35:16.246866Z","iopub.status.idle":"2024-03-02T14:35:16.247211Z","shell.execute_reply.started":"2024-03-02T14:35:16.247043Z","shell.execute_reply":"2024-03-02T14:35:16.247057Z"},"trusted":true},"execution_count":null,"outputs":[]}]}