{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\n\ntraining_data = pd.read_csv('/kaggle/input/digit-recognizer/train.csv')\ntesting_data = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")","metadata":{"_uuid":"c0eae390-f5c7-4ca2-836a-6d9774d3037e","_cell_guid":"32c4f992-acfa-425d-87cf-413529c7b1c0","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-04-20T16:48:40.863499Z","iopub.execute_input":"2022-04-20T16:48:40.866248Z","iopub.status.idle":"2022-04-20T16:48:44.949379Z","shell.execute_reply.started":"2022-04-20T16:48:40.866177Z","shell.execute_reply":"2022-04-20T16:48:44.948615Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"training = training_data.isnull().sum().sum()\nprint(f\"Nulls in training: {training}\")\n\nvalidation = testing_data.isnull().sum().sum()\nprint(f\"Nulls in validation: {validation}\")\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:48:49.329304Z","iopub.execute_input":"2022-04-20T16:48:49.329869Z","iopub.status.idle":"2022-04-20T16:48:49.404814Z","shell.execute_reply.started":"2022-04-20T16:48:49.329831Z","shell.execute_reply":"2022-04-20T16:48:49.404031Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = training_data.copy()\nY = X.pop('label')\n\nX.shape, Y.shape","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:48:58.495751Z","iopub.execute_input":"2022-04-20T16:48:58.496010Z","iopub.status.idle":"2022-04-20T16:48:58.606884Z","shell.execute_reply.started":"2022-04-20T16:48:58.495981Z","shell.execute_reply":"2022-04-20T16:48:58.606203Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\n\ntrain_X, val_X, train_Y, val_Y = train_test_split(X, Y, test_size=0.3, random_state=0)\n\ntrain_X.shape, val_X.shape, train_Y.shape, val_Y.shape","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:49:03.287984Z","iopub.execute_input":"2022-04-20T16:49:03.288656Z","iopub.status.idle":"2022-04-20T16:49:03.701991Z","shell.execute_reply.started":"2022-04-20T16:49:03.288619Z","shell.execute_reply":"2022-04-20T16:49:03.701267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\n\ntrain_X = train_X / 255.0\nval_X = val_X / 255.0\n\ntrain_Y = keras.utils.to_categorical(train_Y, num_classes=10)\nval_Y = keras.utils.to_categorical(val_Y, num_classes=10)\n\ntrain_Y.shape, val_Y.shape","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:49:07.700471Z","iopub.execute_input":"2022-04-20T16:49:07.700730Z","iopub.status.idle":"2022-04-20T16:49:07.812724Z","shell.execute_reply.started":"2022-04-20T16:49:07.700699Z","shell.execute_reply":"2022-04-20T16:49:07.812050Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef show_train_number(idx):\n  plt.imshow(train_X.to_numpy()[idx].reshape(28, 28))  # (rows, columns)\n  plt.title(f\"Digit: {np.where(train_Y[idx] == np.amax(train_Y[idx]))[0]}\")\n  plt.show() \n\ndef show_val_number(idx):\n  plt.imshow(val_X.to_numpy()[idx].reshape(28, 28))  # (rows, columns)\n  plt.title(f\"Digit: {np.where(val_Y[idx] == np.amax(val_Y[idx]))[0]}\")\n  plt.show() \n\ndef show_testing_data(idx):\n  plt.imshow(testing_data.to_numpy()[idx].reshape(28, 28))  # (rows, columns)\n  plt.show()\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:49:11.653777Z","iopub.execute_input":"2022-04-20T16:49:11.654049Z","iopub.status.idle":"2022-04-20T16:49:11.660827Z","shell.execute_reply.started":"2022-04-20T16:49:11.654016Z","shell.execute_reply":"2022-04-20T16:49:11.660135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow import keras\nfrom tensorflow.keras import layers\n\ninput_shape = [28*28]\n\nmodel = keras.Sequential([\n    #layers.Flatten(input_shape=input_shape),\n    layers.Dense(512, activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dense(128, activation='relu'),\n    layers.BatchNormalization(),\n    layers.Dense(10, activation='softmax')\n])\n\nmodel.compile(\n    optimizer='adam',\n    loss='categorical_crossentropy',\n    metrics=[\"categorical_accuracy\"]\n)","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:49:31.878864Z","iopub.execute_input":"2022-04-20T16:49:31.879125Z","iopub.status.idle":"2022-04-20T16:49:31.898357Z","shell.execute_reply.started":"2022-04-20T16:49:31.879094Z","shell.execute_reply":"2022-04-20T16:49:31.897664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# initiate early stopping to prevent overfitting\nearly_stopping = keras.callbacks.EarlyStopping(\n    patience=4,\n    min_delta=0.001,\n    restore_best_weights=True,\n)\n\n# train the model\ntraining = model.fit(\n    train_X, train_Y,\n    validation_data=(val_X, val_Y),\n    batch_size=128,\n    epochs=10,\n    callbacks=[early_stopping],\n    verbose=1\n)\n\nmodel.summary()\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:50:16.358001Z","iopub.execute_input":"2022-04-20T16:50:16.358256Z","iopub.status.idle":"2022-04-20T16:50:26.442731Z","shell.execute_reply.started":"2022-04-20T16:50:16.358227Z","shell.execute_reply":"2022-04-20T16:50:26.442008Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# PRUEBA CON UN ELEMENTO DEL CONJUNTO DE DATOS QUE NOS HEMOS GUARDADO PARA VALIDAR\nimport numpy as np\n\nvalIdx = 46;\n\noutput = model.predict(val_X)[valIdx]\n\n# convertimos la salida del modelo en un único valor\nres = np.where(output == np.amax(output))\n\n# convertimos el hotmap array de lo esperado en un valor\nexpected = np.where(val_Y[valIdx] == np.amax(val_Y[valIdx]))\n\nprint(f\"Valor esperado: {expected[0]}\")\nprint(f\"Valor de la predicción: {res[0]}\")\nshow_val_number(valIdx)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:50:50.297919Z","iopub.execute_input":"2022-04-20T16:50:50.298169Z","iopub.status.idle":"2022-04-20T16:50:51.307449Z","shell.execute_reply.started":"2022-04-20T16:50:50.298140Z","shell.execute_reply":"2022-04-20T16:50:51.306777Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Note, this code is taken straight from the SKLEARN website, an nice way of viewing confusion matrix.\nfrom sklearn.metrics import confusion_matrix\nimport itertools\n\ndef plot_confusion_matrix(cm, classes,\n                          normalize=False,\n                          title='Confusion matrix',\n                          cmap=plt.cm.Blues):\n    \"\"\"\n    This function prints and plots the confusion matrix.\n    Normalization can be applied by setting `normalize=True`.\n    \"\"\"\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(val_X)\n\n# Convert predictions classes to numbers\nY_pred_classes = np.argmax(Y_pred, axis = 1) \n\n\nprint(Y_pred_classes)\nprint(np.argmax(val_Y,  axis = 1))\n\n# Convert validation observations to one hot vectors\n#Y_true = np.argmax(val_Y, axis = 1) \n# compute the confusion matrix\nconfusion_mtx = confusion_matrix(np.argmax(val_Y,  axis = 1), Y_pred_classes)\n\n# plot the confusion matrix\nplot_confusion_matrix(confusion_mtx, classes = range(10))\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:50:55.506397Z","iopub.execute_input":"2022-04-20T16:50:55.506945Z","iopub.status.idle":"2022-04-20T16:50:57.245762Z","shell.execute_reply.started":"2022-04-20T16:50:55.506907Z","shell.execute_reply":"2022-04-20T16:50:57.245122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# evaluate the model\nloss_and_metrics = model.evaluate(val_X, val_Y, verbose=2)\n\nprint(\"Val Loss\", loss_and_metrics[0])\nprint(\"Val Accuracy\", loss_and_metrics[1])\n\n# plotting the metrics\nfig = plt.figure(figsize=(8,6))\nplt.subplot(2,1,1)\nplt.plot(training.history['categorical_accuracy'])\nplt.plot(training.history['val_categorical_accuracy'])\nplt.title('Model Accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', 'val'], loc='lower right')\n\nplt.subplot(2,1,2)\nplt.plot(training.history['loss'])\nplt.plot(training.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', 'val'], loc='upper right')\n\nplt.tight_layout()\nplt.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:51:04.892188Z","iopub.execute_input":"2022-04-20T16:51:04.892525Z","iopub.status.idle":"2022-04-20T16:51:06.733872Z","shell.execute_reply.started":"2022-04-20T16:51:04.892490Z","shell.execute_reply":"2022-04-20T16:51:06.733148Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CREAR PREDICCIONES DEL TESTSET\nsubmissionPredictions = np.argmax(model.predict(testing_data.to_numpy()), axis=-1)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:51:16.295733Z","iopub.execute_input":"2022-04-20T16:51:16.295983Z","iopub.status.idle":"2022-04-20T16:51:18.006065Z","shell.execute_reply.started":"2022-04-20T16:51:16.295954Z","shell.execute_reply":"2022-04-20T16:51:18.005274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# PRUEBA CON UN ELEMENTO DEL TESTSET\nitemToTest = 4\nplt.imshow(testing_data.to_numpy()[itemToTest].reshape(28, 28))\n# the label of the first number\nplt.title(f\"Digit: {submissionPredictions[itemToTest]}\")\nplt.show()\n\n","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:51:21.341018Z","iopub.execute_input":"2022-04-20T16:51:21.341272Z","iopub.status.idle":"2022-04-20T16:51:21.507982Z","shell.execute_reply.started":"2022-04-20T16:51:21.341244Z","shell.execute_reply":"2022-04-20T16:51:21.507291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# PREPARAR LA ENTREGA\n\nsubmission = pd.DataFrame({'ImageId':pd.Series(list(range(1, len(submissionPredictions)+1))),\n                                   'Label':pd.Series(submissionPredictions)})\n\nsubmission.to_csv(\"submission.csv\", index=False)\n\nsubmission","metadata":{"execution":{"iopub.status.busy":"2022-04-20T16:54:30.026895Z","iopub.execute_input":"2022-04-20T16:54:30.027149Z","iopub.status.idle":"2022-04-20T16:54:30.092689Z","shell.execute_reply.started":"2022-04-20T16:54:30.027120Z","shell.execute_reply":"2022-04-20T16:54:30.091872Z"},"trusted":true},"execution_count":null,"outputs":[]}]}