{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Setup"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport tensorflow as tf\nimport csv\n%matplotlib inline\nimport matplotlib.pyplot as plt\nfrom tensorflow import keras\nfrom functools import partial","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Load and create dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"with open(\"/kaggle/input/digit-recognizer/train.csv\") as f:\n    reader = csv.reader(f, delimiter=',')\n    next(reader)\n    dataset = [row for row in reader]","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"labels, images = np.array_split(np.array(dataset, dtype='float32'), [1,], axis=1)\nlabels, images = labels.flatten(), images.reshape((len(images), 28, 28))[..., np.newaxis]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"split_ratio = 0.1\ndata_set = tf.data.Dataset.from_tensor_slices((images, labels)).shuffle(len(labels))\ntrain_set = data_set.take(int(len(labels)*(1-split_ratio))).batch(32).cache().prefetch(1)\nval_set = data_set.skip(len(labels)-int(len(labels)*(1-split_ratio))).batch(32).cache().prefetch(1)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Preprocessing layers for image augmentation"},{"metadata":{"trusted":true},"cell_type":"code","source":"data_augmentation = keras.models.Sequential([\n    keras.layers.experimental.preprocessing.Rescaling(1./255, input_shape=(28, 28, 1)),\n    keras.layers.experimental.preprocessing.RandomRotation(0.1),\n    keras.layers.experimental.preprocessing.RandomZoom(0.1),\n    keras.layers.experimental.preprocessing.RandomTranslation(0.1, 0.1)\n])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Create model and pretrain"},{"metadata":{"trusted":true},"cell_type":"code","source":"DefaultConv2D = partial(keras.layers.Conv2D, kernel_size=3, activation='relu', padding='same')\nmodel = keras.models.Sequential([\n    data_augmentation,\n    DefaultConv2D(filters=32),\n    DefaultConv2D(filters=32),\n    keras.layers.MaxPool2D(),\n    DefaultConv2D(filters=64),\n    DefaultConv2D(filters=64),\n    keras.layers.MaxPool2D(),\n    DefaultConv2D(filters=128),\n    DefaultConv2D(filters=128),\n    keras.layers.MaxPool2D(),\n    keras.layers.Dropout(0.2),\n    keras.layers.Flatten(),\n    keras.layers.Dense(128, activation='relu'),\n    keras.layers.Dropout(0.5),\n    keras.layers.Dense(256, activation='relu'),\n    keras.layers.Dropout(0.5),\n    keras.layers.Dense(10, activation='softmax')\n])\nmodel.compile(optimizer=keras.optimizers.Adam(),\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\nn_epochs=20\nlr_schedule = keras.callbacks.LearningRateScheduler(lambda epoch: 1e-6 * 10 ** (epoch / n_epochs * 5))\nhistory = model.fit(train_set, epochs=n_epochs, callbacks=[lr_schedule])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.loglog(history.history[\"lr\"], history.history[\"loss\"])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Train the model"},{"metadata":{"trusted":true},"cell_type":"code","source":"DefaultConv2D = partial(keras.layers.Conv2D, kernel_size=3, activation='relu', padding='same')\nmodel = keras.models.Sequential([\n    data_augmentation,\n    DefaultConv2D(filters=32),\n    DefaultConv2D(filters=32),\n    keras.layers.MaxPool2D(),\n    DefaultConv2D(filters=64),\n    DefaultConv2D(filters=64),\n    keras.layers.MaxPool2D(),\n    DefaultConv2D(filters=128),\n    DefaultConv2D(filters=128),\n    keras.layers.MaxPool2D(),\n    keras.layers.Dropout(0.2),\n    keras.layers.Flatten(),\n    keras.layers.Dense(128, activation='relu'),\n    keras.layers.Dropout(0.5),\n    keras.layers.Dense(256, activation='relu'),\n    keras.layers.Dropout(0.5),\n    keras.layers.Dense(10, activation='softmax')\n])\nmodel.compile(optimizer=keras.optimizers.Adam(1e-3),\n              loss='sparse_categorical_crossentropy',\n              metrics=['accuracy'])\nn_epochs=200\nhistory = model.fit(train_set,validation_data=val_set, \n                    epochs=n_epochs,\n                    callbacks=[keras.callbacks.EarlyStopping(patience=10, restore_best_weights=True),\n                               keras.callbacks.ReduceLROnPlateau(patience=5, factor=0.5, min_lr=1e-4)])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(16, 8))\nplt.subplot(1,2,1)\nplt.plot(history.history['accuracy'])\nplt.plot(history.history['val_accuracy'])\n\nplt.subplot(1,2,2)\nplt.plot(history.history['loss'])\nplt.plot(history.history['val_loss'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Test and submit"},{"metadata":{"trusted":true},"cell_type":"code","source":"with open(\"/kaggle/input/digit-recognizer/test.csv\") as f:\n    reader = csv.reader(f, delimiter=',')\n    next(reader)\n    dataset = [row for row in reader]\n\ntest_imgs = np.array(dataset, dtype='float32').reshape((len(dataset), 28, 28))[..., np.newaxis]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import pandas as pd\n\npredictions = [np.argmax(p) for p in model.predict(test_imgs)]\nids = np.arange(len(dataset)) + 1\nsubmission_df = pd.DataFrame({'ImageId':ids, 'label':predictions})\nsubmission_df.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\", 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}