{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \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 \"../input/\" directory.\n# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory\n\nimport os\nprint(os.listdir(\"../input\"))\n\n# Any results you write to the current directory are saved as output.","execution_count":1,"outputs":[{"output_type":"stream","text":"['sample_submission.csv', 'test.csv', 'train.csv']\n","name":"stdout"}]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"train = pd.read_csv(\"../input/train.csv\")\ntest = pd.read_csv(\"../input/test.csv\")","execution_count":2,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.info()","execution_count":3,"outputs":[{"output_type":"stream","text":"<class 'pandas.core.frame.DataFrame'>\nRangeIndex: 42000 entries, 0 to 41999\nColumns: 785 entries, label to pixel783\ndtypes: int64(785)\nmemory usage: 251.5 MB\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"train.head()","execution_count":4,"outputs":[{"output_type":"execute_result","execution_count":4,"data":{"text/plain":"   label  pixel0  pixel1    ...     pixel781  pixel782  pixel783\n0      1       0       0    ...            0         0         0\n1      0       0       0    ...            0         0         0\n2      1       0       0    ...            0         0         0\n3      4       0       0    ...            0         0         0\n4      0       0       0    ...            0         0         0\n\n[5 rows x 785 columns]","text/html":"<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }\n\n    .dataframe tbody tr th {\n        vertical-align: top;\n    }\n\n    .dataframe thead th {\n        text-align: right;\n    }\n</style>\n<table border=\"1\" class=\"dataframe\">\n  <thead>\n    <tr style=\"text-align: right;\">\n      <th></th>\n      <th>label</th>\n      <th>pixel0</th>\n      <th>pixel1</th>\n      <th>pixel2</th>\n      <th>pixel3</th>\n      <th>pixel4</th>\n      <th>pixel5</th>\n      <th>pixel6</th>\n      <th>pixel7</th>\n      <th>pixel8</th>\n      <th>pixel9</th>\n      <th>pixel10</th>\n      <th>pixel11</th>\n      <th>pixel12</th>\n      <th>pixel13</th>\n      <th>pixel14</th>\n      <th>pixel15</th>\n      <th>pixel16</th>\n      <th>pixel17</th>\n      <th>pixel18</th>\n      <th>pixel19</th>\n      <th>pixel20</th>\n      <th>pixel21</th>\n      <th>pixel22</th>\n      <th>pixel23</th>\n      <th>pixel24</th>\n      <th>pixel25</th>\n      <th>pixel26</th>\n      <th>pixel27</th>\n      <th>pixel28</th>\n      <th>pixel29</th>\n      <th>pixel30</th>\n      <th>pixel31</th>\n      <th>pixel32</th>\n      <th>pixel33</th>\n      <th>pixel34</th>\n      <th>pixel35</th>\n      <th>pixel36</th>\n      <th>pixel37</th>\n      <th>pixel38</th>\n      <th>...</th>\n      <th>pixel744</th>\n      <th>pixel745</th>\n      <th>pixel746</th>\n      <th>pixel747</th>\n      <th>pixel748</th>\n      <th>pixel749</th>\n      <th>pixel750</th>\n      <th>pixel751</th>\n      <th>pixel752</th>\n      <th>pixel753</th>\n      <th>pixel754</th>\n      <th>pixel755</th>\n      <th>pixel756</th>\n      <th>pixel757</th>\n      <th>pixel758</th>\n      <th>pixel759</th>\n      <th>pixel760</th>\n      <th>pixel761</th>\n      <th>pixel762</th>\n      <th>pixel763</th>\n      <th>pixel764</th>\n      <th>pixel765</th>\n      <th>pixel766</th>\n      <th>pixel767</th>\n      <th>pixel768</th>\n      <th>pixel769</th>\n      <th>pixel770</th>\n      <th>pixel771</th>\n      <th>pixel772</th>\n      <th>pixel773</th>\n      <th>pixel774</th>\n      <th>pixel775</th>\n      <th>pixel776</th>\n      <th>pixel777</th>\n      <th>pixel778</th>\n      <th>pixel779</th>\n      <th>pixel780</th>\n      <th>pixel781</th>\n      <th>pixel782</th>\n      <th>pixel783</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr>\n      <th>0</th>\n      <td>1</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>...</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>1</th>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>...</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>2</th>\n      <td>1</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>...</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>3</th>\n      <td>4</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>...</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n    <tr>\n      <th>4</th>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>...</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n      <td>0</td>\n    </tr>\n  </tbody>\n</table>\n</div>"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"We can see that first column is the label while other columns are the pixel values for the digit"},{"metadata":{"trusted":true},"cell_type":"code","source":"Y_Train = train[\"label\"]\nX_Train = train.drop(labels = [\"label\"], axis = 1)\n\nX_Train = X_Train.values.reshape(-1,28,28,1)\nX_Test = test.values.reshape(-1,28,28,1)","execution_count":5,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(\"Number of records in training data \"+str(X_Train.shape[0]))\nprint(\"Number of records in test data \"+str(test.shape[0]))","execution_count":6,"outputs":[{"output_type":"stream","text":"Number of records in training data 42000\nNumber of records in test data 28000\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"Lets visualize some random samples"},{"metadata":{"trusted":true},"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport random\n\nplt.figure(figsize=(10,5))\nfor i in range(10):  \n    plt.subplot(1, 10, i+1)\n    r = random.randint(0, X_Train.shape[0])\n    plt.imshow(X_Train[r].reshape((28,28)),cmap=plt.cm.binary)\n    plt.axis('off')","execution_count":7,"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 720x360 with 10 Axes>","image/png":"iVBORw0KGgoAAAANSUhEUgAAAlIAAABRCAYAAAAZ1Ej0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvnQurowAAFWBJREFUeJzt3Xm4VdMfx/H3FSF0QxnjlgzlCZnzSIokJIkUyUzJUKbMQyQNhIfKmCGKQpEknnBNT1KEyBSNlCkqZLj1+2P/vmufe++5t3P22fucvfN5/RP3nHvOXvecvfda3/Vd31W0Zs0aRERERCR76xX6AERERESSSh0pERERkYDUkRIREREJSB0pERERkYDUkRIREREJSB0pERERkYDUkRIREREJSB0pERERkYDUkRIREREJaP08v1/Sy6gXZfCcdb2N63r7QG1MArVx3W8fqI1J8J9voyJSIiIiIgGpIyUiIiISkDpSIiIiIgHlO0dKRCQxfvzxRwDOPfdcADp06MC2225b7jlHHXVU3o9LROJDESkRERGRgIrWrMlrMn2kb7ZixQr33xdffDEAs2fPBuDGG28EoH379rm8xX9+dQIFaN+UKVMAaNeuHQA9evTgvvvuC/py+gw9amMGOnbsCMCkSZOqfE6vXr044YQTAGjZsmWub5kqdudiyPQ99aiN8adVeyIiIiJRWCciUhZ1OuaYYwAoKirit99+A+DXX38FYIMNNgDgoosu4qabbgJgs802y/at8tLzXrBgAQAlJSWANyp+6KGHANhyyy1zffm1ic0o+IUXXgCgS5cuAKxatQqAZs2aMXXqVAC22GKLbF82L5/hnDlzAP+zHDt2LCNHjqz0vD322AOA448/HoBrrrkGgA033DCXt89LG994441y/2bKzr8cRdrGs88+G4BHHnkEgBo1alT53LKyMrbeemsAxo8fD0Dz5s2DvnWq2JyLESl4JOP9998HvGuMXVsvu+wyAP766y/3vG222QaAI488Mtu3KHgb33vvPcD7TtatWxeAxx57DICjjz46jLcoeBvzoNo2Jj7Z/LPPPnPTdXbTatKkCUuXLi33vH/++QeAoUOH8tVXXwEwatQoAIqLi/N1uBkpKvI+s/XW8wKGEyZM4LXXXgP8G26bNm3cVJddAOz31hVPPfUU4HegzJlnnhmkAxW6srIyANdpf+KJJ3jyyScB73sJsHLlyip/f/311+eTTz4BcP9+9913ADz44IPRHHQIrOPUunXrQL9fWloKwOuvvx7WIYWu4vVjbX766SfA+26C35FOipdffhmAJUuWVHrszDPPrPbacvDBBwMwbtw4wO90JIFdW+rXr89bb70FwMknnwzArrvuCngD9I033rgwBxiCefPmAd79oXfv3kBoHaiCsPv8sGHDXNvGjh3rHrf7ol1D69evH/kxaWpPREREJKDETu1ZhKlRo0YsXLgQ8KdJ3nrrLT7//HMABg8eDMCsWbMA+Oabb9xrjBgxAoCePXtm+rZ5DWFeffXVANx1112VojKpDjvsMAB23HFHAE444YRy05xZisV0wqWXXuqiOz/88AMAp59+OgAPP/xwtVMtaxHKZ1hWVsbdd98N+FMB6dhS+TvuuKPSY40aNeL8888H4IMPPij3fItMBRTZ9/Smm26iX79+QX61klatWuUSlYr0XJw5cybglz+w8+i7777jvPPOK/fcsrIy933ceeedgdAiUpGci6tWreLWW28F4O233wbg448/BmD58uWVnp/avnQsMtu9e3fAnzbKQMGmhOyaYlN1S5Ys4ZRTTgHgxRdfBKBhw4YAPPvss2yyySZB36rg016nnXYa4EXM58+fD8AOO+wQ5ltE2sZ///0X8GeQ7HpraTtVsel5W5iUwz0DlGwuIiIiEo3E5khdfvnlACxcuNDlOFn0qbi4mAMPPBDwRhPgR6IaNWrkXsPmVbOISOXVbbfdBnhz9sOGDQPglVdeAWDZsmUuN+edd94BcHlUjz76qIuWWBmIpPjjjz8AmD59uhs1Gou45TiyCMV7773nIoYtWrQAvFFegwYNAH+e3ka1VY0ALefNIlJxFUX+3RtvvOHyrVq1ahX66+di3333rfIxK7PSp08fANasWeOiMnmO8GfF/taPP/64G93bcedyTjVr1gyAm2++ObcDzJPVq1e76LbdOx588EH2228/wG+PRXLGjx/PqaeeWoAjDV+ABVYF9c8//9CrVy/Am4lItdlmm7nosOWzzZkzx90r7fl77bUXABdeeGFkx5m4qb1HH30UgLPOOguAWrVqMWHCBMBLwK6KrcDYf//9XWLvRhttBMC0adPcH3stCh6mNcuXL3crTr7//nvA7zQtW7bM3cgnT56c7UsXdGpv4sSJgFdB2tiKS+sw7r///rm8RSif4QsvvMC0adMAGDBgQEZvPHfuXO8A/t8pqVOnjvveLVq0CMANAOy1Awr9e2or7cKa1jNW3y3ASr6CnYsfffQR4E9lzZ4923VEateuDcADDzwA4OpLBRTKuWjfLfuuLV++nMaNGwNQr149wK/c/tNPP3H77bcD/vRyWVmZm9o64IADKr1+27ZtAbjyyiszOZxUef0M7TrZuXNn93lZfbBNN93UPc/SKOxcbNiwobvHBFDwe0bq1N4vv/wCeNeeEIXeRvvuderUienTp5d7zDq/c+fOTbvoyAalNsC1lYqWpB6QpvZEREREopCYqT0LQduI2CJpderUqTYSZawuz9SpU11yttWfGjRoEKNHjw79mKNUu3ZtDj/8cMDvve+5556Av7w8iW644YZKP7OlujlGokLVoUOHclGzTNSqVQuAa6+9FvDC0BYtsCTlHEa+kcokElVV8nh15RKS+F21yI5NNdt1BPxkbYue5hiRCoUl66YmkttI3hKsbcn/hAkTXMpAKqtvZtPZSWKRKLuOzJ8/330+qZEoYzMVdn4PGTLEfcZNmzaN/Hj/y2wRmUU+Uxfd2CyLpfBUVQJnn332AWC33XYD4Oeff47mYFMoIiUiIiISUGIiUpZUZgW41l/fO3Srfp2pevXquTIJNspYsWKFG7XZ6yaJJaCnju4t+S4prPim5Z+AX0jNFgwknY10rSDstGnTqFmzJuAvLIhrMUOLNKVGlexn6RLFU6ueJzHqlIljjz0WgJdeeqnAR5IZi+oDrvjkm2++CfgVvtMVgl29enUeji58FSNRVjR10qRJNGnSZK2/f8QRRwDQv39/d59RRCpalhCeGomya84zzzwD+JH9qliOm81a2fegf//+XHfddeEe8P8pIiUiIiISUCLCLytXrnRz2sZWm9h8aDZshDJmzBjAK8BmhcpSyyPEnfXa0y07PvHEE/N9ODmpmPuWKg7lDoL68ssvAbj//vvdaN+WzwNcddVVQPw/L4s6rW2Vb7bbxxx66KG5HFZB9ejRA8AVVY0ri3Km7oloS8OtDILtA5l6rgVYhRcb//77L127dgX8YqNWfPSggw7K6DWsBEbjxo0rrRyT8M2aNcvNTJh27dplFIn64osvAK8E0JAhQwB/9soMHz7cbeG0/fbbh3XYQEI6Uk899ZT7Q1nlZ5vOCqJieLZu3bpu2iUpVq1a5Wppffvtt+Uea9CggauJkgQLFixwYfdUl1xySQGOJhxW08uWHi9evDjt82xJrp30VocqqbLdwDhu9aOyYdNhqXWkjJ2TP/74oxv0FYpd21q2bOl+Zv9tnXorO5LK9otMor59+7qO0/XXXw9k3oEyVvKhW7durhK8lc6x9BAJz6JFi8oNMgGuuOIK14GyzqydW9OnT3c/s85yxd9PtWTJEpYtWwaE35HS1J6IiIhIQLGOSNmIyCIv4C8nziXpz/ZwM61atQq9hxoVS6Q766yz3NSksaW8w4YNS9Ru5UcffXSliFTLli3d0uwkskiLTSPPnDkzbfVyKzD7+OOPA35hxCuuuCJR08wm28KdFZ8XhwhVaWkp48ePB/ypzHSV3S0BuaioqNL0s+3X1qNHD5577rkoDzcntpTcpqAt8g9+lKphw4buc7WK4HFlS93HjBnjIlEBir2WU1JS4q67a9vfTcLVqVMntyDHyndYce10ttlmG3cNtaK4S5cuBbzCzlEtJlNESkRERCSgWEekVq5cCVCuQJzt6JyLqvJV4sz2nbP224g3lRXotChI3NnnauUAUl1//fWxLQWQifXW88YoNioC+PDDD8s9p7S01JV2sMUU999/PwBPP/20+7vYFgdJkpqUXl2UKrVMQsXfy7d3330XgK5du7oIaa570U2cONGVIrGk9AsvvNBte1RolkeUGomqaP78+fTu3RvwS6xYscO4JaQ/8cQTgLdnp20jlqtsc6skmGbNmrl72NSpUwHSFofdfffdAW+vPStRYefYSSed5CJYFjG2iFSLFi3c1khhi3VHKt1KiS233DKn1xw/frwL21tl4ltuuSWn14zaqlWr3Aap6TpQtsnmfffdl9fjCspulgMHDgTg77//do9ZB8T+TZLPPvvMTa/adyvV3nvvXen/7XO1G4DVOZk/fz477bQT4G2QDGRU+yaOrCNl03bWoUqXmF5UVFRtfaoo2YqedAsfcvH1118DXgI0eBWz4zZtm5osb8m8JSUlgPd3+f333wF/Ktp88803rvMfB7bCq6SkJO05GMS4ceNCeR2pXv369ZkyZQoAM2bMALxK+1tvvTXgd2jtOljVBswWdKg4DWud/ygk724lIiIiEhOxjkil27crWxbtmDx5MuAlq1tExEKEUYX7wjJq1KhKieXg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\n"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"We have total of 42000 records in training data. Lets perform necessary pre processing steps-\n\n1. Normalization : Normalize all pixel values to same scale\n2. Augmentation : generate more images by introducing some distortions ( like scaling, zooming, rotating... etc)\n"},{"metadata":{"trusted":true},"cell_type":"code","source":"## Normalization\nX_Train = X_Train / 255.0\nX_Test = X_Test / 255.0","execution_count":8,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Augmentation\nimage = X_Train[r].reshape((28,28))\nplt.imshow(image)","execution_count":9,"outputs":[{"output_type":"execute_result","execution_count":9,"data":{"text/plain":"<matplotlib.image.AxesImage at 0x7f44713eea20>"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 1 Axes>","image/png":"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\n"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"from skimage import transform as tf\n\n# specify x and y coordinates to be used for shifting (mid points)\nshift_x, shift_y = image.shape[0]/2, image.shape[1]/2\n\n# translation by certain units\nmatrix_to_topleft = tf.SimilarityTransform(translation=[-shift_x, -shift_y])\nmatrix_to_center = tf.SimilarityTransform(translation=[shift_x, shift_y])\n\n\n# rotation\nrot_transforms =  tf.AffineTransform(rotation=np.deg2rad(15))\nrot_matrix = matrix_to_topleft + rot_transforms + matrix_to_center\nrot_image = tf.warp(image, rot_matrix)\n\n# scaling \nscale_transforms = tf.AffineTransform(scale=(1.5, 1.5))\nscale_matrix = matrix_to_topleft + scale_transforms + matrix_to_center\nscale_image_zoom_out = tf.warp(image, scale_matrix)\n\nscale_transforms = tf.AffineTransform(scale=(0.8, 0.8))\nscale_matrix = matrix_to_topleft + scale_transforms + matrix_to_center\nscale_image_zoom_in = tf.warp(image, scale_matrix)\n\n# shear transforms\nshear_transforms = tf.AffineTransform(shear=np.deg2rad(20))\nshear_matrix = matrix_to_topleft + shear_transforms + matrix_to_center\nshear_image = tf.warp(image, shear_matrix)","execution_count":10,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"items = [image, rot_image, scale_image_zoom_out, scale_image_zoom_in, shear_image]\n\nf, (ax1, ax2, ax3, ax4, ax5) = plt.subplots(1, 5, sharey=True)\nf.set_figwidth(15)\nax1.imshow(image)\nax2.imshow(rot_image)\nax3.imshow(scale_image_zoom_out)\nax4.imshow(scale_image_zoom_in)\nax5.imshow(shear_image)","execution_count":11,"outputs":[{"output_type":"execute_result","execution_count":11,"data":{"text/plain":"<matplotlib.image.AxesImage at 0x7f4471628e48>"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 1080x288 with 5 Axes>","image/png":"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\n"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"We can achive above transformation using ImageDataGenerator which can then be used to feed images to our model."},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ndatagen = ImageDataGenerator(\n        rotation_range=15,  ## Degree range for random rotations.\n        zoom_range = 0.10,  ## Range for random zoom\n        width_shift_range=0.1, ## fraction of total width\n        height_shift_range=0.1, ## fraction of total height\n        shear_range=0.1,\n)\n\nval_datagen = ImageDataGenerator()","execution_count":12,"outputs":[{"output_type":"stream","text":"Using TensorFlow backend.\n","name":"stderr"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"## Bring target to categorical\nfrom keras.utils.np_utils import to_categorical\n\nlabels = to_categorical(Y_Train, num_classes = 10)","execution_count":13,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"**Lets build our network using keras**"},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D, Flatten, MaxPool2D, Dropout, BatchNormalization, Dense\n\nmodel = Sequential()\n\nmodel.add(Conv2D(32, kernel_size = 3, activation='relu', input_shape = (28, 28, 1)))\nmodel.add(BatchNormalization())\nmodel.add(Conv2D(32, kernel_size = 3, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.2))\n\nmodel.add(Conv2D(64, kernel_size = 3, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Conv2D(64, kernel_size = 3, activation='relu'))\nmodel.add(BatchNormalization())\n\n\nmodel.add(Conv2D(128, kernel_size = 3, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Conv2D(128, kernel_size = 3, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Dropout(0.4))\n\nmodel.add(Conv2D(128, kernel_size = 3, activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(Flatten())\nmodel.add(Dropout(0.2))\nmodel.add(Dense(10, activation='softmax'))\n\nmodel.summary()","execution_count":14,"outputs":[{"output_type":"stream","text":"WARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py:263: colocate_with (from tensorflow.python.framework.ops) is deprecated and will be removed in a future version.\nInstructions for updating:\nColocations handled automatically by placer.\nWARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/keras/backend/tensorflow_backend.py:3445: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\nInstructions for updating:\nPlease use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n_________________________________________________________________\nLayer (type)                 Output Shape              Param #   \n=================================================================\nconv2d_1 (Conv2D)            (None, 26, 26, 32)        320       \n_________________________________________________________________\nbatch_normalization_1 (Batch (None, 26, 26, 32)        128       \n_________________________________________________________________\nconv2d_2 (Conv2D)            (None, 24, 24, 32)        9248      \n_________________________________________________________________\nbatch_normalization_2 (Batch (None, 24, 24, 32)        128       \n_________________________________________________________________\ndropout_1 (Dropout)          (None, 24, 24, 32)        0         \n_________________________________________________________________\nconv2d_3 (Conv2D)            (None, 22, 22, 64)        18496     \n_________________________________________________________________\nbatch_normalization_3 (Batch (None, 22, 22, 64)        256       \n_________________________________________________________________\nconv2d_4 (Conv2D)            (None, 20, 20, 64)        36928     \n_________________________________________________________________\nbatch_normalization_4 (Batch (None, 20, 20, 64)        256       \n_________________________________________________________________\nconv2d_5 (Conv2D)            (None, 18, 18, 128)       73856     \n_________________________________________________________________\nbatch_normalization_5 (Batch (None, 18, 18, 128)       512       \n_________________________________________________________________\nconv2d_6 (Conv2D)            (None, 16, 16, 128)       147584    \n_________________________________________________________________\nbatch_normalization_6 (Batch (None, 16, 16, 128)       512       \n_________________________________________________________________\ndropout_2 (Dropout)          (None, 16, 16, 128)       0         \n_________________________________________________________________\nconv2d_7 (Conv2D)            (None, 14, 14, 128)       147584    \n_________________________________________________________________\nbatch_normalization_7 (Batch (None, 14, 14, 128)       512       \n_________________________________________________________________\nflatten_1 (Flatten)          (None, 25088)             0         \n_________________________________________________________________\ndropout_3 (Dropout)          (None, 25088)             0         \n_________________________________________________________________\ndense_1 (Dense)              (None, 10)                250890    \n=================================================================\nTotal params: 687,210\nTrainable params: 686,058\nNon-trainable params: 1,152\n_________________________________________________________________\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.compile(optimizer=\"adam\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])","execution_count":15,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 50\nepochs = 50\n\ntrain_generator = datagen.flow(\n    X_Train,\n    labels,\n    batch_size=batch_size\n)","execution_count":16,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import ModelCheckpoint, ReduceLROnPlateau\n\nmodel_name = 'model' + '/'\n    \nif not os.path.exists(model_name):\n    os.mkdir(model_name)\n        \nfilepath = model_name + 'model.h5'\n\ncheckpoint = ModelCheckpoint(filepath, monitor='val_loss', verbose=1, save_best_only=False, save_weights_only=False, mode='auto', period=1)\n\nLR = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=2, cooldown=1, verbose=1)\ncallbacks_list = [checkpoint, LR]","execution_count":17,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"## Lets keep 10% of the data for validation\nfrom sklearn.model_selection import train_test_split\n\nX_train, X_val, Y_train, Y_val = train_test_split(X_Train, labels, test_size = 0.1)\n\nmodel_hist = model.fit_generator(train_generator, steps_per_epoch=len(X_train)/batch_size, epochs=epochs, verbose=1, \n                    callbacks=callbacks_list,\n                    validation_data = (X_val,Y_val), class_weight=None, workers=1, initial_epoch=0)","execution_count":18,"outputs":[{"output_type":"stream","text":"WARNING:tensorflow:From /opt/conda/lib/python3.6/site-packages/tensorflow/python/ops/math_ops.py:3066: to_int32 (from tensorflow.python.ops.math_ops) is deprecated and will be removed in a future version.\nInstructions for updating:\nUse tf.cast instead.\nEpoch 1/50\n756/756 [==============================] - 21s 27ms/step - loss: 0.8609 - acc: 0.8782 - val_loss: 0.6774 - val_acc: 0.9405\n\nEpoch 00001: saving model to model/model.h5\nEpoch 2/50\n756/756 [==============================] - 17s 22ms/step - loss: 0.5843 - acc: 0.9402 - val_loss: 0.2631 - val_acc: 0.9726\n\nEpoch 00002: saving model to model/model.h5\nEpoch 3/50\n756/756 [==============================] - 17s 22ms/step - loss: 0.5012 - acc: 0.9521 - val_loss: 0.2584 - val_acc: 0.9745\n\nEpoch 00003: saving model to model/model.h5\nEpoch 4/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.4533 - acc: 0.9580 - val_loss: 0.3698 - val_acc: 0.9681\n\nEpoch 00004: saving model to model/model.h5\nEpoch 5/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.4150 - acc: 0.9629 - val_loss: 0.1786 - val_acc: 0.9852\n\nEpoch 00005: saving model to model/model.h5\nEpoch 6/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.3783 - acc: 0.9666 - val_loss: 0.1893 - val_acc: 0.9831\n\nEpoch 00006: saving model to model/model.h5\nEpoch 7/50\n756/756 [==============================] - 17s 22ms/step - loss: 0.3557 - acc: 0.9690 - val_loss: 0.1817 - val_acc: 0.9826\n\nEpoch 00007: saving model to model/model.h5\n\nEpoch 00007: ReduceLROnPlateau reducing learning rate to 0.0005000000237487257.\nEpoch 8/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.2572 - acc: 0.9764 - val_loss: 0.1138 - val_acc: 0.9898\n\nEpoch 00008: saving model to model/model.h5\nEpoch 9/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.2067 - acc: 0.9813 - val_loss: 0.0911 - val_acc: 0.9900\n\nEpoch 00009: saving model to model/model.h5\nEpoch 10/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.2027 - acc: 0.9802 - val_loss: 0.0441 - val_acc: 0.9952\n\nEpoch 00010: saving model to model/model.h5\nEpoch 11/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.1848 - acc: 0.9815 - val_loss: 0.0893 - val_acc: 0.9902\n\nEpoch 00011: saving model to model/model.h5\nEpoch 12/50\n756/756 [==============================] - 17s 22ms/step - loss: 0.1911 - acc: 0.9815 - val_loss: 0.0837 - val_acc: 0.9912\n\nEpoch 00012: saving model to model/model.h5\n\nEpoch 00012: ReduceLROnPlateau reducing learning rate to 0.0002500000118743628.\nEpoch 13/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.1424 - acc: 0.9861 - val_loss: 0.0479 - val_acc: 0.9945\n\nEpoch 00013: saving model to model/model.h5\nEpoch 14/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.1300 - acc: 0.9871 - val_loss: 0.0351 - val_acc: 0.9950\n\nEpoch 00014: saving model to model/model.h5\nEpoch 15/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.1266 - acc: 0.9870 - val_loss: 0.0630 - val_acc: 0.9943\n\nEpoch 00015: saving model to model/model.h5\nEpoch 16/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.1081 - acc: 0.9879 - val_loss: 0.0345 - val_acc: 0.9962\n\nEpoch 00016: saving model to model/model.h5\nEpoch 17/50\n756/756 [==============================] - 17s 22ms/step - loss: 0.1160 - acc: 0.9875 - val_loss: 0.0315 - val_acc: 0.9962\n\nEpoch 00017: saving model to model/model.h5\nEpoch 18/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.1059 - acc: 0.9889 - val_loss: 0.0390 - val_acc: 0.9955\n\nEpoch 00018: saving model to model/model.h5\nEpoch 19/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.1101 - acc: 0.9876 - val_loss: 0.0282 - val_acc: 0.9952\n\nEpoch 00019: saving model to model/model.h5\nEpoch 20/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.1074 - acc: 0.9884 - val_loss: 0.0304 - val_acc: 0.9964\n\nEpoch 00020: saving model to model/model.h5\nEpoch 21/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.0973 - acc: 0.9889 - val_loss: 0.0260 - val_acc: 0.9969\n\nEpoch 00021: saving model to model/model.h5\nEpoch 22/50\n756/756 [==============================] - 17s 22ms/step - loss: 0.0903 - acc: 0.9888 - val_loss: 0.0223 - val_acc: 0.9964\n\nEpoch 00022: saving model to model/model.h5\nEpoch 23/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0845 - acc: 0.9899 - val_loss: 0.0304 - val_acc: 0.9943\n\nEpoch 00023: saving model to model/model.h5\nEpoch 24/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0887 - acc: 0.9892 - val_loss: 0.0161 - val_acc: 0.9967\n\nEpoch 00024: saving model to model/model.h5\nEpoch 25/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.0851 - acc: 0.9894 - val_loss: 0.0180 - val_acc: 0.9979\n\nEpoch 00025: saving model to model/model.h5\nEpoch 26/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0776 - acc: 0.9903 - val_loss: 0.0238 - val_acc: 0.9969\n\nEpoch 00026: saving model to model/model.h5\n\nEpoch 00026: ReduceLROnPlateau reducing learning rate to 0.0001250000059371814.\nEpoch 27/50\n756/756 [==============================] - 16s 22ms/step - loss: 0.0706 - acc: 0.9908 - val_loss: 0.0129 - val_acc: 0.9981\n\nEpoch 00027: saving model to model/model.h5\nEpoch 28/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0637 - acc: 0.9915 - val_loss: 0.0152 - val_acc: 0.9967\n\nEpoch 00028: saving model to model/model.h5\nEpoch 29/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0513 - acc: 0.9928 - val_loss: 0.0129 - val_acc: 0.9971\n\nEpoch 00029: saving model to model/model.h5\n\nEpoch 00029: ReduceLROnPlateau reducing learning rate to 6.25000029685907e-05.\nEpoch 30/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0567 - acc: 0.9925 - val_loss: 0.0106 - val_acc: 0.9971\n\nEpoch 00030: saving model to model/model.h5\nEpoch 31/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0507 - acc: 0.9929 - val_loss: 0.0092 - val_acc: 0.9988\n\nEpoch 00031: saving model to model/model.h5\nEpoch 32/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0479 - acc: 0.9932 - val_loss: 0.0082 - val_acc: 0.9986\n\nEpoch 00032: saving model to model/model.h5\nEpoch 33/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0475 - acc: 0.9935 - val_loss: 0.0050 - val_acc: 0.9993\n\nEpoch 00033: saving model to model/model.h5\nEpoch 34/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0421 - acc: 0.9936 - val_loss: 0.0054 - val_acc: 0.9995\n\nEpoch 00034: saving model to model/model.h5\nEpoch 35/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0416 - acc: 0.9934 - val_loss: 0.0070 - val_acc: 0.9993\n\nEpoch 00035: saving model to model/model.h5\n\nEpoch 00035: ReduceLROnPlateau reducing learning rate to 3.125000148429535e-05.\nEpoch 36/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0473 - acc: 0.9932 - val_loss: 0.0058 - val_acc: 0.9995\n\nEpoch 00036: saving model to model/model.h5\nEpoch 37/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0370 - acc: 0.9935 - val_loss: 0.0057 - val_acc: 0.9990\n\nEpoch 00037: saving model to model/model.h5\n\nEpoch 00037: ReduceLROnPlateau reducing learning rate to 1.5625000742147677e-05.\nEpoch 38/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0430 - acc: 0.9936 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00038: saving model to model/model.h5\nEpoch 39/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.0371 - acc: 0.9944 - val_loss: 0.0049 - val_acc: 0.9995\n\nEpoch 00039: saving model to model/model.h5\nEpoch 40/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0334 - acc: 0.9947 - val_loss: 0.0054 - val_acc: 0.9993\n\nEpoch 00040: saving model to model/model.h5\n\nEpoch 00040: ReduceLROnPlateau reducing learning rate to 7.812500371073838e-06.\nEpoch 41/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0394 - acc: 0.9942 - val_loss: 0.0052 - val_acc: 0.9993\n\nEpoch 00041: saving model to model/model.h5\nEpoch 42/50\n","name":"stdout"},{"output_type":"stream","text":"756/756 [==============================] - 17s 23ms/step - loss: 0.0377 - acc: 0.9937 - val_loss: 0.0049 - val_acc: 0.9995\n\nEpoch 00042: saving model to model/model.h5\n\nEpoch 00042: ReduceLROnPlateau reducing learning rate to 3.906250185536919e-06.\nEpoch 43/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0363 - acc: 0.9940 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00043: saving model to model/model.h5\nEpoch 44/50\n756/756 [==============================] - 15s 21ms/step - loss: 0.0318 - acc: 0.9946 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00044: saving model to model/model.h5\n\nEpoch 00044: ReduceLROnPlateau reducing learning rate to 1.9531250927684596e-06.\nEpoch 45/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.0386 - acc: 0.9942 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00045: saving model to model/model.h5\nEpoch 46/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0384 - acc: 0.9942 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00046: saving model to model/model.h5\n\nEpoch 00046: ReduceLROnPlateau reducing learning rate to 9.765625463842298e-07.\nEpoch 47/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0337 - acc: 0.9944 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00047: saving model to model/model.h5\nEpoch 48/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0376 - acc: 0.9943 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00048: saving model to model/model.h5\n\nEpoch 00048: ReduceLROnPlateau reducing learning rate to 4.882812731921149e-07.\nEpoch 49/50\n756/756 [==============================] - 16s 21ms/step - loss: 0.0372 - acc: 0.9941 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00049: saving model to model/model.h5\nEpoch 50/50\n756/756 [==============================] - 15s 20ms/step - loss: 0.0355 - acc: 0.9943 - val_loss: 0.0048 - val_acc: 0.9995\n\nEpoch 00050: saving model to model/model.h5\n\nEpoch 00050: ReduceLROnPlateau reducing learning rate to 2.4414063659605745e-07.\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.plot(model_hist.history['loss'])\nplt.plot(model_hist.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('Loss')\nplt.xlabel('Epochs')\nplt.legend(['train', 'test'])\nplt.show()","execution_count":19,"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 1 Axes>","image/png":"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\n"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_Test.shape","execution_count":20,"outputs":[{"output_type":"execute_result","execution_count":20,"data":{"text/plain":"(28000, 28, 28, 1)"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"predicted_digits = model.predict(X_Test).argmax(axis=-1)\nresult_df = pd.DataFrame()\nresult_df['ImageId'] = list(range(1,X_Test.shape[0] + 1))\nresult_df['Label'] = predicted_digits\nresult_df.to_csv(\"submission.csv\", index = False)","execution_count":22,"outputs":[]}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}