{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"from tensorflow.keras.datasets import cifar10\n(x_train, y_train), (x_test, y_test) = cifar10.load_data()\nprint('x_train shape:', x_train.shape)\nprint('y_train shape:', y_train.shape)\nprint(x_train.shape[0], 'train samples')\nprint(x_test.shape[0], 'test samples')\n\n","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"from __future__ import print_function\nimport keras\nfrom keras.datasets import cifar10\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Activation, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D\nimport os\n\nimport numpy as np\nimport pandas as pd\n\nimport seaborn as sns\nimport matplotlib\nimport matplotlib.pyplot as plt\nfrom keras.utils import to_categorical\nfrom keras.optimizers import Adam\n\nfrom sklearn.metrics import confusion_matrix, classification_report\nimport itertools\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D,MaxPool2D,Dense,Flatten,Dropout,Input, AveragePooling2D, Activation,Conv2D, MaxPooling2D, BatchNormalization,Concatenate\nfrom tensorflow.keras.callbacks import EarlyStopping, TensorBoard\nfrom tensorflow.keras import regularizers, optimizers\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras.utils import to_categorical\nfrom keras.models import Sequential, load_model\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D, BatchNormalization\nfrom keras.optimizers import Adam\nfrom keras.callbacks import LearningRateScheduler\nfrom keras.callbacks import EarlyStopping\n## Setting the seeds for Reproducibility.\nseed = 3141\nnp.random.seed(seed)\n\n%matplotlib inline","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"batch_size = 32  # The default batch size of keras.\nnum_classes = 10  # Number of class for the dataset\nepochs = 100\ndata_augmentation = False","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"fig, axs = plt.subplots(1,2,figsize=(15,5)) \n# Count plot for training set\nsns.countplot(y_train.ravel(), ax=axs[0])\naxs[0].set_title('Distribution of training data')\naxs[0].set_xlabel('Classes')\n# Count plot for testing set\nsns.countplot(y_test.ravel(), ax=axs[1])\naxs[1].set_title('Distribution of Testing data')\naxs[1].set_xlabel('Classes')\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Normalize the data. Before we need to connvert data type to float for computation.\nx_train = x_train.astype('float32')\nx_test = x_test.astype('float32')\nx_train /= 255\nx_test /= 255\n\n# Convert class vectors to binary class matrices. This is called one hot encoding.\ny_train = keras.utils.to_categorical(y_train, num_classes)\ny_test = keras.utils.to_categorical(y_test, num_classes)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(20,8))\nfor i in range(10,18):\n    plt.subplot(231 + (i))\n    plt.imshow(x_train[i][:, :, 0], cmap=\"gray\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#define the convnet\nmodel = Sequential()\n# CONV => RELU => CONV => RELU => POOL => DROPOUT\nmodel.add(Conv2D(32, (3, 3), padding='same',input_shape=x_train.shape[1:]))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(32, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# CONV => RELU => CONV => RELU => POOL => DROPOUT\nmodel.add(Conv2D(64, (3, 3), padding='same'))\nmodel.add(Activation('relu'))\nmodel.add(Conv2D(64, (3, 3)))\nmodel.add(Activation('relu'))\nmodel.add(MaxPooling2D(pool_size=(2, 2)))\nmodel.add(Dropout(0.25))\n\n# FLATTERN => DENSE => RELU => DROPOUT\nmodel.add(Flatten())\nmodel.add(Dense(512))\nmodel.add(Activation('relu'))\nmodel.add(Dropout(0.5))\n# a softmax classifier\nmodel.add(Dense(num_classes))\nmodel.add(Activation('softmax'))\n\nmodel.summary()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# initiate RMSprop optimizer\nopt = keras.optimizers.RMSprop(learning_rate=0.0001, decay=1e-6)\n\n# Let's train the model using RMSprop\nmodel.compile(loss='categorical_crossentropy',\n              optimizer=opt,\n              metrics=['accuracy'])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"history = None  # For recording the history of trainning process.\nif not data_augmentation:\n    print('Not using data augmentation.')\n    history = model.fit(x_train, y_train,\n              batch_size=batch_size,\n              epochs=epochs,\n              validation_data=(x_test, y_test),\n              shuffle=True)\nelse:\n    print('Using real-time data augmentation.')\n    # This will do preprocessing and realtime data augmentation:\n    datagen = ImageDataGenerator(\n        featurewise_center=False,  # set input mean to 0 over the dataset\n        samplewise_center=False,  # set each sample mean to 0\n        featurewise_std_normalization=False,  # divide inputs by std of the dataset\n        samplewise_std_normalization=False,  # divide each input by its std\n        zca_whitening=False,  # apply ZCA whitening\n        zca_epsilon=1e-06,  # epsilon for ZCA whitening\n        rotation_range=0,  # randomly rotate images in the range (degrees, 0 to 180)\n        # randomly shift images horizontally (fraction of total width)\n        width_shift_range=0.1,\n        # randomly shift images vertically (fraction of total height)\n        height_shift_range=0.1,\n        shear_range=0.,  # set range for random shear\n        zoom_range=0.,  # set range for random zoom\n        channel_shift_range=0.,  # set range for random channel shifts\n        # set mode for filling points outside the input boundaries\n        fill_mode='nearest',\n        cval=0.,  # value used for fill_mode = \"constant\"\n        horizontal_flip=True,  # randomly flip images\n        vertical_flip=False,  # randomly flip images\n        # set rescaling factor (applied before any other transformation)\n        rescale=None,\n        # set function that will be applied on each input\n        preprocessing_function=None,\n        # image data format, either \"channels_first\" or \"channels_last\"\n        data_format=None,\n        # fraction of images reserved for validation (strictly between 0 and 1)\n        validation_split=0.0)\n\n    # Compute quantities required for feature-wise normalization\n    # (std, mean, and principal components if ZCA whitening is applied).\n    datagen.fit(x_train)\n\n    # Fit the model on the batches generated by datagen.flow().\n    history = model.fit_generator(datagen.flow(x_train, y_train,\n                                    batch_size=batch_size),\n                                    epochs=epochs,\n                                    validation_data=(x_test, y_test),\n                                    workers=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def plotmodelhistory(history): \n    fig, axs = plt.subplots(1,2,figsize=(15,5)) \n    # summarize history for accuracy\n    axs[0].plot(history.history['accuracy']) \n    axs[0].plot(history.history['val_accuracy']) \n    axs[0].set_title('Model Accuracy')\n    axs[0].set_ylabel('Accuracy') \n    axs[0].set_xlabel('Epoch')\n    axs[0].legend(['train', 'validate'], loc='upper left')\n    # summarize history for loss\n    axs[1].plot(history.history['loss']) \n    axs[1].plot(history.history['val_loss']) \n    axs[1].set_title('Model Loss')\n    axs[1].set_ylabel('Loss') \n    axs[1].set_xlabel('Epoch')\n    axs[1].legend(['train', 'validate'], loc='upper left')\n    plt.show()\n\n# list all data in history\nprint(history.history.keys())\n\nplotmodelhistory(history)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Score trained model.\nscores = model.evaluate(x_test, y_test, verbose=1)\nprint('Test loss:', scores[0])\nprint('Test accuracy:', scores[1])\n\n# make prediction.\npred = model.predict(x_test)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def heatmap(data, row_labels, col_labels, ax=None, cbar_kw={}, cbarlabel=\"\", **kwargs):\n    \"\"\"\n    Create a heatmap from a numpy array and two lists of labels.\n    \"\"\"\n    if not ax:\n        ax = plt.gca()\n\n    # Plot the heatmap\n    im = ax.imshow(data, **kwargs)\n\n    # Create colorbar\n    cbar = ax.figure.colorbar(im, ax=ax, **cbar_kw)\n    cbar.ax.set_ylabel(cbarlabel, rotation=-90, va=\"bottom\")\n\n    # Let the horizontal axes labeling appear on top.\n    ax.tick_params(top=True, bottom=False,\n                   labeltop=True, labelbottom=False)\n    # We want to show all ticks...\n    ax.set_xticks(np.arange(data.shape[1]))\n    ax.set_yticks(np.arange(data.shape[0]))\n    # ... and label them with the respective list entries.\n    ax.set_xticklabels(col_labels)\n    ax.set_yticklabels(row_labels)\n    \n    ax.set_xlabel('Predicted Label') \n    ax.set_ylabel('True Label')\n    \n    return im, cbar\n\ndef annotate_heatmap(im, data=None, fmt=\"d\", threshold=None):\n    \"\"\"\n    A function to annotate a heatmap.\n    \"\"\"\n    # Change the text's color depending on the data.\n    texts = []\n    for i in range(data.shape[0]):\n        for j in range(data.shape[1]):\n            text = im.axes.text(j, i, format(data[i, j], fmt), horizontalalignment=\"center\",\n                                 color=\"white\" if data[i, j] > thresh else \"black\")\n            texts.append(text)\n\n    return texts","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"labels = ['Airplane', 'Automobile', 'Bird', 'Cat', 'Deer', 'Dog', 'Frog', 'Horse', 'Ship', 'Truck']\n\n# Convert predictions classes to one hot vectors \nY_pred_classes = np.argmax(pred, axis=1) \n# Convert validation observations to one hot vectors\nY_true = np.argmax(y_test, axis=1)\n# Errors are difference between predicted labels and true labels\nerrors = (Y_pred_classes - Y_true != 0)\n\nY_pred_classes_errors = Y_pred_classes[errors]\nY_pred_errors = pred[errors]\nY_true_errors = Y_true[errors]\nX_test_errors = x_test[errors]\n\ncm = confusion_matrix(Y_true, Y_pred_classes) \nthresh = cm.max() / 2.\n\nfig, ax = plt.subplots(figsize=(12,12))\nim, cbar = heatmap(cm, labels, labels, ax=ax,\n                   cmap=plt.cm.Blues, cbarlabel=\"count of predictions\")\ntexts = annotate_heatmap(im, data=cm, threshold=thresh)\n\nfig.tight_layout()\nplt.show()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(classification_report(Y_true, Y_pred_classes))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"R = 5\nC = 5\nfig, axes = plt.subplots(R, C, figsize=(12,12))\naxes = axes.ravel()\n\nfor i in np.arange(0, R*C):\n    axes[i].imshow(x_test[i])\n    axes[i].set_title(\"True: %s \\nPredict: %s\" % (labels[Y_true[i]], labels[Y_pred_classes[i]]))\n    axes[i].axis('off')\n    plt.subplots_adjust(wspace=1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"R = 3\nC = 5\nfig, axes = plt.subplots(R, C, figsize=(12,8))\naxes = axes.ravel()\n\nmisclassified_idx = np.where(Y_pred_classes != Y_true)[0]\nfor i in np.arange(0, R*C):\n    axes[i].imshow(x_test[misclassified_idx[i]])\n    axes[i].set_title(\"True: %s \\nPredicted: %s\" % (labels[Y_true[misclassified_idx[i]]], \n                                                  labels[Y_pred_classes[misclassified_idx[i]]]))\n    axes[i].axis('off')\n    plt.subplots_adjust(wspace=1)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def display_errors(errors_index, img_errors, pred_errors, obs_errors):\n    \"\"\" This function shows 10 images with their predicted and real labels\"\"\"\n    n = 0\n    nrows = 2\n    ncols = 5\n    fig, ax = plt.subplots(nrows,ncols,sharex=True,sharey=True, figsize=(12,6))\n    for row in range(nrows):\n        for col in range(ncols):\n            error = errors_index[n]\n            ax[row,col].imshow((img_errors[error]).reshape((32,32,3)))\n            ax[row,col].set_title(\"Predicted:{}\\nTrue:{}\".\n                                  format(labels[pred_errors[error]],labels[obs_errors[error]]))\n            n += 1\n            ax[row,col].axis('off')\n            plt.subplots_adjust(wspace=1)\n\n# Probabilities of the wrong predicted numbers\nY_pred_errors_prob = np.max(Y_pred_errors,axis = 1)\n\n# Predicted probabilities of the true values in the error set\ntrue_prob_errors = np.diagonal(np.take(Y_pred_errors, Y_true_errors, axis=1))\n\n# Difference between the probability of the predicted label and the true label\ndelta_pred_true_errors = Y_pred_errors_prob - true_prob_errors\n\n# Sorted list of the delta prob errors\nsorted_dela_errors = np.argsort(delta_pred_true_errors)\n\n# Top 10 errors \nmost_important_errors = sorted_dela_errors[-10:]\n\n# Show the top 10 errors\ndisplay_errors(most_important_errors, X_test_errors, Y_pred_classes_errors, Y_true_errors)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def show_test(number):\n    fig = plt.figure(figsize = (3,3))\n    test_image = np.expand_dims(x_test[number], axis=0)\n    test_result = model.predict_classes(test_image)\n    plt.imshow(x_test[number])\n    dict_key = test_result[0]\n    plt.title(\"Predicted: {} \\nTrue Label: {}\".format(labels[dict_key],\n                                                      labels[Y_true[number]]))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"show_test(20)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"save_dir = os.path.join(os.getcwd(), 'saved_models')\nmodel_name = 'keras_cifar10_trained_model.h5'\n\n# Save model and weights\nif not os.path.isdir(save_dir):\n    os.makedirs(save_dir)\nmodel_path = os.path.join(save_dir, model_name)\nmodel.save(model_path)\nprint('Saved trained model at %s ' % model_path)\n\n# Score trained model.\nscores = model.evaluate(x_test, y_test, verbose=1)\nprint('Test loss:', scores[0])\nprint('Test accuracy:', scores[1])\n","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}