{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np \nimport pandas as pd \n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Conv2D, Flatten, MaxPooling2D, Dropout, BatchNormalization\nfrom keras.callbacks import EarlyStopping\nfrom keras.utils import to_categorical\n\nimport matplotlib.pyplot as plt\n%matplotlib inline\n\nfrom sklearn.metrics import confusion_matrix, classification_report, accuracy_score\nfrom mlxtend.plotting import plot_confusion_matrix","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"train = pd.read_csv(\"../input/Kannada-MNIST/train.csv\")\ntest = pd.read_csv(\"../input/Kannada-MNIST/test.csv\")\nsample_sub = pd.read_csv(\"../input/Kannada-MNIST/sample_submission.csv\")\ndig = pd.read_csv(\"../input/Kannada-MNIST/Dig-MNIST.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train = train.iloc[:, 1:].values.astype(np.float32)\ny_train = train.iloc[:, 0].values\n\nX_test = test.iloc[:, 1:].values.astype(np.float32)\nid_test = test.iloc[:, 0].values\n\nX_dig = dig.iloc[:, 1:].values.astype(np.float32)\ny_dig = dig.iloc[:, 0].values","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's scale the values to 0 mean and 1 std, and reshape them to proper tensors. "},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train = X_train / 255.0\nX_train = X_train.reshape(X_train.shape[0], 28, 28, 1)\n\nX_test = X_test / 255.0\nX_test = X_test.reshape(X_test.shape[0], 28, 28, 1)\n\nX_dig = X_dig / 255.0\nX_dig = X_dig.reshape(X_dig.shape[0], 28, 28, 1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now we convert the target labels to one-hot encoding (for better NN processing). "},{"metadata":{"trusted":true},"cell_type":"code","source":"y_train_oh = to_categorical(y_train)\ny_dig_oh = to_categorical(y_dig)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":""},{"metadata":{},"cell_type":"markdown","source":"Let's create a rather simple CNN model. "},{"metadata":{"trusted":true},"cell_type":"code","source":"np.random.seed(420)\n\nmodel = Sequential()\n\nmodel.add(Conv2D(32, input_shape=(28, 28, 1), kernel_size=(3, 3), padding=\"same\", activation=\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D())\nmodel.add(Dropout(0.25))\n\nmodel.add(Conv2D(64, kernel_size=(3, 3), padding=\"same\", activation=\"relu\"))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D())\nmodel.add(Dropout(0.25))\n\nmodel.add(Flatten())\nmodel.add(Dense(128, activation=\"relu\"))\nmodel.add(Dropout(0.25))\nmodel.add(Dense(64, activation=\"relu\"))\nmodel.add(Dropout(0.25))\nmodel.add(Dense(10, activation=\"softmax\"))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We can now train the model, using the *Dig* dataset as validation data. This dataset is a bit different from the training data, so prediction performance will be far from optimal, but it can be useful to tweak the model and tune it for better results. "},{"metadata":{"trusted":true},"cell_type":"code","source":"early_stop = EarlyStopping(monitor=\"loss\", patience=3, restore_best_weights=True)\nmodel.compile(optimizer=\"adam\", loss=\"categorical_crossentropy\", metrics=[\"accuracy\"])\nhistory = model.fit(X_train, y_train_oh, epochs=20, batch_size=32, validation_data=(X_dig, y_dig_oh),\n                    callbacks=[early_stop], verbose=0)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's check the performance of the model on training and evaluation data. "},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.rcParams[\"figure.figsize\"] = (20, 10)\nplt.rcParams[\"figure.facecolor\"] = \"white\"\n\nplt.subplot(1, 2, 1)\nplt.plot(history.history['acc'])\nplt.plot(history.history['val_acc'])\nplt.title('Model Accuracy')\nplt.ylabel('accuracy')\nplt.xlabel('epoch')\nplt.legend(['train', \"dig\"], loc='upper left')\n\nplt.subplot(1, 2, 2)\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])\nplt.title('Model Loss')\nplt.ylabel('loss')\nplt.xlabel('epoch')\nplt.legend(['train', \"dig\"], loc='upper left')\n\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"It seems like the model might need some more adjustments to avoid overfitting, but the test set should be more similar to the training data than the Dig set, so for the time being I will stick with it and try to predict labels. "},{"metadata":{"trusted":true},"cell_type":"code","source":"y_pred_oh = model.predict(X_test)\ny_pred = np.argmax(y_pred_oh, axis=1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_pred = pd.DataFrame({\"id\": id_test, \"label\": y_pred})\ndf_pred.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"df_pred.to_csv(\"subm_v1.csv\", index=False, header=True)","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":1}