{"cells":[{"metadata":{},"cell_type":"markdown","source":"# 1. Import Libraries","execution_count":null},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nfrom keras.preprocessing.image import ImageDataGenerator, load_img\nfrom keras.utils import to_categorical\nfrom sklearn.model_selection import train_test_split\nimport matplotlib.pyplot as plt\nimport random\nimport os\nprint(os.listdir(\"../input/digit-recognizer\"))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. Define Image PROPERTIES","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"FAST_RUN = False\n# following properties are mentioned in \nIMAGE_WIDTH=28\nIMAGE_HEIGHT=28\nIMAGE_SIZE=(IMAGE_WIDTH, IMAGE_HEIGHT)\n# channel refer to number of colors, here GrayScale\nIMAGE_CHANNELS=1","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. Prepare dataset for training model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"# import important data\ntrain_data = pd.read_csv(\"../input/digit-recognizer/train.csv\")\ntest_data = pd.read_csv(\"../input/digit-recognizer/test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_data.head()\n# it is seen that total pixel of an image are 784 (i.e 28x28 matrix)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# function to display image\ndef show_image(train_image, label, index):\n    \n    #converting 784x1 to 28x28\n    image_shaped = train_image.values.reshape(28,28)\n    \n    #3 - no. of rows, 6 - no. of columns\n    plt.subplot(3, 6, index+1)\n    \n    #plotting grayscale image\n    plt.imshow(image_shaped, cmap=plt.cm.gray)\n    plt.title(label)\n\n\n#size of total figure\nplt.figure(figsize=(18, 8))\nsample_image = train_data.sample(18).reset_index(drop=True)\nfor index, row in sample_image.iterrows():\n    # storing 1st columns i.e. label column\n    label = row['label']\n    # storing all columns except label\n    image_pixels = row.drop('label')\n    show_image(image_pixels, label, index)\n\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 4. Create a Sequential Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.models import Sequential\nfrom keras.layers import Conv2D,MaxPooling2D,\\\n     Dropout,Flatten,Dense,Activation,\\\n     BatchNormalization\n\n# Keras defines a sequential model as a sequential stack of linear layers.\nmodel=Sequential()\n\n# here we using 32 filter layers and kernel size of (3,3), with relu activation function (max(0,x))\n# Batch normalization() is a technique for improving the speed, performance, and stability of cnn.\n# max pooling reduces the dimensionality of images by reducing the number of pixels in the output from previous cnn\n# pool size define size of filter\n\n\n#1st layer is input layer\nmodel.add(Conv2D(32,(3,3),activation='relu',input_shape=(IMAGE_WIDTH,IMAGE_HEIGHT,IMAGE_CHANNELS)))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\n\n# 2nd layer\nmodel.add(Conv2D(64,(3,3),activation='relu'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(2,2)))\n\n\n# Flatten convert matrix into single array\nmodel.add(Flatten())\nmodel.add(Dense(512,activation='relu'))\nmodel.add(BatchNormalization())\n\n\n# Finally we compile our model with rsmprop optimizer\nmodel.add(Dense(10,activation='softmax'))\nmodel.compile(loss='categorical_crossentropy',\n  optimizer='rmsprop',metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 5. Analyzing model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model.summary()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 6. CALLBACK","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.callbacks import EarlyStopping, ReduceLROnPlateau\n\n#One way to avoid overfitting is to terminate the process early using earlystop\nearlystop = EarlyStopping(patience = 10)\n\n# Following line will reduce learning rate when a metric has stopped improving. \nlearning_rate_reduction = ReduceLROnPlateau(monitor = 'val_acc',patience = 2,verbose = 1,factor = 0.5,min_lr = 0.00001)\n\ncallbacks = [earlystop,learning_rate_reduction]\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 7. Manage DATA","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"x = train_data.drop(columns=['label']).values.reshape(train_data.shape[0],28,28,1)\ny = to_categorical(train_data['label'])\n\n#using train_test_split to split your data\nx_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.1)\n\n# batch_size specifies how many training samples should be sent to the model at once.\nbatch_size=32","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"\n# 8. Training & Validation Generator (DATA AUGMENTATION)","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"from keras.preprocessing.image import ImageDataGenerator\n\ntrain_datagen = ImageDataGenerator(\n    rotation_range=10,\n    rescale=1./255,\n    shear_range=0.1,\n    zoom_range=0.1,\n    width_shift_range=0.1,\n    height_shift_range=0.1\n)\ntrain_datagen.fit(x_train)\ntrain_generator = train_datagen.flow(\n    x_train,\n    y_train,\n    batch_size=batch_size\n)\n\nvalidation_datagen = ImageDataGenerator(rescale=1./255)\ntrain_datagen.fit(x_test)\nvalidation_generator = validation_datagen.flow(\n    x_test,\n    y_test\n    \n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 9. Training Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"model.fit_generator(\n    train_generator, \n    steps_per_epoch=len(x_train) // batch_size, \n    validation_data=validation_generator,\n    validation_steps=len(x_test) // batch_size,\n    epochs=10,\n    callbacks=callbacks\n)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 10. Evaluate Model","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"x_test_recaled = (x_test.astype(\"float32\") / 255)\nscores = model.evaluate(x_test_recaled, y_test, verbose=0)\nprint(\"%s: %.2f%%\" % (model.metrics_names[1], scores[1]*100))\nprint(\"%s: %.2f%%\" % (model.metrics_names[0], scores[0]*100))","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 11. Prediction","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"test_digit_data = test_data.values.reshape(test_data.shape[0],28,28,1).astype(\"float32\") / 255\npredictions = model.predict(test_digit_data)\nresults = np.argmax(predictions, axis = 1)\n\nplt.figure(figsize=(18, 8))\nsample_test = test_data.head(18)\nfor index, image_pixels in sample_test.iterrows():\n    label = results[index]\n    show_image(image_pixels, label, index)\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 12. Create submission file","execution_count":null},{"metadata":{"trusted":true},"cell_type":"code","source":"submissions = pd.read_csv(\"../input/digit-recognizer/sample_submission.csv\")\nsubmissions['Label'] = results\nsubmissions.to_csv('sample_submission.csv', index = False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# END","execution_count":null}],"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}