{"cells":[{"metadata":{"_cell_guid":"667080ec-efe6-48c6-99fc-3a11bd0adaa4","_uuid":"3f3231a1e047f9d1f661456dedffb10d1ab34e5f"},"cell_type":"markdown","source":"# The 15 Minute MNIST","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"8571b9f2-38e7-430c-9231-2b1e2a8d712e","_uuid":"0f67e4fc14a17ed0530e3cc5427fdfbd8de8fa12"},"cell_type":"markdown","source":"This notebook is not about finishing first but it is about what you can do in 15 minutes of work. It provides a simple basis upon which to build a better model. ","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"293f4116-f283-45e4-8ca7-519b28d91ff7","_uuid":"f6173a5e699f4f2ca311e83d46c2c0a5bd992b35","collapsed":true,"trusted":false},"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"01d6a158-f6f3-462a-a653-48218238b760","_uuid":"6e5cc9535983bc57f8fde8fda969f862ae10184b"},"cell_type":"markdown","source":"## Load up the training and test sets.","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"6e73448c-2677-4381-a67b-6ea32446ecde","_uuid":"f168b27385fae32e44b359597b33d4f945a7dc14","trusted":false,"collapsed":true},"cell_type":"code","source":"\n#load Data Here\nprint(\"Fetching Training Data...\")\ntrain = pd.read_csv(\"../input/train.csv\")\n\nprint(\"Fetching Testing Data...\")\ntest = pd.read_csv(\"../input/test.csv\")","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"d5b4057c-5022-47db-9a5a-610861d680f0","_uuid":"f8617f55b698d9630dfabee5150146f549331772"},"cell_type":"markdown","source":"We know the images are 28x28 so reform the images and normalize them:","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"e8b50f5d-a635-4dc0-a838-689b9c21516c","_uuid":"a40884d0634d8cd0023cffe30b030cce7f500184","collapsed":true,"trusted":false},"cell_type":"code","source":"Ytrain = np.array(train['label'])\nXtrain = np.array(train.iloc[:,1:]).reshape(-1,28,28,1)\nXtest = np.array(test).reshape(-1,28,28,1)\n\n#normalize X\nXtrain = Xtrain/255.0\nXtest = Xtest/255.0\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"ce11f8c4-7162-4861-bc5b-3a4eea012cbf","_uuid":"720304d87847337604d2f26ce20609e5a1035917"},"cell_type":"markdown","source":"Now, the model. I've put together a very standard CNN model that I've used as a basic \"see what you get\" with appropriate default values. It is by no means tuned or more than just a basic idea of what a CNN could be.","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"6e69bbf3-39bb-46a9-b134-96456946c5f8","_uuid":"d0fa3863fad239e248ffbb0997fca78c8166fbbf","trusted":false,"collapsed":true},"cell_type":"code","source":"from keras.layers import Dense, Dropout, Flatten, Input\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras.models import Model\nfrom keras.layers.normalization import BatchNormalization\nfrom keras.optimizers import Adam\nfrom keras.utils import np_utils\nfrom keras.callbacks import EarlyStopping, ModelCheckpoint, ReduceLROnPlateau\n\ndef getModel():\n    \n    mi = Input(shape=(28,28,1), name=\"images\")\n\n    x = Conv2D(32, kernel_size=(5, 5), activation='relu')((BatchNormalization(momentum=0))(mi))\n    x = Conv2D(32, kernel_size=(3, 3), activation='relu')(x)\n    x = (MaxPooling2D(pool_size=(2, 2)))(x)\n    x = Dropout(0.2)(x)\n    \n    x = Conv2D(64, kernel_size=(3, 3), activation='relu')(x)\n    x = Conv2D(128, kernel_size=(3, 3), activation='relu')(x)\n    x = (MaxPooling2D(pool_size=(2, 2)))(x)\n    x = Dropout(0.2)(x)\n    \n    x = Flatten()(x)\n    \n    x = Dense(256, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    \n    x = Dense(128, activation='relu')(x)\n    x = Dropout(0.5)(x)\n    \n    main_output = Dense(10, activation=\"softmax\", name='main_output')(x)\n    \n    model = Model(mi,main_output)\n    \n    myoptim=Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0)\n       \n    model.compile(loss='categorical_crossentropy',\n                  optimizer=myoptim,\n                  metrics=['accuracy'])\n    \n    return model","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"9f8757ad-9675-45da-bb16-624a725e4127","_uuid":"a1012e14de6ab377ba54adbf4190dfeca34947b8"},"cell_type":"markdown","source":"Okay - let's load that model and take a peak at it:","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"e4d54cec-e419-41bb-aa08-f7582ccc3398","_uuid":"797295d2dbaf8cb18ccb34db34ab9e939f788fd1","trusted":false,"collapsed":true},"cell_type":"code","source":"model = getModel()\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"45251a34-cfb9-4031-b295-d3d34ec7a454","_uuid":"ba9e604ca3d78921ad5a554b8c5b594ab4d09a97"},"cell_type":"markdown","source":"Setup a Stratified K-fold of 5","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"0b421c02-c724-4b9a-8ffd-7362127a7e35","_uuid":"01ef10283dabcc9423bb76c335589662a598dabd","collapsed":true,"trusted":false},"cell_type":"code","source":"from sklearn.model_selection import StratifiedShuffleSplit\n\nsss = StratifiedShuffleSplit(n_splits=5)","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"1f7780ac-2364-4e54-9660-fd5e712a7582","_uuid":"9729179f3d22ce3f48988ad847f0ea25fbdf59d6"},"cell_type":"markdown","source":"Run the model via the Stratified Shuffle:","outputs":[],"execution_count":null},{"metadata":{"_cell_guid":"436697f5-b65b-498e-9b96-7aec64a15d24","_uuid":"f95fee827bef19cd0283fcc811989361b74c1048","collapsed":true,"trusted":false},"cell_type":"code","source":"i=0\n\nfor train_index, cv_index in sss.split(Xtrain,Ytrain):\n\n    i += 1\n\n    X_train, X_cv = Xtrain[train_index], Xtrain[cv_index]\n    y_train, y_cv = Ytrain[train_index], Ytrain[cv_index]\n    # convert class vectors to binary class matrices\n    Y_train = np_utils.to_categorical(y_train, 10)\n    Y_cv = np_utils.to_categorical(y_cv, 10)\n        \n    # Data Info, etc\n    nb_classes = 10\n    nb_epoch = 100\n    batch_size = 32\n    \n    earlyStopping = EarlyStopping(monitor='val_loss', patience=6, verbose=0, mode='min')\n    mcp_save = ModelCheckpoint('.mdl_wts.hdf5', save_best_only=True, monitor='val_loss', mode='min')\n    reduce_lr_loss = ReduceLROnPlateau(monitor='val_loss', factor=0.05, patience=2, verbose=1, epsilon=1e-4, mode='min')\n    history = model.fit(X_train, Y_train, batch_size=batch_size, epochs=nb_epoch, verbose=0, callbacks=[earlyStopping, mcp_save,reduce_lr_loss],validation_data=(X_cv,Y_cv))\n\n    model.load_weights(filepath = '.mdl_wts.hdf5')\n\n    score = model.evaluate(X_cv, Y_cv, verbose=2)\n    print('CV Train loss:', score[0])\n    print('CV Train accuracy:', score[1])\n\n    pred = model.predict(Xtest, batch_size=batch_size, verbose=0)\n\n    pred_val = np.argmax(pred,axis=1)\n    \n    submission = pd.DataFrame({'ImageId': np.arange(1,len(Xtest[:,...])+1),'Label': pred_val})\n    print(submission.head(10))\n    \n    #submission.to_csv('../input/Submission_'+str(i)+'.csv', index=False)\n    \n    break # remove to do all folds\n","execution_count":null,"outputs":[]},{"metadata":{"_cell_guid":"eff3892e-67ec-409f-8b63-684c3f717f1c","_uuid":"2dc32983ca1a0dafe18539e4acacb8d10a9edf6a"},"cell_type":"markdown","source":"And there you go! Less than 15 minutes of work and 0.99385 score on the leaderboard. Good place to start - now GO!","outputs":[],"execution_count":null}],"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","version":"3.6.4","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":1}