{"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":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"}],"dockerImageVersionId":30626,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"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-12T06:42:37.480310Z","iopub.execute_input":"2024-01-12T06:42:37.480742Z","iopub.status.idle":"2024-01-12T06:42:37.814621Z","shell.execute_reply.started":"2024-01-12T06:42:37.480708Z","shell.execute_reply":"2024-01-12T06:42:37.813300Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Loading the Dataset.**\n\nThe above code sets up our work environment. It downloads pandas and numpy, two basic libraries for data handling and numerical computations, and also prints the complete file paths of the required input files. The next step is to load the datset for our own use.","metadata":{}},{"cell_type":"code","source":"train_dataset = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\nX = train_dataset.drop(\"label\", axis=1)  # Features (pixel values)\ny = train_dataset[\"label\"] ","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:42:41.214712Z","iopub.execute_input":"2024-01-12T06:42:41.215396Z","iopub.status.idle":"2024-01-12T06:42:43.888864Z","shell.execute_reply.started":"2024-01-12T06:42:41.215364Z","shell.execute_reply":"2024-01-12T06:42:43.888217Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Displaying Images**\nThis next bit imports matplotlib, which is a very useful python library for all your graphing needs!(read: data visualization). I have set up a 'for' loop to display the first five images. You might have noticed the 'iloc' operator used in the plt.imshow() method. This is the 'index location' operator of lists, used to slice them based on their indexes. The 'loc' operator uses column/row names. Understanding of these two is crucial to manipulate datasets effectively, they're both incredibly powerful.","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfor i in range(5):\n    plt.figure()\n    plt.imshow(X.iloc[i, :].values.reshape(28, 28), cmap='gray') \n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:45:27.523763Z","iopub.execute_input":"2024-01-12T06:45:27.524097Z","iopub.status.idle":"2024-01-12T06:45:28.334345Z","shell.execute_reply.started":"2024-01-12T06:45:27.524071Z","shell.execute_reply":"2024-01-12T06:45:28.333471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images_np = np.array(X)\nlabels_np = np.array(y)\nprint(images_np.shape, labels_np.shape)","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:45:43.740941Z","iopub.execute_input":"2024-01-12T06:45:43.741335Z","iopub.status.idle":"2024-01-12T06:45:43.787917Z","shell.execute_reply.started":"2024-01-12T06:45:43.741307Z","shell.execute_reply":"2024-01-12T06:45:43.786918Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Reshaping and Normalisation.**\nWe must be extremely mindful of the shape of our numpy array throughout. Most of those us who use Tensorflow are bound to run into these quite frequently! But fret not, for a little bit of practice can go a long way in solving these! Refer to the outut of the cell above. The first dimension indicates a **2d** numpy array for images, in which there are ","metadata":{}},{"cell_type":"markdown","source":"#** Reshaping and Normalisation**\nWe must be extremely mindful of the shape of our numpy array throughout. Most of us who use Tensorflow are bound to run into these quite frequently! But fret not, for a little bit of practice can go a long way in solving these! Refer to the outut of the cell above. The first dimension indicates a 2d numpy array for images, in which there are 420000 training examples, and 784 is the number of pixels contained by each image. This means that the pixels of each image are all stacked up, but we need to separate them into no.of pixels by height, no.of pixels by width, and no. of color channels. Since it is specified that images are of 28X28 size, and they are grayscale - so one color channel.\n\nNormalisation is done to ensure uniformity among values which makes the model converge quicker!","metadata":{}},{"cell_type":"code","source":"images_np = images_np.reshape(-1, 28, 28, 1)\nimages_np = images_np / 255.0","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:45:47.520588Z","iopub.execute_input":"2024-01-12T06:45:47.520951Z","iopub.status.idle":"2024-01-12T06:45:47.597621Z","shell.execute_reply.started":"2024-01-12T06:45:47.520923Z","shell.execute_reply":"2024-01-12T06:45:47.596336Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Import Tensorflow.**\nNext, we import tensorflow, which is one of the most popular machine learning frameworks. The Keras API built on top of it is especially useful for building convolutional neural networks, which is the architecture required to solve the problem at hand. \nNotice that I have converted my pandas dataframe into a numpy array. This is because tensorflow only works on numpy arrays. It is an extremely important step.","metadata":{}},{"cell_type":"markdown","source":"# **Model architecture**\nMy code above has 4 layers - 2 convolutional layers, and 2 pooling layers. A convolution helps in edge detection, which is the fundamental concept of Computer Vision. It is made to go through filters of the specified size and no. of units are 64 and 32 respectively. Pooling recognises the largest pixels in the specified kernel size, and extracts it from the image. This serves two purposes - paring down image size making it less compilacted, and aids in feature extraction by allowing the model to focus only on the most important parts of the image.\n\nTo construct a model architecture that works well for the image is a skill honed by practice and intuition. Initially, it is best practice to look up architectures that work well, and implement them. CNNs are very flexible, and a lot of the lower layers are common in all image detectors, which is very convenient for us.","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import layers, models\nfrom sklearn.model_selection import train_test_split\nimport numpy as np\nimport pandas as pd\n\n# Load your dataset\ntrain_dataset = pd.read_csv(\"/kaggle/input/digit-recognizer/train.csv\")\nX = train_dataset.drop(\"label\", axis=1)\ny = train_dataset[\"label\"]\n\nimages_np = np.array(X)\nlabels_np = np.array(y)\n\nimages_np = images_np.reshape(-1, 28, 28, 1)\nimages_np = images_np / 255.0\n\nX_train, X_val, y_train, y_val = train_test_split(images_np, labels_np, test_size=0.2, random_state=42)\n\ndef create_custom_model():\n    model = models.Sequential()\n\n    # Convolutional layers\n    model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)))\n    model.add(layers.Conv2D(32, (3, 3), activation='relu'))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Dropout(0.25))\n\n    model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n    model.add(layers.Conv2D(64, (3, 3), activation='relu'))\n    model.add(layers.MaxPooling2D((2, 2)))\n    model.add(layers.Dropout(0.25))\n\n    # Flatten layer\n    model.add(layers.Flatten())\n\n    # Dense layers\n    model.add(layers.Dense(8192, activation='relu'))\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(2048, activation='relu'))\n    model.add(layers.Dropout(0.5))\n    model.add(layers.Dense(10, activation='softmax'))\n\n    return model\n\n# Create the model\ncustom_model = create_custom_model()","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:45:50.622317Z","iopub.execute_input":"2024-01-12T06:45:50.622650Z","iopub.status.idle":"2024-01-12T06:46:05.686125Z","shell.execute_reply.started":"2024-01-12T06:45:50.622624Z","shell.execute_reply":"2024-01-12T06:46:05.685202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Compile the model\ncustom_model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])\n","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:47:54.553314Z","iopub.execute_input":"2024-01-12T06:47:54.553664Z","iopub.status.idle":"2024-01-12T06:47:54.572460Z","shell.execute_reply.started":"2024-01-12T06:47:54.553633Z","shell.execute_reply":"2024-01-12T06:47:54.571043Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train the model with validation data\nhistory = custom_model.fit(x=X_train, y=y_train, validation_data=(X_val, y_val), batch_size=32, epochs=10)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-12T06:47:59.422690Z","iopub.execute_input":"2024-01-12T06:47:59.423073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = pd.read_csv(\"/kaggle/input/digit-recognizer/test.csv\")\ntest_dataset.drop([])\ntest_np = np.array(test_dataset)\ntest_np = test_np.reshape(-1, 28, 28, 1)\ntest_np = test_np / 255.0\n","metadata":{"execution":{"iopub.status.busy":"2024-01-08T19:20:38.700225Z","iopub.execute_input":"2024-01-08T19:20:38.700784Z","iopub.status.idle":"2024-01-08T19:20:50.007992Z","shell.execute_reply.started":"2024-01-08T19:20:38.700745Z","shell.execute_reply":"2024-01-08T19:20:50.006643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Predicitions galore!**\nNow is the moment of truth where we evaluate how well our model works for similar data. Don't worry if you don't get the best results on the first try! Machine Learning is an iterative process that involves a lot of fine tuning to get the model to where we want it to be. Through constant practice, you will hone your intuition to the point where you can tune the model to work just fine. Happy learning!","metadata":{}},{"cell_type":"code","source":"results = custom_model.predict(test_np)\n\nresults = np.argmax(results,axis = 1)\nresults = pd.Series(results,name=\"Label\")\n\nsubmission = pd.concat([pd.Series(range(1,28001),name = \"ImageId\"),results],axis = 1)\nsubmission.to_csv('Submission.csv',index=False)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-08T19:35:24.892287Z","iopub.execute_input":"2024-01-08T19:35:24.892759Z","iopub.status.idle":"2024-01-08T19:35:33.987243Z","shell.execute_reply.started":"2024-01-08T19:35:24.892726Z","shell.execute_reply":"2024-01-08T19:35:33.985904Z"},"trusted":true},"execution_count":null,"outputs":[]}]}