{"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":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30636,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-01-26T13:13:32.442420Z","iopub.execute_input":"2024-01-26T13:13:32.442772Z","iopub.status.idle":"2024-01-26T13:13:34.081148Z","shell.execute_reply.started":"2024-01-26T13:13:32.442743Z","shell.execute_reply":"2024-01-26T13:13:34.080158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Function to evaluate: accuracy, precision, recall, f1-score\nfrom sklearn.metrics import accuracy_score, precision_recall_fscore_support\n\ndef calculate_results(y_true, y_pred):\n  \"\"\"\n  Calculates model accuracy, precision, recall and f1 score of a binary classification model.\n\n  Args:\n      y_true: true labels in the form of a 1D array\n      y_pred: predicted labels in the form of a 1D array\n\n  Returns a dictionary of accuracy, precision, recall, f1-score.\n  \"\"\"\n  # Calculate model accuracy\n  model_accuracy = accuracy_score(y_true, y_pred) * 100\n  # Calculate model precision, recall and f1 score using \"weighted average\n  model_precision, model_recall, model_f1, _ = precision_recall_fscore_support(y_true, y_pred, average=\"weighted\")\n  model_results = {\"accuracy\": model_accuracy,\n                  \"precision\": model_precision,\n                  \"recall\": model_recall,\n                  \"f1\": model_f1}\n  return model_results","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:13:34.083085Z","iopub.execute_input":"2024-01-26T13:13:34.083641Z","iopub.status.idle":"2024-01-26T13:13:35.661996Z","shell.execute_reply.started":"2024-01-26T13:13:34.083604Z","shell.execute_reply":"2024-01-26T13:13:35.660961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\ny = train_df[['label']]","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:13:35.663243Z","iopub.execute_input":"2024-01-26T13:13:35.663578Z","iopub.status.idle":"2024-01-26T13:13:39.271412Z","shell.execute_reply.started":"2024-01-26T13:13:35.663520Z","shell.execute_reply":"2024-01-26T13:13:39.270595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:13:39.273601Z","iopub.execute_input":"2024-01-26T13:13:39.273912Z","iopub.status.idle":"2024-01-26T13:13:39.295631Z","shell.execute_reply.started":"2024-01-26T13:13:39.273885Z","shell.execute_reply":"2024-01-26T13:13:39.294764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df.label.hist()","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:13:39.296541Z","iopub.execute_input":"2024-01-26T13:13:39.296819Z","iopub.status.idle":"2024-01-26T13:13:39.619778Z","shell.execute_reply.started":"2024-01-26T13:13:39.296797Z","shell.execute_reply":"2024-01-26T13:13:39.618894Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(y)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:13:39.620968Z","iopub.execute_input":"2024-01-26T13:13:39.621255Z","iopub.status.idle":"2024-01-26T13:13:39.626980Z","shell.execute_reply.started":"2024-01-26T13:13:39.621231Z","shell.execute_reply":"2024-01-26T13:13:39.626158Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X = []\nfor index, pixels in train_df.drop(columns=['label']).iterrows():\n    image = []\n    for i in range(0, 28):\n        row = []\n        for j in range(i * 28, i * 28 + 28):\n            row.append(pixels[f'pixel{j}'])\n        image.append(row)\n    X.append(image)\nlen(X)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:13:39.628708Z","iopub.execute_input":"2024-01-26T13:13:39.628957Z","iopub.status.idle":"2024-01-26T13:16:40.639954Z","shell.execute_reply.started":"2024-01-26T13:13:39.628934Z","shell.execute_reply":"2024-01-26T13:16:40.638956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"X[0]","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:16:40.641244Z","iopub.execute_input":"2024-01-26T13:16:40.641636Z","iopub.status.idle":"2024-01-26T13:16:40.668300Z","shell.execute_reply.started":"2024-01-26T13:16:40.641602Z","shell.execute_reply":"2024-01-26T13:16:40.667291Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nplt.imshow(X[10])","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:16:40.670296Z","iopub.execute_input":"2024-01-26T13:16:40.671238Z","iopub.status.idle":"2024-01-26T13:16:40.880807Z","shell.execute_reply.started":"2024-01-26T13:16:40.671204Z","shell.execute_reply":"2024-01-26T13:16:40.879953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Create datasets","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\ntrain_X, val_X, train_y, val_y = train_test_split(X, y, test_size=0.1)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:16:40.884119Z","iopub.execute_input":"2024-01-26T13:16:40.884421Z","iopub.status.idle":"2024-01-26T13:16:40.924342Z","shell.execute_reply.started":"2024-01-26T13:16:40.884395Z","shell.execute_reply":"2024-01-26T13:16:40.923191Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(val_X), len(val_y)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:16:40.925585Z","iopub.execute_input":"2024-01-26T13:16:40.925955Z","iopub.status.idle":"2024-01-26T13:16:40.932835Z","shell.execute_reply.started":"2024-01-26T13:16:40.925929Z","shell.execute_reply":"2024-01-26T13:16:40.931820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:16:40.934243Z","iopub.execute_input":"2024-01-26T13:16:40.934654Z","iopub.status.idle":"2024-01-26T13:16:58.394234Z","shell.execute_reply.started":"2024-01-26T13:16:40.934618Z","shell.execute_reply":"2024-01-26T13:16:58.393476Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dataset = tf.data.Dataset.from_tensor_slices((train_X, train_y)).batch(batch_size=64).prefetch(tf.data.AUTOTUNE)\nval_dataset = tf.data.Dataset.from_tensor_slices((val_X, val_y)).batch(batch_size=64).prefetch(tf.data.AUTOTUNE)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:16:58.395518Z","iopub.execute_input":"2024-01-26T13:16:58.396269Z","iopub.status.idle":"2024-01-26T13:19:06.624647Z","shell.execute_reply.started":"2024-01-26T13:16:58.396232Z","shell.execute_reply":"2024-01-26T13:19:06.623614Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Build model like VGGNet","metadata":{}},{"cell_type":"code","source":"inputs = tf.keras.layers.Input(shape=[28, 28, 1], dtype=tf.float32, name=\"input_layer\")\n# data augmentation\nx = tf.keras.layers.RandomFlip(\"horizontal_and_vertical\")(inputs)\nx = tf.keras.layers.RandomRotation(0.2)(x)\nx = tf.keras.layers.Rescaling(1/255.)(x)\nx = tf.keras.layers.Conv2D(filters=32, kernel_size=3, name=\"conv_layer_1\", padding='same',activation='relu')(inputs)\nx = tf.keras.layers.Conv2D(filters=32, kernel_size=3, name=\"conv_layer_2\", padding='same',activation='relu')(x)\nx = tf.keras.layers.Conv2D(filters=32, kernel_size=3, name=\"conv_layer_3\", padding='same',activation='relu')(x)\nx = tf.keras.layers.AveragePooling2D()(x)\nx = tf.keras.layers.Conv2D(filters=32, kernel_size=3, name=\"conv_layer_4\", padding='same',activation='relu')(x)\nx = tf.keras.layers.Conv2D(filters=32, kernel_size=3, name=\"conv_layer_5\", padding='same',activation='relu')(x)\nx = tf.keras.layers.Conv2D(filters=32, kernel_size=3, name=\"conv_layer_6\", padding='same',activation='relu')(x)\nx = tf.keras.layers.AveragePooling2D()(x)\nx = tf.keras.layers.Dropout(0.5)(x)\nx = tf.keras.layers.Flatten()(x)\nx = tf.keras.layers.Dense(32, activation='relu')(x)\noutputs = tf.keras.layers.Dense(units=10, activation=\"softmax\", name=\"output_layer\")(x)\n\nmodel = tf.keras.models.Model(inputs, outputs)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:32:15.303350Z","iopub.execute_input":"2024-01-26T13:32:15.303807Z","iopub.status.idle":"2024-01-26T13:32:15.542744Z","shell.execute_reply.started":"2024-01-26T13:32:15.303778Z","shell.execute_reply":"2024-01-26T13:32:15.541934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:32:18.024974Z","iopub.execute_input":"2024-01-26T13:32:18.025975Z","iopub.status.idle":"2024-01-26T13:32:18.069173Z","shell.execute_reply.started":"2024-01-26T13:32:18.025941Z","shell.execute_reply":"2024-01-26T13:32:18.065407Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(loss=\"sparse_categorical_crossentropy\", optimizer=tf.keras.optimizers.Adam(learning_rate=1e-3), metrics=['accuracy'])\nhistory = model.fit(train_dataset, epochs=100, validation_data=val_dataset,verbose=1,\n                       callbacks=[\n                           tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss',patience=5),\n                           tf.keras.callbacks.ModelCheckpoint(filepath=\"/output/saved_models/\"),\n                           tf.keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)\n                   ])","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:32:19.992771Z","iopub.execute_input":"2024-01-26T13:32:19.993429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\npd.DataFrame(history.history).plot()","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:22:05.588442Z","iopub.execute_input":"2024-01-26T13:22:05.588757Z","iopub.status.idle":"2024-01-26T13:22:05.946650Z","shell.execute_reply.started":"2024-01-26T13:22:05.588732Z","shell.execute_reply":"2024-01-26T13:22:05.945601Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = tf.keras.models.load_model(filepath='/output/saved_models/')","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:22:05.947872Z","iopub.execute_input":"2024-01-26T13:22:05.948177Z","iopub.status.idle":"2024-01-26T13:22:06.561630Z","shell.execute_reply.started":"2024-01-26T13:22:05.948151Z","shell.execute_reply":"2024-01-26T13:22:06.560605Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probs = model.predict(val_dataset)\npredicted_pred = [ np.argmax(prob) for prob in probs]","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:22:06.564704Z","iopub.execute_input":"2024-01-26T13:22:06.565022Z","iopub.status.idle":"2024-01-26T13:22:06.963389Z","shell.execute_reply.started":"2024-01-26T13:22:06.564996Z","shell.execute_reply":"2024-01-26T13:22:06.962496Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"calculate_results(val_y, predicted_pred)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:22:06.964878Z","iopub.execute_input":"2024-01-26T13:22:06.965768Z","iopub.status.idle":"2024-01-26T13:22:06.990626Z","shell.execute_reply.started":"2024-01-26T13:22:06.965728Z","shell.execute_reply":"2024-01-26T13:22:06.989455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Predict on test","metadata":{}},{"cell_type":"code","source":"test_df = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:22:06.991706Z","iopub.execute_input":"2024-01-26T13:22:06.991959Z","iopub.status.idle":"2024-01-26T13:22:09.237120Z","shell.execute_reply.started":"2024-01-26T13:22:06.991937Z","shell.execute_reply":"2024-01-26T13:22:09.236078Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_X = []\nfor index, pixels in test_df.iterrows():\n    image = []\n    for i in range(0, 28):\n        row = []\n        for j in range(i * 28, i * 28 + 28):\n            row.append(pixels[f'pixel{j}'])\n        image.append(row)\n    test_X.append(image)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:22:09.238355Z","iopub.execute_input":"2024-01-26T13:22:09.238696Z","iopub.status.idle":"2024-01-26T13:24:10.304825Z","shell.execute_reply.started":"2024-01-26T13:22:09.238669Z","shell.execute_reply":"2024-01-26T13:24:10.303686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"probs = model.predict(tf.data.Dataset.from_tensor_slices(test_X).batch(32).prefetch(tf.data.AUTOTUNE))\npreds = [np.argmax(prob) for prob in probs]","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:24:10.306168Z","iopub.execute_input":"2024-01-26T13:24:10.306452Z","iopub.status.idle":"2024-01-26T13:25:36.610078Z","shell.execute_reply.started":"2024-01-26T13:24:10.306428Z","shell.execute_reply":"2024-01-26T13:25:36.608709Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv(\"/kaggle/input/digit-recognizer/sample_submission.csv\")\nsubmission['Label'] = preds\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-26T13:25:36.612583Z","iopub.execute_input":"2024-01-26T13:25:36.613075Z","iopub.status.idle":"2024-01-26T13:25:36.833672Z","shell.execute_reply.started":"2024-01-26T13:25:36.613041Z","shell.execute_reply":"2024-01-26T13:25:36.832667Z"},"trusted":true},"execution_count":null,"outputs":[]}]}