{"cells":[{"metadata":{},"cell_type":"markdown","source":"### Load Files"},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport pickle\n\nimport keras\nfrom keras.preprocessing.image import ImageDataGenerator\n\nfrom keras.models import Sequential\nfrom keras.layers import Conv2D\nfrom keras.layers import MaxPooling2D\nfrom keras.layers import Flatten, BatchNormalization\nfrom keras.layers import Dense, Dropout\nfrom keras import optimizers\nfrom keras.callbacks import ReduceLROnPlateau\n\nimport os\nprint(os.listdir(\"../input\"))\n","execution_count":1,"outputs":[{"output_type":"stream","text":"Using TensorFlow backend.\n","name":"stderr"},{"output_type":"stream","text":"['test_batch', 'data_batch_4', 'data_batch_2', 'data_batch_5', 'data_batch_1', 'data_batch_3', 'batches.meta']\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"run_model1 = True","execution_count":2,"outputs":[]},{"metadata":{"_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","trusted":true},"cell_type":"code","source":"def load_cifar10_data(filename):\n    with open('../input/'+ filename, 'rb') as file:\n        batch = pickle.load(file, encoding='latin1')\n\n    features = batch['data']\n    labels = batch['labels']\n    return features, labels","execution_count":3,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Load files\nbatch_1, labels_1 = load_cifar10_data('data_batch_1')\nbatch_2, labels_2 = load_cifar10_data('data_batch_2')\nbatch_3, labels_3 = load_cifar10_data('data_batch_3')\nbatch_4, labels_4 = load_cifar10_data('data_batch_4')\nbatch_5, labels_5 = load_cifar10_data('data_batch_5')\n\ntest, label_test = load_cifar10_data('test_batch')","execution_count":4,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Merge files\nX_train = np.concatenate([batch_1,batch_2,batch_3,batch_4,batch_5], 0)\nY_train = np.concatenate([labels_1,labels_2,labels_3,labels_4,labels_5], 0)\n","execution_count":5,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dict_ = {0:'Airplane', 1:'Automobile', 2:'Bird', 3:'Cat', 4:'Deer',\n         5:'Dog', 6:'Frog', 7:'Horse', 8:'Ship', 9:'Truck'}\n\ndef return_photo(batch_file):\n    assert batch_file.shape[1] == 3072\n    dim = np.sqrt(1024).astype(int)\n    r = batch_file[:, 0:1024].reshape(batch_file.shape[0], dim, dim, 1)\n    g = batch_file[:, 1024:2048].reshape(batch_file.shape[0], dim, dim, 1)\n    b = batch_file[:, 2048:3072].reshape(batch_file.shape[0], dim, dim, 1)\n    photo = np.concatenate([r,g,b], -1)\n    return photo\n\n\n","execution_count":6,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train = return_photo(X_train)\nX_test = return_photo(test)\nY_test = np.array(label_test)","execution_count":7,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plot_image(number, file, label):\n    fig = plt.figure(figsize = (3,2))\n    #img = return_photo(batch_file)\n    plt.imshow(file[number])\n    plt.title(dict_[label[number]])\n    \nplot_image(12345, X_train, Y_train)","execution_count":8,"outputs":[{"output_type":"display_data","data":{"text/plain":"<Figure size 216x144 with 1 Axes>","image/png":"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\n"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"# The cifar-10 is designed to balance distribution that the counts for each classification are 5000\nimport seaborn as sns\nsns.countplot(Y_train)\nhist_Y_train = pd.Series(Y_train).groupby(Y_train).count()\nprint(hist_Y_train)","execution_count":9,"outputs":[{"output_type":"stream","text":"0    5000\n1    5000\n2    5000\n3    5000\n4    5000\n5    5000\n6    5000\n7    5000\n8    5000\n9    5000\ndtype: int64\n","name":"stdout"},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 1 Axes>","image/png":"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\n"},"metadata":{}}]},{"metadata":{},"cell_type":"markdown","source":"### Preprocessing"},{"metadata":{"trusted":true},"cell_type":"code","source":"from sklearn import preprocessing\noh_encoder = preprocessing.OneHotEncoder(categories='auto')\noh_encoder.fit(Y_train.reshape(-1,1))\n","execution_count":10,"outputs":[{"output_type":"execute_result","execution_count":10,"data":{"text/plain":"OneHotEncoder(categorical_features=None, categories='auto',\n       dtype=<class 'numpy.float64'>, handle_unknown='error',\n       n_values=None, sparse=True)"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"X_train_nor = X_train.astype('float32') / 255.0\nX_test_nor = X_test.astype('float32') / 255.0\nY_train_oh = oh_encoder.transform(Y_train.reshape(-1,1)).toarray()\nY_test_oh = oh_encoder.transform(Y_test.reshape(-1,1)).toarray()","execution_count":11,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print('One-hot:')\nprint(Y_train_oh[:5])\nprint('\\nLabel:')\nprint(Y_train[:5])","execution_count":12,"outputs":[{"output_type":"stream","text":"One-hot:\n[[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]]\n\nLabel:\n[6 9 9 4 1]\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Final check for dimensions before training\nprint('X_train shape:', X_train_nor.shape)\nprint('Y_train_oh shape:', Y_train_oh.shape)\nprint('X_test shape:', X_test_nor.shape)\nprint('Y_train_oh shape:', Y_test_oh.shape)","execution_count":13,"outputs":[{"output_type":"stream","text":"X_train shape: (50000, 32, 32, 3)\nY_train_oh shape: (50000, 10)\nX_test shape: (10000, 32, 32, 3)\nY_train_oh shape: (10000, 10)\n","name":"stdout"}]},{"metadata":{},"cell_type":"markdown","source":"### Build Model"},{"metadata":{"trusted":true},"cell_type":"code","source":"def build_basic_net(model, dropout=0.2):\n    model.add(Conv2D(filters=32, kernel_size=(5,5), padding='same', strides=1,\n                     input_shape=X_train.shape[1:], activation='relu'))\n    model.add(Dropout(dropout))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    model.add(Conv2D(filters=64, kernel_size=(3,3), padding='same', strides=1,\n                     input_shape=X_train.shape[1:], activation='relu'))\n    model.add(Dropout(dropout))\n    model.add(MaxPooling2D(pool_size=(2, 2)))\n    \n    model.add(Flatten())\n    model.add(Dense(1024, activation='relu'))\n    model.add(Dropout(dropout))\n    model.add(Dense(512, activation='relu'))\n    model.add(Dropout(dropout))\n    model.add(Dense(10,activation='softmax'))","execution_count":14,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"hist_dict = {}\n\nif __name__ == '__main__' and run_model1:\n    model = Sequential()\n    build_basic_net(model)\n    model.summary()\n    \n    adam = optimizers.Adam()\n    model.compile(loss='categorical_crossentropy', metrics=['accuracy'], optimizer=adam)\n    hist_dict['run_model1'] = model.fit(X_train_nor, Y_train_oh, batch_size=64, epochs=10,\n                                    shuffle=True, validation_split=0.2, verbose=1)","execution_count":28,"outputs":[{"output_type":"stream","text":"_________________________________________________________________\nLayer (type)                 Output Shape              Param #   \n=================================================================\nconv2d_3 (Conv2D)            (None, 32, 32, 32)        2432      \n_________________________________________________________________\ndropout_5 (Dropout)          (None, 32, 32, 32)        0         \n_________________________________________________________________\nmax_pooling2d_3 (MaxPooling2 (None, 16, 16, 32)        0         \n_________________________________________________________________\nconv2d_4 (Conv2D)            (None, 16, 16, 64)        18496     \n_________________________________________________________________\ndropout_6 (Dropout)          (None, 16, 16, 64)        0         \n_________________________________________________________________\nmax_pooling2d_4 (MaxPooling2 (None, 8, 8, 64)          0         \n_________________________________________________________________\nflatten_2 (Flatten)          (None, 4096)              0         \n_________________________________________________________________\ndense_4 (Dense)              (None, 1024)              4195328   \n_________________________________________________________________\ndropout_7 (Dropout)          (None, 1024)              0         \n_________________________________________________________________\ndense_5 (Dense)              (None, 512)               524800    \n_________________________________________________________________\ndropout_8 (Dropout)          (None, 512)               0         \n_________________________________________________________________\ndense_6 (Dense)              (None, 10)                5130      \n=================================================================\nTotal params: 4,746,186\nTrainable params: 4,746,186\nNon-trainable params: 0\n_________________________________________________________________\nTrain on 40000 samples, validate on 10000 samples\nEpoch 1/10\n40000/40000 [==============================] - 7s 163us/step - loss: 1.4875 - acc: 0.4581 - val_loss: 1.2120 - val_acc: 0.5851\nEpoch 2/10\n40000/40000 [==============================] - 6s 141us/step - loss: 1.1142 - acc: 0.6046 - val_loss: 1.0632 - val_acc: 0.6285\nEpoch 3/10\n40000/40000 [==============================] - 6s 141us/step - loss: 0.9411 - acc: 0.6682 - val_loss: 0.9733 - val_acc: 0.6659\nEpoch 4/10\n40000/40000 [==============================] - 6s 142us/step - loss: 0.7878 - acc: 0.7227 - val_loss: 0.9155 - val_acc: 0.6823\nEpoch 5/10\n40000/40000 [==============================] - 6s 141us/step - loss: 0.6535 - acc: 0.7709 - val_loss: 0.9142 - val_acc: 0.6827\nEpoch 6/10\n40000/40000 [==============================] - 6s 141us/step - loss: 0.5337 - acc: 0.8109 - val_loss: 0.8565 - val_acc: 0.7070\nEpoch 7/10\n40000/40000 [==============================] - 6s 142us/step - loss: 0.4301 - acc: 0.8488 - val_loss: 0.9061 - val_acc: 0.6918\nEpoch 8/10\n40000/40000 [==============================] - 6s 141us/step - loss: 0.3526 - acc: 0.8764 - val_loss: 0.9418 - val_acc: 0.6975\nEpoch 9/10\n40000/40000 [==============================] - 6s 141us/step - loss: 0.3022 - acc: 0.8946 - val_loss: 0.9274 - val_acc: 0.7085\nEpoch 10/10\n40000/40000 [==============================] - 6s 141us/step - loss: 0.2467 - acc: 0.9167 - val_loss: 1.0139 - val_acc: 0.6937\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"def model_predict(model, test_set):\n    print(\"Generating test predictions...\")\n    predictions = model.predict_classes(test_set, verbose=1)\n    print(\"OK.\")\n    return predictions\n\n\ndef write_preds(preds, filename):\n    pd.DataFrame({\"ImageId\": list(range(1,len(preds)+1)), \"Label\": preds}).to_csv(filename, index=False, header=True)","execution_count":29,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if __name__ == '__main__' and run_model1:\n    predictions = model_predict(model, X_test_nor)\n    print(predictions[:5])\n    write_preds(predictions, \"keras-model1.csv\")\n    \n    scores = model.evaluate(X_test_nor, Y_test_oh)\n    print(\"Accuracy=\", scores[1])","execution_count":30,"outputs":[{"output_type":"stream","text":"Generating test predictions...\n10000/10000 [==============================] - 1s 70us/step\nOK.\n[3 8 0 0 6]\n10000/10000 [==============================] - 1s 69us/step\nAccuracy= 0.6931\n","name":"stdout"}]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Plot the loss and accuracy curves for training and validation \ndef loss_acc_plt(history):\n    fig, ax = plt.subplots(2,1)\n    ax[0].plot(history.history['loss'], color='b', label=\"Training loss\")\n    ax[0].plot(history.history['val_loss'], color='r', label=\"validation loss\",axes =ax[0])\n    legend = ax[0].legend(loc='best', shadow=True)\n\n    ax[1].plot(history.history['acc'], color='b', label=\"Training accuracy\")\n    ax[1].plot(history.history['val_acc'], color='r',label=\"Validation accuracy\")\n    legend = ax[1].legend(loc='best', shadow=True)\n    \n\nif run_model1:\n    loss_acc_plt(hist_dict['run_model1'])\n    \n\"\"\"\n    if run_model2:\n    loss_acc_plt(hist_dict['run_model2'])\nif run_model3:\n    loss_acc_plt(hist_dict['run_model3'])\nif run_model_adv:\n    loss_acc_plt(hist_dict['run_model_adv'])\n\"\"\"","execution_count":31,"outputs":[{"output_type":"execute_result","execution_count":31,"data":{"text/plain":"\"\\n    if run_model2:\\n    loss_acc_plt(hist_dict['run_model2'])\\nif run_model3:\\n    loss_acc_plt(hist_dict['run_model3'])\\nif run_model_adv:\\n    loss_acc_plt(hist_dict['run_model_adv'])\\n\""},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"<Figure size 432x288 with 2 Axes>","image/png":"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xWLBYrFQp04dDh06xMCBAzl06JDTTUdctGgRa9euLdcU0dIkJSWxceNG+vfvT2RkJABKqSStdZnJ5FyfWBWbPRuefNKM+nz5pakNJoSoPleuXKFfv35YLBa01rz//vtOF+yPPvoo3377LWvWVP+hPvac61OrIjk5MH06vPOOOUBp4UKpByOEIwQEBOSPgzur9957z9FNAGTMncxMGDrUBPszz5g6MRLsQghn59Y99+PHTU993z547z1z8KoQQrgCtw33bdtMj/36dVi9GgYMcHSLhBCi8rjlsMxnn0Hv3mYhjc2bJdiFEK7HrcJda1Nv/b77TOWCrVtluTshEhISihyQNGvWLB599NFSH+eXt3MqNTWVUaNGFbtNnz59KGvK86xZswosMXjXXXdx6dKl8jRdlMJtwv3XX00JgT/+EcaPh//8B/JKVgvh1saNG8eiRQUPKl+0aBHjxo0r1+NbtGhR6hGeZSkc7qtWrarwwhSOpLXOL2NQk7hFuJ8/b4Ze5s2Dv/zFVHisU8fRrRKiZhg1ahRff/012dnZAKSkpJCamkrPnj3z553HxsYSGRnJF198UeTxKSkpREREAKY0wNixYwkNDWX48OH5h/yDmf9tLRf84osvAvDOO++QmppKQkICCQkJgCkLcO7cOQDeeustIiIiiIiIyC8XnJKSQmhoKA8//DDh4eEMHDiwwOtYffnll3Tt2pWYmBj69+9PWt56yFeuXGHKlClERkYSFRWVX75gzZo1xMbGEh0dnb94ycyZM3njjTfynzMiIoKUlBRSUlJo3749kyZNIiIighMnThT7/gC2b9/Ob37zG6Kjo+nSpQuZmZn06tWrQCnjHj16sGvXrgr9u5XF5Xeo/vyzmRFz4oSZv55XcE6ImskBNX8bNGhAly5dWL16NcOGDWPRokXcd999KKWoU6cOy5cvp169epw7d474+HiGDh2KKqEex3vvvYevry/79+9n9+7dBUr2vvzyyzRo0ICcnBz69evH7t27efLJJ3nrrbdYv349jRo1KvBcSUlJzJ07l61bt6K1pmvXrvTu3ZvAwEAOHTrEwoUL+ec//8l9993HsmXLmDhxYoHH9+jRgy1btqCU4sMPP+S1117jzTff5K9//Sv169dnz549gKm5np6ezsMPP8zGjRsJCQkpV1ngQ4cOMW/ePOLj40t8fx06dGDMmDEs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\n"},"metadata":{}}]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"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}