# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load in 

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the "../input/" directory.
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory

import os
print(os.listdir("../input"))

# Any results you write to the current directory are saved as output.

import keras
from keras import layers
from keras import models
from keras.utils import to_categorical
from keras import optimizers
from keras.preprocessing.image import ImageDataGenerator



test_data = pd.read_csv('../input/test.csv')
train_data = pd.read_csv('../input/train.csv')


train_x = train_data.loc['0':'35999', 'pixel0':]
train_y = train_data.loc['0':'35999', 'label']

val_x = train_data.loc['36000':, 'pixel0':]
val_y = train_data.loc['36000':, 'label']

train_x = np.array(train_x).reshape(36000, 28, 28, 1)
val_x = np.array(val_x).reshape(6000, 28, 28, 1)

train_x = train_x.astype('float32') / 255
val_x = val_x.astype('float32') / 255

train_y = to_categorical(train_y)
val_y = to_categorical(val_y)

datagen = ImageDataGenerator(
    zoom_range=0.2,
    rotation_range=10,
    width_shift_range=0.1,
    height_shift_range=0.1)

datagen.fit(train_x)

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(28, 28, 1)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(64, (3, 3), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Conv2D(128, (3, 3), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(layers.Dropout(0.2))

model.add(layers.Conv2D(256, (2, 2), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((1, 1)))
model.add(layers.Conv2D(256, (2, 2), padding='same', activation='relu'))
model.add(layers.MaxPooling2D((1, 1)))
model.add(layers.Dropout(0.2))


model.add(layers.Flatten())
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1024, activation='relu'))
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(10, activation='softmax'))

model.compile(optimizer=optimizers.Adam(lr=1e-4),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

model.fit_generator(datagen.flow(train_x, train_y, batch_size=64),
                    steps_per_epoch=len(train_x) / 32, epochs=50,
                    validation_data=(val_x, val_y))
                    
test_x = np.array(test_data).reshape(28000, 28, 28, 1)
test_x = test_x.astype('float32') / 255
                    
prediction = model.predict_classes(test_x)

submission = pd.DataFrame({"ImageId": list(range(1,len(prediction)+1)),
                         "Label": prediction})
submission.to_csv("submission.csv", index=False, header=True)


