{"cells":[{"metadata":{},"cell_type":"markdown","source":"Let's start with importing some libraries and functions:\n- Numpy: linear algebra and math operations, here used mostly for reshaping data\n- Matplotlib: data visualization\n- Pandas: Data manipulation, reading/saving data\n- train_test_split from sklearn: splitting dataset training and test subsets","execution_count":null},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport os\nimport seaborn as sns\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"training_dataset = pd.read_csv('/kaggle/input/digit-recognizer/train.csv', header=0)\ntraining_dataset.head()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# *EXPLORATORY DATA ANALYSIS*","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Let's see proportions of each class in 'label' column:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"bincount = np.bincount(training_dataset.label)\nprint(dict(zip(np.nonzero(bincount)[0], bincount)))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now, I will split original training dataset to train and test subsets - file 'test.csv' does not contain a 'label' column.\nParameter 'stratify' will be used in orde to make sure that our target variable has the same proportions in both train and test sets.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"y = training_dataset['label'].copy()\nX = training_dataset.drop(['label'], axis='columns')\ndel training_dataset\nX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1, stratify=y)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('X train shape: {}'.format(X_train.shape))\nprint('y train shape: {}'.format(y_train.shape))\nprint('X test shape: {}'.format(X_test.shape))\nprint('y test shape: {}'.format(y_test.shape))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's see if class proportions in both training and test sets are more or less equal:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"train_class_counter = dict(zip(np.nonzero(np.bincount(y_train))[0], np.bincount(y_train)))\nprint(train_class_counter)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"test_class_counter = dict(zip(np.nonzero(np.bincount(y_test))[0], np.bincount(y_test)))\nprint(test_class_counter)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Seems like all sets have correct shape and size. Now, let's turn our data into NumPy arrays, in order to plot some digits along with labels. ","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train = np.array(X_train)\ny_train = np.array(y_train)\nX_test = np.array(X_test)\ny_test = np.array(y_test)\n\nX_train = X_train.reshape(-1, 28, 28)\nX_test = X_test.reshape(-1, 28, 28)\n\nprint('X train shape: {}'.format(X_train.shape))\nprint('y train shape: {}'.format(y_train.shape))\nprint('X test shape: {}'.format(X_test.shape))\nprint('y test shape: {}'.format(y_test.shape))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's plot some digits along with labels from the training set.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_digits(X=X_train, y=y_train, n=10, figsize=(20,3)):\n    \n    fig, axes = plt.subplots(1, n, figsize=figsize)\n    for i in range(n):\n        ax = axes[i]\n        ax.imshow(X[i], cmap='gray_r')\n        ax.set_title(str(y[i]), fontsize=12, color='white')\n    plt.tight_layout()\n    plt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_digits(n=13, figsize=(26, 2))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Next thing that we should do is normalization of our X-es, both train and test.\nThis operation should make our neural network learn much faster.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train = X_train / 255.\nX_test = X_test / 255.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's plot our train digits again to see if inputs were normalized correctly.","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"show_digits(n=13, figsize=(26, 2))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# *BUILDING A NN MODEL IN TENSORFLOW 2.0 AND KERAS*","execution_count":null},{"metadata":{},"cell_type":"markdown","source":"Let's import some essential functions from tensorflow.keras:","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from tensorflow.keras.layers import Flatten, Dense, Dropout\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.optimizers import Adam","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model = Sequential([\n    Flatten(input_shape=(28, 28)),\n    Dense(units=128, activation='relu'),\n    Dropout(0.2),\n    Dense(units=64, activation='relu'),\n    Dropout(0.15),\n    Dense(units=10, activation='softmax')\n])\n\noptim = Adam(learning_rate=0.0001, epsilon=1e-8)\n\nmodel.compile(optimizer=optim, loss='sparse_categorical_crossentropy', metrics=['accuracy'])\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = model.fit(X_train, y_train, epochs=200, batch_size=1024)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.evaluate(X_test, y_test, verbose=2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"metrics = pd.DataFrame(history.history)\nmetrics.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = range(1, 201)\nf, axes = plt.subplots(1, 2, figsize=(16, 8))\nsns.set()\nsns.lineplot(x=epochs, y=metrics.loss, ax=axes[0]).set(title='Training loss', xlabel='Epochs', ylabel='Loss value')\nsns.lineplot(x=epochs, y=metrics.accuracy, ax=axes[1], color='orange').set(title='Training accuracy', xlabel='Epochs', ylabel='Accuracy value')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_data = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\nsubmission_data.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_data = np.array(submission_data)\nsubmission_data = submission_data.reshape(-1, 28, 28)\nprint(submission_data[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_data = submission_data / 255.\nsubmission_classes = model.predict_classes(submission_data)\nprint(submission_classes[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_classes.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sub = pd.read_csv('/kaggle/input/digit-recognizer/test.csv')\nsub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sample_sub = pd.read_csv('/kaggle/input/digit-recognizer/sample_submission.csv')\nsample_sub.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"ids = [i for i in range(1, sub.shape[0] + 1)]\nsubmission = pd.DataFrame({'ImageId': ids, 'Label': submission_classes})\nsubmission.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"filename = 'Mnist_submission.csv'\nsubmission.to_csv(filename, index=False)","execution_count":null,"outputs":[]}],"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":4,"nbformat_minor":4}